Hex Artifact Content

Artifact 388927f9caa908a778eedf64e3deee6662ea4f9f:


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 52 6f 6f 74 3b 0a 09 09 09 69 6e   suidRoot;....in
1010: 74 20 77 6f 72 6c 64 61 63 63 65 73 73 69 62 6c  t worldaccessibl
1020: 65 3b 0a 09 09 09 6f 66 66 5f 74 20 73 69 7a 65  e;....off_t size
1030: 3b 0a 09 09 7d 20 66 69 6c 65 3b 0a 09 09 73 74  ;...} file;...st
1040: 72 75 63 74 20 7b 0a 09 09 09 6f 66 66 5f 74 20  ruct {....off_t 
1050: 73 69 7a 65 3b 0a 09 09 09 63 68 61 72 20 73 6f  size;....char so
1060: 75 72 63 65 5b 32 35 36 5d 3b 0a 09 09 7d 20 73  urce[256];...} s
1070: 79 6d 6c 69 6e 6b 3b 0a 09 7d 20 74 79 70 65 69  ymlink;..} typei
1080: 6e 66 6f 3b 0a 0a 09 2f 2a 20 41 74 74 72 69 62  nfo;.../* Attrib
1090: 75 74 65 73 20 75 73 65 64 20 6f 6e 6c 79 20 66  utes used only f
10a0: 6f 72 20 63 61 63 68 69 6e 67 20 65 6e 74 72 69  or caching entri
10b0: 65 73 20 2a 2f 0a 09 63 68 61 72 20 2a 5f 63 61  es */..char *_ca
10c0: 63 68 65 5f 70 61 74 68 3b 0a 09 75 69 64 5f 74  che_path;..uid_t
10d0: 20 5f 63 61 63 68 65 5f 75 69 64 3b 0a 7d 3b 0a   _cache_uid;.};.
10e0: 0a 2f 2a 0a 20 2a 20 43 72 65 61 74 65 20 61 20  ./*. * Create a 
10f0: 6e 65 77 20 54 63 6c 20 69 6e 74 65 72 70 72 65  new Tcl interpre
1100: 74 65 72 20 61 6e 64 20 63 6f 6d 70 6c 65 74 65  ter and complete
1110: 6c 79 20 69 6e 69 74 69 61 6c 69 7a 65 20 69 74  ly initialize it
1120: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 54 63 6c 5f  . */.static Tcl_
1130: 49 6e 74 65 72 70 20 2a 61 70 70 66 73 5f 63 72  Interp *appfs_cr
1140: 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 63  eate_TclInterp(c
1150: 68 61 72 20 2a 2a 65 72 72 6f 72 5f 73 74 72 69  har **error_stri
1160: 6e 67 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  ng) {..Tcl_Inter
1170: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 69 6e 74 20  p *interp;..int 
1180: 74 63 6c 5f 72 65 74 3b 0a 09 63 6f 6e 73 74 20  tcl_ret;..const 
1190: 63 68 61 72 20 2a 74 63 6c 5f 73 65 74 76 61 72  char *tcl_setvar
11a0: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
11b0: 42 55 47 28 22 43 72 65 61 74 69 6e 67 20 6e 65  BUG("Creating ne
11c0: 77 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  w Tcl interprete
11d0: 72 20 66 6f 72 20 54 49 44 20 3d 20 30 78 25 6c  r for TID = 0x%l
11e0: 6c 78 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c  lx", (unsigned l
11f0: 6f 6e 67 20 6c 6f 6e 67 29 20 70 74 68 72 65 61  ong long) pthrea
1200: 64 5f 73 65 6c 66 28 29 29 3b 0a 0a 09 61 70 70  d_self());...app
1210: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
1220: 09 09 69 6e 74 65 72 70 20 3d 20 54 63 6c 5f 43  ..interp = Tcl_C
1230: 72 65 61 74 65 49 6e 74 65 72 70 28 29 3b 0a 09  reateInterp();..
1240: 29 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  )..if (interp ==
1250: 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e   NULL) {...fprin
1260: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
1270: 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54 63 6c  le to create Tcl
1280: 20 49 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41   Interpreter.  A
1290: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09  borting.\n");...
12a0: 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e  .if (error_strin
12b0: 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73  g) {....*error_s
12c0: 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 22  tring = strdup("
12d0: 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65  Unable to create
12e0: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
12f0: 2e 22 29 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 75  .");...}....retu
1300: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61  rn(NULL);..}...a
1310: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1320: 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e  (Tcl_Preserve(in
1330: 74 65 72 70 29 3b 29 0a 0a 09 61 70 70 66 73 5f  terp);)...appfs_
1340: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74  call_libtcl(...t
1350: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 49 6e 69  cl_ret = Tcl_Ini
1360: 74 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 09 69  t(interp);..)..i
1370: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
1380: 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74  L_OK) {...fprint
1390: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
13a0: 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20  e to initialize 
13b0: 54 63 6c 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c  Tcl.  Aborting.\
13c0: 6e 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c  n");...appfs_cal
13d0: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 66 70 72  l_libtcl(....fpr
13e0: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54 63  intf(stderr, "Tc
13f0: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e  l Error is: %s\n
1400: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
1410: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
1420: 0a 09 09 29 0a 0a 09 09 69 66 20 28 65 72 72 6f  ...)....if (erro
1430: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 61  r_string) {....a
1440: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1450: 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74 72  (.....*error_str
1460: 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c  ing = strdup(Tcl
1470: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
1480: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29 0a  (interp));....).
1490: 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c  ..}....appfs_cal
14a0: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
14b0: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
14c0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
14d0: 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20 69  erminating Tcl i
14e0: 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a  nterpreter.");..
14f0: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1500: 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e  tcl(Tcl_DeleteIn
1510: 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a  terp(interp);)..
1520: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
1530: 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .}...appfs_call_
1540: 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65  libtcl(...tcl_re
1550: 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74  t = Tcl_Eval(int
1560: 65 72 70 2c 20 22 70 61 63 6b 61 67 65 20 69 66  erp, "package if
1570: 6e 65 65 64 65 64 20 73 68 61 31 20 31 2e 30 20  needed sha1 1.0 
1580: 5b 6c 69 73 74 20 6c 6f 61 64 20 7b 7d 20 73 68  [list load {} sh
1590: 61 31 5d 22 29 3b 0a 09 29 0a 09 69 66 20 28 74  a1]");..)..if (t
15a0: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
15b0: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
15c0: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f  derr, "Unable to
15d0: 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20   initialize Tcl 
15e0: 53 48 41 31 2e 20 20 41 62 6f 72 74 69 6e 67 2e  SHA1.  Aborting.
15f0: 5c 6e 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61  \n");...appfs_ca
1600: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 66 70  ll_libtcl(....fp
1610: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54  rintf(stderr, "T
1620: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c  cl Error is: %s\
1630: 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  n", Tcl_GetStrin
1640: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
1650: 3b 0a 09 09 29 0a 0a 09 09 69 66 20 28 65 72 72  ;...)....if (err
1660: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09  or_string) {....
1670: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
1680: 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74  l(.....*error_st
1690: 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63  ring = strdup(Tc
16a0: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
16b0: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29  t(interp));....)
16c0: 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61  ...}....appfs_ca
16d0: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
16e0: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
16f0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
1700: 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20  Terminating Tcl 
1710: 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a  interpreter.");.
1720: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
1730: 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49  btcl(Tcl_DeleteI
1740: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a  nterp(interp);).
1750: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
1760: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..}...appfs_call
1770: 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72  _libtcl(...tcl_r
1780: 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e  et = Tcl_Eval(in
1790: 74 65 72 70 2c 20 22 70 61 63 6b 61 67 65 20 69  terp, "package i
17a0: 66 6e 65 65 64 65 64 20 61 70 70 66 73 64 20 31  fneeded appfsd 1
17b0: 2e 30 20 5b 6c 69 73 74 20 6c 6f 61 64 20 7b 7d  .0 [list load {}
17c0: 20 61 70 70 66 73 64 5d 22 29 3b 0a 09 29 0a 09   appfsd]");..)..
17d0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
17e0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e  CL_OK) {...fprin
17f0: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
1800: 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65  le to initialize
1810: 20 54 63 6c 20 41 70 70 46 53 20 50 61 63 6b 61   Tcl AppFS Packa
1820: 67 65 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e  ge.  Aborting.\n
1830: 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  ");...appfs_call
1840: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 66 70 72 69  _libtcl(....fpri
1850: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c  ntf(stderr, "Tcl
1860: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22   Error is: %s\n"
1870: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
1880: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
1890: 09 09 29 0a 0a 09 09 69 66 20 28 65 72 72 6f 72  ..)....if (error
18a0: 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 61 70  _string) {....ap
18b0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
18c0: 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69  .....*error_stri
18d0: 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f  ng = strdup(Tcl_
18e0: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
18f0: 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29 0a 09  interp));....)..
1900: 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  .}....appfs_call
1910: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
1920: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
1930: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 65  .APPFS_DEBUG("Te
1940: 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e  rminating Tcl in
1950: 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09  terpreter.");...
1960: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
1970: 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74  cl(Tcl_DeleteInt
1980: 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  erp(interp);)...
1990: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
19a0: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4c 6f 61 64 20  }.../*.. * Load 
19b0: 22 70 6b 69 2e 74 63 6c 22 20 69 6e 20 74 68 65  "pki.tcl" in the
19c0: 20 73 61 6d 65 20 77 61 79 20 61 73 20 61 70 70   same way as app
19d0: 66 73 64 2e 74 63 6c 20 28 73 65 65 20 62 65 6c  fsd.tcl (see bel
19e0: 6f 77 29 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f  ow).. */..appfs_
19f0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 6e 74 65  call_libtcl_ente
1a00: 72 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63  r...tcl_ret = Tc
1a10: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22  l_Eval(interp, "
1a20: 22 0a 23 69 6e 63 6c 75 64 65 20 22 70 6b 69 2e  ".#include "pki.
1a30: 74 63 6c 2e 68 22 0a 09 09 22 22 29 3b 0a 09 61  tcl.h"..."");..a
1a40: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1a50: 5f 65 78 69 74 0a 09 69 66 20 28 74 63 6c 5f 72  _exit..if (tcl_r
1a60: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
1a70: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
1a80: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69  , "Unable to ini
1a90: 74 69 61 6c 69 7a 65 20 54 63 6c 20 50 4b 49 2e  tialize Tcl PKI.
1aa0: 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b    Aborting.\n");
1ab0: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
1ac0: 62 74 63 6c 28 0a 09 09 09 66 70 72 69 6e 74 66  btcl(....fprintf
1ad0: 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45 72  (stderr, "Tcl Er
1ae0: 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54  ror is: %s\n", T
1af0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
1b00: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29  lt(interp));...)
1b10: 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73 74  ....if (error_st
1b20: 72 69 6e 67 29 20 7b 0a 09 09 09 61 70 70 66 73  ring) {....appfs
1b30: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
1b40: 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20  ..*error_string 
1b50: 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74  = strdup(Tcl_Get
1b60: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
1b70: 65 72 70 29 29 3b 0a 09 09 09 29 0a 09 09 7d 0a  erp));....)...}.
1b80: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
1b90: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
1ba0: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 41 50  (interp);)....AP
1bb0: 50 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69  PFS_DEBUG("Termi
1bc0: 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e 74 65 72  nating Tcl inter
1bd0: 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 61 70  preter.");....ap
1be0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
1bf0: 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70  Tcl_DeleteInterp
1c00: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65  (interp);)....re
1c10: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
1c20: 09 2f 2a 0a 09 20 2a 20 4c 6f 61 64 20 74 68 65  ./*.. * Load the
1c30: 20 22 61 70 70 66 73 64 2e 74 63 6c 22 20 73 63   "appfsd.tcl" sc
1c40: 72 69 70 74 2c 20 77 68 69 63 68 20 69 73 20 22  ript, which is "
1c50: 63 6f 6d 70 69 6c 65 64 22 20 69 6e 74 6f 20 61  compiled" into a
1c60: 20 43 20 68 65 61 64 65 72 0a 09 20 2a 20 73 6f   C header.. * so
1c70: 20 74 68 61 74 20 69 74 20 64 6f 65 73 20 6e 6f   that it does no
1c80: 74 20 6e 65 65 64 20 74 6f 20 65 78 69 73 74 20  t need to exist 
1c90: 6f 6e 20 74 68 65 20 66 69 6c 65 73 79 73 74 65  on the filesyste
1ca0: 6d 20 61 6e 64 20 63 61 6e 20 62 65 0a 09 20 2a  m and can be.. *
1cb0: 20 64 69 72 65 63 74 6c 79 20 65 76 61 6c 75 61   directly evalua
1cc0: 74 65 64 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73  ted... */..appfs
1cd0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 6e 74  _call_libtcl_ent
1ce0: 65 72 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54  er...tcl_ret = T
1cf0: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
1d00: 22 22 0a 23 69 6e 63 6c 75 64 65 20 22 61 70 70  "".#include "app
1d10: 66 73 64 2e 74 63 6c 2e 68 22 0a 09 09 22 22 29  fsd.tcl.h"..."")
1d20: 3b 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ;..appfs_call_li
1d30: 62 74 63 6c 5f 65 78 69 74 0a 09 69 66 20 28 74  btcl_exit..if (t
1d40: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
1d50: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
1d60: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f  derr, "Unable to
1d70: 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20   initialize Tcl 
1d80: 41 70 70 46 53 20 73 63 72 69 70 74 2e 20 20 41  AppFS script.  A
1d90: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09  borting.\n");...
1da0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
1db0: 6c 28 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74  l(....fprintf(st
1dc0: 64 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72  derr, "Tcl Error
1dd0: 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f   is: %s\n", Tcl_
1de0: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
1df0: 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09  interp));...)...
1e00: 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e  .if (error_strin
1e10: 67 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61  g) {....appfs_ca
1e20: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a  ll_libtcl(.....*
1e30: 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73  error_string = s
1e40: 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72  trdup(Tcl_GetStr
1e50: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
1e60: 29 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09  ));....)...}....
1e70: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
1e80: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
1e90: 74 65 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53  terp);)....APPFS
1ea0: 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74  _DEBUG("Terminat
1eb0: 69 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65  ing Tcl interpre
1ec0: 74 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73  ter.");....appfs
1ed0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
1ee0: 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e  _DeleteInterp(in
1ef0: 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72  terp);)....retur
1f00: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a  n(NULL);..}.../*
1f10: 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20  .. * Set global 
1f20: 76 61 72 69 61 62 6c 65 73 20 66 72 6f 6d 20 43  variables from C
1f30: 20 74 6f 20 54 63 6c 0a 09 20 2a 2f 0a 09 61 70   to Tcl.. */..ap
1f40: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
1f50: 0a 09 09 74 63 6c 5f 73 65 74 76 61 72 5f 72 65  ...tcl_setvar_re
1f60: 74 20 3d 20 54 63 6c 5f 53 65 74 56 61 72 28 69  t = Tcl_SetVar(i
1f70: 6e 74 65 72 70 2c 20 22 3a 3a 61 70 70 66 73 3a  nterp, "::appfs:
1f80: 3a 63 61 63 68 65 64 69 72 22 2c 20 61 70 70 66  :cachedir", appf
1f90: 73 5f 63 61 63 68 65 64 69 72 2c 20 54 43 4c 5f  s_cachedir, TCL_
1fa0: 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a 09 29  GLOBAL_ONLY);..)
1fb0: 0a 09 69 66 20 28 74 63 6c 5f 73 65 74 76 61 72  ..if (tcl_setvar
1fc0: 5f 72 65 74 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  _ret == NULL) {.
1fd0: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
1fe0: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 73 65 74  , "Unable to set
1ff0: 20 63 61 63 68 65 20 64 69 72 65 63 74 6f 72 79   cache directory
2000: 2e 20 20 54 68 69 73 20 73 68 6f 75 6c 64 20 6e  .  This should n
2010: 65 76 65 72 20 66 61 69 6c 2e 5c 6e 22 29 3b 0a  ever fail.\n");.
2020: 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72  ...if (error_str
2030: 69 6e 67 29 20 7b 0a 09 09 09 61 70 70 66 73 5f  ing) {....appfs_
2040: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
2050: 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d  .*error_string =
2060: 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53   strdup(Tcl_GetS
2070: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
2080: 72 70 29 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a  rp));....)...}..
2090: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
20a0: 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28  tcl(Tcl_Release(
20b0: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 41 50 50  interp);)....APP
20c0: 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e  FS_DEBUG("Termin
20d0: 61 74 69 6e 67 20 54 63 6c 20 69 6e 74 65 72 70  ating Tcl interp
20e0: 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70  reter.");....app
20f0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
2100: 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28  cl_DeleteInterp(
2110: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74  interp);)....ret
2120: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
2130: 2f 2a 0a 09 20 2a 20 49 6e 69 74 69 61 6c 69 7a  /*.. * Initializ
2140: 65 20 74 68 65 20 22 61 70 70 66 73 64 2e 74 63  e the "appfsd.tc
2150: 6c 22 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 2c 20  l" environment, 
2160: 77 68 69 63 68 20 6d 75 73 74 20 62 65 20 64 6f  which must be do
2170: 6e 65 20 61 66 74 65 72 0a 09 20 2a 20 67 6c 6f  ne after.. * glo
2180: 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20 61 72  bal variables ar
2190: 65 20 73 65 74 2e 0a 09 20 2a 2f 0a 09 61 70 70  e set... */..app
21a0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
21b0: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
21c0: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 3a 3a  Eval(interp, "::
21d0: 61 70 70 66 73 3a 3a 69 6e 69 74 22 29 3b 0a 09  appfs::init");..
21e0: 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  )..if (tcl_ret !
21f0: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70  = TCL_OK) {...fp
2200: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55  rintf(stderr, "U
2210: 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c  nable to initial
2220: 69 7a 65 20 54 63 6c 20 41 70 70 46 53 20 73 63  ize Tcl AppFS sc
2230: 72 69 70 74 20 28 3a 3a 61 70 70 66 73 3a 3a 69  ript (::appfs::i
2240: 6e 69 74 29 2e 20 20 41 62 6f 72 74 69 6e 67 2e  nit).  Aborting.
2250: 5c 6e 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61  \n");...appfs_ca
2260: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 66 70  ll_libtcl(....fp
2270: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54  rintf(stderr, "T
2280: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c  cl Error is: %s\
2290: 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  n", Tcl_GetStrin
22a0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
22b0: 3b 0a 09 09 29 0a 0a 09 09 69 66 20 28 65 72 72  ;...)....if (err
22c0: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09  or_string) {....
22d0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
22e0: 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74  l(.....*error_st
22f0: 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63  ring = strdup(Tc
2300: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
2310: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29  t(interp));....)
2320: 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61  ...}....appfs_ca
2330: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
2340: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
2350: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
2360: 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20  Terminating Tcl 
2370: 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a  interpreter.");.
2380: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
2390: 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49  btcl(Tcl_DeleteI
23a0: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a  nterp(interp);).
23b0: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
23c0: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 48 69 64  ..}.../*.. * Hid
23d0: 65 20 73 6f 6d 65 20 54 63 6c 20 63 6f 6d 6d 61  e some Tcl comma
23e0: 6e 64 73 20 74 68 61 74 20 77 65 20 64 6f 20 6e  nds that we do n
23f0: 6f 74 20 63 61 72 65 20 74 6f 20 75 73 65 20 61  ot care to use a
2400: 6e 64 20 77 68 69 63 68 20 6d 61 79 0a 09 20 2a  nd which may.. *
2410: 20 73 6c 6f 77 20 64 6f 77 6e 20 72 75 6e 2d 74   slow down run-t
2420: 69 6d 65 20 6f 70 65 72 61 74 69 6f 6e 73 2e 0a  ime operations..
2430: 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c  . */..appfs_call
2440: 5f 6c 69 62 74 63 6c 28 0a 09 09 54 63 6c 5f 48  _libtcl(...Tcl_H
2450: 69 64 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ideCommand(inter
2460: 70 2c 20 22 61 75 74 6f 5f 6c 6f 61 64 5f 69 6e  p, "auto_load_in
2470: 64 65 78 22 2c 20 22 61 75 74 6f 5f 6c 6f 61 64  dex", "auto_load
2480: 5f 69 6e 64 65 78 22 29 3b 0a 09 09 54 63 6c 5f  _index");...Tcl_
2490: 48 69 64 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  HideCommand(inte
24a0: 72 70 2c 20 22 75 6e 6b 6e 6f 77 6e 22 2c 20 22  rp, "unknown", "
24b0: 75 6e 6b 6e 6f 77 6e 22 29 3b 0a 09 09 54 63 6c  unknown");...Tcl
24c0: 5f 48 69 64 65 43 6f 6d 6d 61 6e 64 28 69 6e 74  _HideCommand(int
24d0: 65 72 70 2c 20 22 65 78 69 74 22 2c 20 22 65 78  erp, "exit", "ex
24e0: 69 74 22 29 3b 0a 09 29 0a 0a 09 2f 2a 0a 09 20  it");..).../*.. 
24f0: 2a 20 52 65 6c 65 61 73 65 20 74 68 65 20 68 6f  * Release the ho
2500: 6c 64 20 77 65 20 68 61 76 65 20 6f 6e 20 74 68  ld we have on th
2510: 65 20 69 6e 74 65 72 70 72 65 74 65 72 20 73 6f  e interpreter so
2520: 20 74 68 61 74 20 69 74 20 6d 61 79 20 62 65 0a   that it may be.
2530: 09 20 2a 20 64 65 6c 65 74 65 64 20 69 66 20 6e  . * deleted if n
2540: 65 65 64 65 64 0a 09 20 2a 2f 0a 09 61 70 70 66  eeded.. */..appf
2550: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
2560: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
2570: 29 3b 29 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 74  );).../*.. * Ret
2580: 75 72 6e 20 74 68 65 20 63 6f 6d 70 6c 65 74 65  urn the complete
2590: 6c 79 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 69  ly initialized i
25a0: 6e 74 65 72 70 72 65 74 65 72 0a 09 20 2a 2f 0a  nterpreter.. */.
25b0: 09 72 65 74 75 72 6e 28 69 6e 74 65 72 70 29 3b  .return(interp);
25c0: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 52 65 74 75 72 6e  .}../*. * Return
25d0: 20 74 68 65 20 74 68 72 65 61 64 2d 73 70 65 63   the thread-spec
25e0: 69 66 69 63 20 54 63 6c 20 69 6e 74 65 72 70 72  ific Tcl interpr
25f0: 65 74 65 72 2c 20 63 72 65 61 74 69 6e 67 20 69  eter, creating i
2600: 74 20 69 66 20 6e 65 65 64 65 64 0a 20 2a 2f 0a  t if needed. */.
2610: 73 74 61 74 69 63 20 54 63 6c 5f 49 6e 74 65 72  static Tcl_Inter
2620: 70 20 2a 61 70 70 66 73 5f 54 63 6c 49 6e 74 65  p *appfs_TclInte
2630: 72 70 28 76 6f 69 64 29 20 7b 0a 09 54 63 6c 5f  rp(void) {..Tcl_
2640: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
2650: 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74  .int pthread_ret
2660: 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65  ;..static __thre
2670: 61 64 20 69 6e 74 20 74 68 72 65 61 64 5f 69 6e  ad int thread_in
2680: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d  terp_reset_key =
2690: 20 30 3b 0a 09 69 6e 74 20 67 6c 6f 62 61 6c 5f   0;..int global_
26a0: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
26b0: 3b 0a 0a 09 67 6c 6f 62 61 6c 5f 69 6e 74 65 72  ;...global_inter
26c0: 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 5f 5f  p_reset_key = __
26d0: 73 79 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 61  sync_fetch_and_a
26e0: 64 64 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74  dd(&interp_reset
26f0: 5f 6b 65 79 2c 20 30 29 3b 0a 0a 09 69 6e 74 65  _key, 0);...inte
2700: 72 70 20 3d 20 70 74 68 72 65 61 64 5f 67 65 74  rp = pthread_get
2710: 73 70 65 63 69 66 69 63 28 69 6e 74 65 72 70 4b  specific(interpK
2720: 65 79 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  ey);..if (interp
2730: 20 21 3d 20 4e 55 4c 4c 20 26 26 20 74 68 72 65   != NULL && thre
2740: 61 64 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  ad_interp_reset_
2750: 6b 65 79 20 21 3d 20 67 6c 6f 62 61 6c 5f 69 6e  key != global_in
2760: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 29 20  terp_reset_key) 
2770: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
2780: 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 6f 6c 64  "Terminating old
2790: 20 69 6e 74 65 72 70 72 65 74 65 72 20 61 6e 64   interpreter and
27a0: 20 72 65 73 74 61 72 74 69 6e 67 20 64 75 65 20   restarting due 
27b0: 74 6f 20 72 65 73 65 74 20 72 65 71 75 65 73 74  to reset request
27c0: 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61  .");....appfs_ca
27d0: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65  ll_libtcl(Tcl_De
27e0: 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72  leteInterp(inter
27f0: 70 29 3b 29 0a 0a 09 09 69 6e 74 65 72 70 20 3d  p);)....interp =
2800: 20 4e 55 4c 4c 3b 0a 0a 09 09 70 74 68 72 65 61   NULL;....pthrea
2810: 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f  d_ret = pthread_
2820: 73 65 74 73 70 65 63 69 66 69 63 28 69 6e 74 65  setspecific(inte
2830: 72 70 4b 65 79 2c 20 69 6e 74 65 72 70 29 3b 0a  rpKey, interp);.
2840: 09 7d 0a 0a 09 69 66 20 28 67 6c 6f 62 61 6c 5f  .}...if (global_
2850: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
2860: 20 3d 3d 20 2d 31 29 20 7b 0a 09 09 41 50 50 46   == -1) {...APPF
2870: 53 5f 44 45 42 55 47 28 22 52 65 74 75 72 6e 69  S_DEBUG("Returni
2880: 6e 67 20 4e 55 4c 4c 20 73 69 6e 63 65 20 77 65  ng NULL since we
2890: 20 61 72 65 20 69 6e 20 74 68 65 20 70 72 6f 63   are in the proc
28a0: 65 73 73 20 6f 66 20 74 65 72 6d 69 6e 61 74 69  ess of terminati
28b0: 6e 67 20 61 6c 6c 20 74 68 72 65 61 64 73 2e 22  ng all threads."
28c0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  );....return(NUL
28d0: 4c 29 3b 0a 09 7d 0a 0a 09 74 68 72 65 61 64 5f  L);..}...thread_
28e0: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
28f0: 20 3d 20 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70   = global_interp
2900: 5f 72 65 73 65 74 5f 6b 65 79 3b 0a 0a 09 69 66  _reset_key;...if
2910: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
2920: 29 20 7b 0a 09 09 69 6e 74 65 72 70 20 3d 20 61  ) {...interp = a
2930: 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49  ppfs_create_TclI
2940: 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 0a 09 09  nterp(NULL);....
2950: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
2960: 4c 4c 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44  LL) {....APPFS_D
2970: 45 42 55 47 28 22 43 72 65 61 74 65 20 69 6e 74  EBUG("Create int
2980: 65 72 70 20 66 61 69 6c 65 64 2c 20 72 65 74 75  erp failed, retu
2990: 72 6e 69 6e 67 69 6e 20 66 61 69 6c 75 72 65 2e  rningin failure.
29a0: 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 4e  ");.....return(N
29b0: 55 4c 4c 29 3b 0a 09 09 7d 0a 0a 09 09 70 74 68  ULL);...}....pth
29c0: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
29d0: 61 64 5f 73 65 74 73 70 65 63 69 66 69 63 28 69  ad_setspecific(i
29e0: 6e 74 65 72 70 4b 65 79 2c 20 69 6e 74 65 72 70  nterpKey, interp
29f0: 29 3b 0a 09 09 69 66 20 28 70 74 68 72 65 61 64  );...if (pthread
2a00: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09  _ret != 0) {....
2a10: 41 50 50 46 53 5f 44 45 42 55 47 28 22 70 74 68  APPFS_DEBUG("pth
2a20: 72 65 61 64 5f 73 65 74 73 70 65 63 69 66 69 63  read_setspecific
2a30: 28 29 20 66 61 69 6c 65 64 2e 20 20 54 65 72 6d  () failed.  Term
2a40: 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e 74 65  inating Tcl inte
2a50: 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 09  rpreter.");.....
2a60: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
2a70: 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65  l(Tcl_DeleteInte
2a80: 72 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09  rp(interp);)....
2a90: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
2aa0: 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 69  .}..}...return(i
2ab0: 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  nterp);.}../*. *
2ac0: 20 45 76 61 6c 75 61 74 65 20 61 20 54 63 6c 20   Evaluate a Tcl 
2ad0: 73 63 72 69 70 74 20 63 6f 6e 73 74 72 75 63 74  script construct
2ae0: 65 64 20 62 79 20 63 6f 6e 63 61 74 65 6e 61 74  ed by concatenat
2af0: 69 6e 67 20 61 20 62 75 6e 63 68 20 6f 66 20 43  ing a bunch of C
2b00: 20 73 74 72 69 6e 67 73 0a 20 2a 20 74 6f 67 65   strings. * toge
2b10: 74 68 65 72 2e 0a 20 2a 2f 0a 73 74 61 74 69 63  ther.. */.static
2b20: 20 69 6e 74 20 61 70 70 66 73 5f 54 63 6c 5f 45   int appfs_Tcl_E
2b30: 76 61 6c 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a  val(Tcl_Interp *
2b40: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63  interp, int objc
2b50: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 6d  , const char *cm
2b60: 64 2c 20 2e 2e 2e 29 20 7b 0a 09 54 63 6c 5f 4f  d, ...) {..Tcl_O
2b70: 62 6a 20 2a 2a 6f 62 6a 76 3b 0a 09 63 6f 6e 73  bj **objv;..cons
2b80: 74 20 63 68 61 72 20 2a 61 72 67 3b 0a 09 76 61  t char *arg;..va
2b90: 5f 6c 69 73 74 20 61 72 67 70 3b 0a 09 69 6e 74  _list argp;..int
2ba0: 20 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20 69 3b   retval;..int i;
2bb0: 0a 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ...if (interp ==
2bc0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53   NULL) {...APPFS
2bd0: 5f 44 45 42 55 47 28 22 49 6e 76 61 6c 69 64 20  _DEBUG("Invalid 
2be0: 69 6e 74 65 72 70 72 65 74 65 72 20 70 61 73 73  interpreter pass
2bf0: 65 64 20 69 6e 2c 20 72 65 74 75 72 6e 69 6e 67  ed in, returning
2c00: 20 69 6e 20 66 61 69 6c 75 72 65 2e 22 29 3b 0a   in failure.");.
2c10: 0a 09 09 72 65 74 75 72 6e 28 54 43 4c 5f 45 52  ...return(TCL_ER
2c20: 52 4f 52 29 3b 0a 09 7d 0a 0a 09 6f 62 6a 76 20  ROR);..}...objv 
2c30: 3d 20 28 76 6f 69 64 20 2a 29 20 63 6b 61 6c 6c  = (void *) ckall
2c40: 6f 63 28 73 69 7a 65 6f 66 28 2a 6f 62 6a 76 29  oc(sizeof(*objv)
2c50: 20 2a 20 6f 62 6a 63 29 3b 0a 0a 09 61 70 70 66   * objc);...appf
2c60: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
2c70: 09 6f 62 6a 76 5b 30 5d 20 3d 20 54 63 6c 5f 4e  .objv[0] = Tcl_N
2c80: 65 77 53 74 72 69 6e 67 4f 62 6a 28 63 6d 64 2c  ewStringObj(cmd,
2c90: 20 2d 31 29 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63   -1);....Tcl_Inc
2ca0: 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 30  rRefCount(objv[0
2cb0: 5d 29 3b 0a 0a 09 09 76 61 5f 73 74 61 72 74 28  ]);....va_start(
2cc0: 61 72 67 70 2c 20 63 6d 64 29 3b 0a 09 09 66 6f  argp, cmd);...fo
2cd0: 72 20 28 69 20 3d 20 31 3b 20 69 20 3c 20 6f 62  r (i = 1; i < ob
2ce0: 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09 09 09 61 72  jc; i++) {....ar
2cf0: 67 20 3d 20 76 61 5f 61 72 67 28 61 72 67 70 2c  g = va_arg(argp,
2d00: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 29 3b 0a   const char *);.
2d10: 0a 09 09 09 6f 62 6a 76 5b 69 5d 20 3d 20 54 63  ....objv[i] = Tc
2d20: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 61  l_NewStringObj(a
2d30: 72 67 2c 20 2d 31 29 3b 0a 0a 09 09 09 54 63 6c  rg, -1);.....Tcl
2d40: 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 6f 62  _IncrRefCount(ob
2d50: 6a 76 5b 69 5d 29 3b 0a 09 09 7d 0a 09 09 76 61  jv[i]);...}...va
2d60: 5f 65 6e 64 28 61 72 67 70 29 3b 0a 09 29 0a 0a  _end(argp);..)..
2d70: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
2d80: 63 6c 28 0a 09 09 72 65 74 76 61 6c 20 3d 20 54  cl(...retval = T
2d90: 63 6c 5f 45 76 61 6c 4f 62 6a 76 28 69 6e 74 65  cl_EvalObjv(inte
2da0: 72 70 2c 20 6f 62 6a 63 2c 20 6f 62 6a 76 2c 20  rp, objc, objv, 
2db0: 30 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63  0);..)...appfs_c
2dc0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 66 6f  all_libtcl(...fo
2dd0: 72 20 28 69 20 3d 20 30 3b 20 69 20 3c 20 6f 62  r (i = 0; i < ob
2de0: 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09 09 09 54 63  jc; i++) {....Tc
2df0: 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 6f  l_DecrRefCount(o
2e00: 62 6a 76 5b 69 5d 29 3b 0a 09 09 7d 0a 09 29 0a  bjv[i]);...}..).
2e10: 0a 09 63 6b 66 72 65 65 28 28 76 6f 69 64 20 2a  ..ckfree((void *
2e20: 29 20 6f 62 6a 76 29 3b 0a 0a 09 69 66 20 28 72  ) objv);...if (r
2e30: 65 74 76 61 6c 20 21 3d 20 54 43 4c 5f 4f 4b 29  etval != TCL_OK)
2e40: 20 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f   {...appfs_call_
2e50: 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53  libtcl(....APPFS
2e60: 5f 44 45 42 55 47 28 22 54 63 6c 20 63 6f 6d 6d  _DEBUG("Tcl comm
2e70: 61 6e 64 20 66 61 69 6c 65 64 2c 20 3a 3a 65 72  and failed, ::er
2e80: 72 6f 72 49 6e 66 6f 20 63 6f 6e 74 61 69 6e 73  rorInfo contains
2e90: 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74  : %s\n", Tcl_Get
2ea0: 56 61 72 28 69 6e 74 65 72 70 2c 20 22 3a 3a 65  Var(interp, "::e
2eb0: 72 72 6f 72 49 6e 66 6f 22 2c 20 30 29 29 3b 0a  rrorInfo", 0));.
2ec0: 09 09 29 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  ..)..}...return(
2ed0: 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20  retval);.}../*. 
2ee0: 2a 20 52 65 71 75 65 73 74 20 61 6c 6c 20 54 63  * Request all Tc
2ef0: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 73 20 72  l interpreters r
2f00: 65 73 74 61 72 74 0a 20 2a 2f 0a 73 74 61 74 69  estart. */.stati
2f10: 63 20 76 6f 69 64 20 61 70 70 66 73 5f 74 63 6c  c void appfs_tcl
2f20: 5f 52 65 73 65 74 49 6e 74 65 72 70 73 28 76 6f  _ResetInterps(vo
2f30: 69 64 29 20 7b 0a 09 41 50 50 46 53 5f 44 45 42  id) {..APPFS_DEB
2f40: 55 47 28 22 52 65 71 75 65 73 74 69 6e 67 20 72  UG("Requesting r
2f50: 65 73 65 74 20 6f 66 20 61 6c 6c 20 69 6e 74 65  eset of all inte
2f60: 72 70 72 65 74 65 72 73 2e 22 29 3b 0a 0a 09 5f  rpreters.");..._
2f70: 5f 73 79 6e 63 5f 61 64 64 5f 61 6e 64 5f 66 65  _sync_add_and_fe
2f80: 74 63 68 28 26 69 6e 74 65 72 70 5f 72 65 73 65  tch(&interp_rese
2f90: 74 5f 6b 65 79 2c 20 31 29 3b 0a 0a 09 72 65 74  t_key, 1);...ret
2fa0: 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44 65  urn;.}../*. * De
2fb0: 74 65 72 6d 69 6e 65 20 74 68 65 20 55 49 44 20  termine the UID 
2fc0: 66 6f 72 20 74 68 65 20 75 73 65 72 20 6d 61 6b  for the user mak
2fd0: 69 6e 67 20 74 68 65 20 63 75 72 72 65 6e 74 20  ing the current 
2fe0: 46 55 53 45 20 66 69 6c 65 73 79 73 74 65 6d 20  FUSE filesystem 
2ff0: 72 65 71 75 65 73 74 2e 0a 20 2a 20 54 68 69 73  request.. * This
3000: 20 77 69 6c 6c 20 62 65 20 75 73 65 64 20 74 6f   will be used to
3010: 20 6c 6f 6f 6b 75 70 20 74 68 65 20 75 73 65 72   lookup the user
3020: 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  's home director
3030: 79 20 73 6f 20 77 65 20 63 61 6e 20 73 65 61 72  y so we can sear
3040: 63 68 20 66 6f 72 0a 20 2a 20 6c 6f 63 61 6c 6c  ch for. * locall
3050: 79 20 6d 6f 64 69 66 69 65 64 20 66 69 6c 65 73  y modified files
3060: 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 75 69 64  .. */.static uid
3070: 5f 74 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75  _t appfs_get_fsu
3080: 69 64 28 76 6f 69 64 29 20 7b 0a 09 73 74 72 75  id(void) {..stru
3090: 63 74 20 66 75 73 65 5f 63 6f 6e 74 65 78 74 20  ct fuse_context 
30a0: 2a 63 74 78 3b 0a 0a 09 69 66 20 28 21 61 70 70  *ctx;...if (!app
30b0: 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 29  fs_fuse_started)
30c0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 67 65 74 75   {...return(getu
30d0: 69 64 28 29 29 3b 0a 09 7d 0a 0a 09 63 74 78 20  id());..}...ctx 
30e0: 3d 20 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65  = fuse_get_conte
30f0: 78 74 28 29 3b 0a 09 69 66 20 28 63 74 78 20 3d  xt();..if (ctx =
3100: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20 55  = NULL) {.../* U
3110: 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20  nable to lookup 
3120: 75 73 65 72 20 66 6f 72 20 73 6f 6d 65 20 72 65  user for some re
3130: 61 73 6f 6e 20 2a 2f 0a 09 09 2f 2a 20 52 65 74  ason */.../* Ret
3140: 75 72 6e 20 61 6e 20 75 6e 70 72 69 76 69 6c 65  urn an unprivile
3150: 67 65 64 20 75 73 65 72 20 49 44 20 2a 2f 0a 09  ged user ID */..
3160: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
3170: 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 75  able to lookup u
3180: 73 65 72 20 66 6f 72 20 73 6f 6d 65 20 72 65 61  ser for some rea
3190: 73 6f 6e 2c 20 72 65 74 75 72 6e 69 6e 6e 67 20  son, returninng 
31a0: 75 73 65 72 20 49 44 20 6f 66 20 31 22 29 3b 0a  user ID of 1");.
31b0: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
31c0: 0a 0a 09 72 65 74 75 72 6e 28 63 74 78 2d 3e 75  ...return(ctx->u
31d0: 69 64 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44 65  id);.}../*. * De
31e0: 74 65 72 6d 69 6e 65 20 74 68 65 20 47 49 44 20  termine the GID 
31f0: 66 6f 72 20 74 68 65 20 75 73 65 72 20 6d 61 6b  for the user mak
3200: 69 6e 67 20 74 68 65 20 63 75 72 72 65 6e 74 20  ing the current 
3210: 46 55 53 45 20 66 69 6c 65 73 79 73 74 65 6d 20  FUSE filesystem 
3220: 72 65 71 75 65 73 74 2e 0a 20 2a 20 54 68 69 73  request.. * This
3230: 20 77 69 6c 6c 20 62 65 20 75 73 65 64 20 74 6f   will be used to
3240: 20 6c 6f 6f 6b 75 70 20 74 68 65 20 75 73 65 72   lookup the user
3250: 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  's home director
3260: 79 20 73 6f 20 77 65 20 63 61 6e 20 73 65 61 72  y so we can sear
3270: 63 68 20 66 6f 72 0a 20 2a 20 6c 6f 63 61 6c 6c  ch for. * locall
3280: 79 20 6d 6f 64 69 66 69 65 64 20 66 69 6c 65 73  y modified files
3290: 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 67 69 64  .. */.static gid
32a0: 5f 74 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67  _t appfs_get_fsg
32b0: 69 64 28 76 6f 69 64 29 20 7b 0a 09 73 74 72 75  id(void) {..stru
32c0: 63 74 20 66 75 73 65 5f 63 6f 6e 74 65 78 74 20  ct fuse_context 
32d0: 2a 63 74 78 3b 0a 0a 09 69 66 20 28 21 61 70 70  *ctx;...if (!app
32e0: 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 29  fs_fuse_started)
32f0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 67 65 74 67   {...return(getg
3300: 69 64 28 29 29 3b 0a 09 7d 0a 0a 09 63 74 78 20  id());..}...ctx 
3310: 3d 20 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65  = fuse_get_conte
3320: 78 74 28 29 3b 0a 09 69 66 20 28 63 74 78 20 3d  xt();..if (ctx =
3330: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20 55  = NULL) {.../* U
3340: 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20  nable to lookup 
3350: 75 73 65 72 20 66 6f 72 20 73 6f 6d 65 20 72 65  user for some re
3360: 61 73 6f 6e 20 2a 2f 0a 09 09 2f 2a 20 52 65 74  ason */.../* Ret
3370: 75 72 6e 20 61 6e 20 75 6e 70 72 69 76 69 6c 65  urn an unprivile
3380: 67 65 64 20 75 73 65 72 20 49 44 20 2a 2f 0a 09  ged user ID */..
3390: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
33a0: 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 67  able to lookup g
33b0: 72 6f 75 70 20 66 6f 72 20 73 6f 6d 65 20 72 65  roup for some re
33c0: 61 73 6f 6e 2c 20 72 65 74 75 72 6e 69 6e 6e 67  ason, returninng
33d0: 20 67 72 6f 75 70 20 49 44 20 6f 66 20 31 22 29   group ID of 1")
33e0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a  ;....return(1);.
33f0: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 63 74 78 2d  .}...return(ctx-
3400: 3e 67 69 64 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  >gid);.}..static
3410: 20 76 6f 69 64 20 61 70 70 66 73 5f 73 69 6d 75   void appfs_simu
3420: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
3430: 65 72 28 76 6f 69 64 29 20 7b 0a 09 73 65 74 66  er(void) {..setf
3440: 73 75 69 64 28 61 70 70 66 73 5f 67 65 74 5f 66  suid(appfs_get_f
3450: 73 75 69 64 28 29 29 3b 0a 09 73 65 74 66 73 67  suid());..setfsg
3460: 69 64 28 61 70 70 66 73 5f 67 65 74 5f 66 73 67  id(appfs_get_fsg
3470: 69 64 28 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  id());.}..static
3480: 20 76 6f 69 64 20 61 70 70 66 73 5f 73 69 6d 75   void appfs_simu
3490: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
34a0: 76 65 28 76 6f 69 64 29 20 7b 0a 09 73 65 74 66  ve(void) {..setf
34b0: 73 75 69 64 28 30 29 3b 0a 09 73 65 74 66 73 67  suid(0);..setfsg
34c0: 69 64 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  id(0);.}../*. * 
34d0: 4c 6f 6f 6b 20 75 70 20 74 68 65 20 68 6f 6d 65  Look up the home
34e0: 20 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20 61   directory for a
34f0: 20 67 69 76 65 6e 20 55 49 44 0a 20 2a 20 20 20   given UID. *   
3500: 20 20 20 20 20 52 65 74 75 72 6e 73 20 61 20 43       Returns a C
3510: 20 73 74 72 69 6e 67 20 63 6f 6e 74 61 69 6e 69   string containi
3520: 6e 67 20 74 68 65 20 75 73 65 72 27 73 20 68 6f  ng the user's ho
3530: 6d 65 20 64 69 72 65 63 74 6f 72 79 20 6f 72 20  me directory or 
3540: 4e 55 4c 4c 20 69 66 0a 20 2a 20 20 20 20 20 20  NULL if. *      
3550: 20 20 74 68 65 20 75 73 65 72 27 73 20 68 6f 6d    the user's hom
3560: 65 20 64 69 72 65 63 74 6f 72 79 20 64 6f 65 73  e directory does
3570: 20 6e 6f 74 20 65 78 69 73 74 20 6f 72 20 69 73   not exist or is
3580: 20 6e 6f 74 20 63 6f 72 72 65 63 74 6c 79 0a 20   not correctly. 
3590: 2a 20 20 20 20 20 20 20 20 63 6f 6e 66 69 67 75  *        configu
35a0: 72 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 63  red. */.static c
35b0: 68 61 72 20 2a 61 70 70 66 73 5f 67 65 74 5f 68  har *appfs_get_h
35c0: 6f 6d 65 64 69 72 28 75 69 64 5f 74 20 66 73 75  omedir(uid_t fsu
35d0: 69 64 29 20 7b 0a 09 73 74 72 75 63 74 20 70 61  id) {..struct pa
35e0: 73 73 77 64 20 65 6e 74 72 79 2c 20 2a 72 65 73  sswd entry, *res
35f0: 75 6c 74 3b 0a 09 73 74 72 75 63 74 20 73 74 61  ult;..struct sta
3600: 74 20 73 74 62 75 66 3b 0a 09 63 68 61 72 20 62  t stbuf;..char b
3610: 75 66 5b 31 30 32 34 5d 2c 20 2a 72 65 74 76 61  uf[1024], *retva
3620: 6c 3b 0a 09 69 6e 74 20 67 70 75 5f 72 65 74 2c  l;..int gpu_ret,
3630: 20 73 74 61 74 5f 72 65 74 3b 0a 0a 09 67 70 75   stat_ret;...gpu
3640: 5f 72 65 74 20 3d 20 67 65 74 70 77 75 69 64 5f  _ret = getpwuid_
3650: 72 28 66 73 75 69 64 2c 20 26 65 6e 74 72 79 2c  r(fsuid, &entry,
3660: 20 62 75 66 2c 20 73 69 7a 65 6f 66 28 62 75 66   buf, sizeof(buf
3670: 29 2c 20 26 72 65 73 75 6c 74 29 3b 0a 09 69 66  ), &result);..if
3680: 20 28 67 70 75 5f 72 65 74 20 21 3d 20 30 29 20   (gpu_ret != 0) 
3690: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
36a0: 22 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c 75  "getpwuid_r(%llu
36b0: 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64 20  , ...) returned 
36c0: 69 6e 20 66 61 69 6c 75 72 65 22 2c 20 28 75 6e  in failure", (un
36d0: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
36e0: 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72 65 74  ) fsuid);....ret
36f0: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
3700: 69 66 20 28 72 65 73 75 6c 74 20 3d 3d 20 4e 55  if (result == NU
3710: 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  LL) {...APPFS_DE
3720: 42 55 47 28 22 67 65 74 70 77 75 69 64 5f 72 28  BUG("getpwuid_r(
3730: 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 74 75 72  %llu, ...) retur
3740: 6e 65 64 20 4e 55 4c 4c 20 72 65 73 75 6c 74 22  ned NULL result"
3750: 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67  , (unsigned long
3760: 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b 0a 0a   long) fsuid);..
3770: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
3780: 09 7d 0a 0a 09 69 66 20 28 72 65 73 75 6c 74 2d  .}...if (result-
3790: 3e 70 77 5f 64 69 72 20 3d 3d 20 4e 55 4c 4c 29  >pw_dir == NULL)
37a0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
37b0: 28 22 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c  ("getpwuid_r(%ll
37c0: 75 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64  u, ...) returned
37d0: 20 4e 55 4c 4c 20 68 6f 6d 65 20 64 69 72 65 63   NULL home direc
37e0: 74 6f 72 79 22 2c 20 28 75 6e 73 69 67 6e 65 64  tory", (unsigned
37f0: 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69   long long) fsui
3800: 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  d);....return(NU
3810: 4c 4c 29 3b 0a 09 7d 0a 0a 09 73 74 61 74 5f 72  LL);..}...stat_r
3820: 65 74 20 3d 20 73 74 61 74 28 72 65 73 75 6c 74  et = stat(result
3830: 2d 3e 70 77 5f 64 69 72 2c 20 26 73 74 62 75 66  ->pw_dir, &stbuf
3840: 29 3b 0a 09 69 66 20 28 73 74 61 74 5f 72 65 74  );..if (stat_ret
3850: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53   != 0) {...APPFS
3860: 5f 44 45 42 55 47 28 22 73 74 61 74 28 25 73 29  _DEBUG("stat(%s)
3870: 20 72 65 74 75 72 6e 65 64 20 69 6e 20 66 61 69   returned in fai
3880: 6c 75 72 65 22 2c 20 72 65 73 75 6c 74 2d 3e 70  lure", result->p
3890: 77 5f 64 69 72 29 3b 0a 0a 09 09 72 65 74 75 72  w_dir);....retur
38a0: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66  n(NULL);..}...if
38b0: 20 28 73 74 62 75 66 2e 73 74 5f 75 69 64 20 21   (stbuf.st_uid !
38c0: 3d 20 66 73 75 69 64 29 20 7b 0a 09 09 41 50 50  = fsuid) {...APP
38d0: 46 53 5f 44 45 42 55 47 28 22 55 49 44 20 6d 69  FS_DEBUG("UID mi
38e0: 73 2d 6d 61 74 63 68 20 6f 6e 20 75 73 65 72 20  s-match on user 
38f0: 25 6c 6c 75 27 73 20 68 6f 6d 65 20 64 69 72 65  %llu's home dire
3900: 63 74 6f 72 79 20 28 25 73 29 2e 20 20 49 74 27  ctory (%s).  It'
3910: 73 20 6f 77 6e 65 64 20 62 79 20 25 6c 6c 75 2e  s owned by %llu.
3920: 22 2c 0a 09 09 20 20 20 20 28 75 6e 73 69 67 6e  ",...    (unsign
3930: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73  ed long long) fs
3940: 75 69 64 2c 0a 09 09 20 20 20 20 72 65 73 75 6c  uid,...    resul
3950: 74 2d 3e 70 77 5f 64 69 72 2c 0a 09 09 20 20 20  t->pw_dir,...   
3960: 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20   (unsigned long 
3970: 6c 6f 6e 67 29 20 73 74 62 75 66 2e 73 74 5f 75  long) stbuf.st_u
3980: 69 64 0a 09 09 29 3b 0a 0a 09 09 72 65 74 75 72  id...);....retur
3990: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65  n(NULL);..}...re
39a0: 74 76 61 6c 20 3d 20 73 74 72 64 75 70 28 72 65  tval = strdup(re
39b0: 73 75 6c 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a  sult->pw_dir);..
39c0: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
39d0: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 47 65 6e 65 72 61  .}../*. * Genera
39e0: 74 65 20 61 6e 20 69 6e 6f 64 65 20 66 6f 72 20  te an inode for 
39f0: 61 20 67 69 76 65 6e 20 70 61 74 68 2e 20 20 54  a given path.  T
3a00: 68 65 20 69 6e 6f 64 65 20 73 68 6f 75 6c 64 20  he inode should 
3a10: 62 65 20 63 6f 6d 70 75 74 65 64 20 69 6e 20 73  be computed in s
3a20: 75 63 68 0a 20 2a 20 61 20 77 61 79 20 74 68 61  uch. * a way tha
3a30: 74 20 69 74 20 69 73 20 75 6e 6c 69 6b 65 6c 79  t it is unlikely
3a40: 20 74 6f 20 62 65 20 64 75 70 6c 69 63 61 74 65   to be duplicate
3a50: 64 20 61 6e 64 20 72 65 6d 61 69 6e 73 20 74 68  d and remains th
3a60: 65 20 73 61 6d 65 20 66 6f 72 20 61 20 67 69 76  e same for a giv
3a70: 65 6e 0a 20 2a 20 66 69 6c 65 0a 20 2a 0a 20 2a  en. * file. *. *
3a80: 20 43 75 72 72 65 6e 74 20 69 6d 70 6c 65 6d 65   Current impleme
3a90: 6e 74 61 74 69 6f 6e 20 69 73 20 61 6e 20 46 4e  ntation is an FN
3aa0: 56 2d 31 61 20 33 32 2d 62 69 74 0a 20 2a 2f 0a  V-1a 32-bit. */.
3ab0: 23 69 66 20 55 49 4e 54 5f 4d 41 58 20 3c 20 34  #if UINT_MAX < 4
3ac0: 32 39 34 39 36 37 32 39 35 0a 23 65 72 72 6f 72  294967295.#error
3ad0: 20 49 6e 74 65 67 65 72 20 73 69 7a 65 20 69 73   Integer size is
3ae0: 20 74 6f 6f 20 73 6d 61 6c 6c 20 0a 23 65 6e 64   too small .#end
3af0: 69 66 0a 73 74 61 74 69 63 20 75 6e 73 69 67 6e  if.static unsign
3b00: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 20 61 70 70  ed long long app
3b10: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64  fs_get_path_inod
3b20: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  e(const char *pa
3b30: 74 68 2c 20 69 6e 74 20 75 69 64 29 20 7b 0a 09  th, int uid) {..
3b40: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 72 65 74  unsigned int ret
3b50: 76 61 6c 3b 0a 09 63 6f 6e 73 74 20 75 6e 73 69  val;..const unsi
3b60: 67 6e 65 64 20 63 68 61 72 20 2a 70 3b 0a 0a 09  gned char *p;...
3b70: 72 65 74 76 61 6c 20 3d 20 32 31 36 36 31 33 36  retval = 2166136
3b80: 32 36 31 3b 20 2f 2a 20 46 4e 56 2d 31 61 20 33  261; /* FNV-1a 3
3b90: 32 2d 62 69 74 20 6f 66 66 73 65 74 5f 62 61 73  2-bit offset_bas
3ba0: 69 73 20 2a 2f 0a 0a 09 66 6f 72 20 28 70 20 3d  is */...for (p =
3bb0: 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20   (unsigned char 
3bc0: 2a 29 20 70 61 74 68 3b 20 2a 70 3b 20 70 2b 2b  *) path; *p; p++
3bd0: 29 20 7b 0a 09 09 72 65 74 76 61 6c 20 5e 3d 20  ) {...retval ^= 
3be0: 28 69 6e 74 29 20 2a 70 3b 0a 23 69 66 20 30 0a  (int) *p;.#if 0.
3bf0: 09 09 72 65 74 76 61 6c 20 2a 3d 20 31 36 37 37  ..retval *= 1677
3c00: 37 36 31 39 3b 20 2f 2a 20 46 4e 56 2d 31 61 20  7619; /* FNV-1a 
3c10: 33 32 2d 62 69 74 20 70 72 69 6d 65 20 2a 2f 0a  32-bit prime */.
3c20: 23 65 6c 73 65 0a 09 09 2f 2a 20 47 43 43 20 4f  #else.../* GCC O
3c30: 70 74 69 6d 69 7a 65 64 20 72 65 70 6c 61 63 65  ptimized replace
3c40: 6d 65 6e 74 20 2a 2f 0a 09 09 72 65 74 76 61 6c  ment */...retval
3c50: 20 2b 3d 20 28 72 65 74 76 61 6c 20 3c 3c 20 31   += (retval << 1
3c60: 29 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 34  ) + (retval << 4
3c70: 29 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 37  ) + (retval << 7
3c80: 29 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 38  ) + (retval << 8
3c90: 29 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 32  ) + (retval << 2
3ca0: 34 29 3b 0a 23 65 6e 64 69 66 0a 09 7d 0a 0a 09  4);.#endif..}...
3cb0: 69 66 20 28 75 69 64 20 3e 3d 20 30 29 20 7b 0a  if (uid >= 0) {.
3cc0: 09 09 72 65 74 76 61 6c 20 2b 3d 20 75 69 64 3b  ..retval += uid;
3cd0: 0a 09 09 72 65 74 76 61 6c 2b 2b 3b 0a 09 7d 0a  ...retval++;..}.
3ce0: 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
3cf0: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 61 63 68 65  ;.}../*. * Cache
3d00: 20 47 65 74 20 50 61 74 68 20 49 6e 66 6f 20 6c   Get Path Info l
3d10: 6f 6f 6b 75 70 73 20 66 6f 72 20 73 70 65 65 64  ookups for speed
3d20: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  . */.static int 
3d30: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
3d40: 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28 63 6f  nfo_cache_get(co
3d50: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
3d60: 75 69 64 5f 74 20 75 69 64 2c 20 73 74 72 75 63  uid_t uid, struc
3d70: 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f  t appfs_pathinfo
3d80: 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 75   *pathinfo) {..u
3d90: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68  nsigned int hash
3da0: 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65  _idx;..int pthre
3db0: 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65 74  ad_ret;..int ret
3dc0: 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  val;...retval = 
3dd0: 31 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74  1;...pthread_ret
3de0: 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78   = pthread_mutex
3df0: 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74  _lock(&appfs_pat
3e00: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74  h_info_cache_mut
3e10: 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61  ex);..if (pthrea
3e20: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
3e30: 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61  APPFS_DEBUG("Una
3e40: 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68  ble to lock path
3e50: 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65  _info cache mute
3e60: 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  x !");....return
3e70: 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 61  (-1);..}...if (a
3e80: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
3e90: 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  ache != NULL) {.
3ea0: 09 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61 70  ..hash_idx = (ap
3eb0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f  pfs_get_path_ino
3ec0: 64 65 28 70 61 74 68 2c 20 75 69 64 29 29 20 25  de(path, uid)) %
3ed0: 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f   appfs_path_info
3ee0: 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 09  _cache_size;....
3ef0: 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69  if (appfs_path_i
3f00: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69  nfo_cache[hash_i
3f10: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20  dx]._cache_path 
3f20: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 69 66  != NULL) {....if
3f30: 20 28 73 74 72 63 6d 70 28 61 70 70 66 73 5f 70   (strcmp(appfs_p
3f40: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68  ath_info_cache[h
3f50: 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f  ash_idx]._cache_
3f60: 70 61 74 68 2c 20 70 61 74 68 29 20 3d 3d 20 30  path, path) == 0
3f70: 20 26 26 20 61 70 70 66 73 5f 70 61 74 68 5f 69   && appfs_path_i
3f80: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69  nfo_cache[hash_i
3f90: 64 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64 20 3d  dx]._cache_uid =
3fa0: 3d 20 75 69 64 29 20 7b 0a 09 09 09 09 72 65 74  = uid) {.....ret
3fb0: 76 61 6c 20 3d 20 30 3b 0a 0a 09 09 09 09 6d 65  val = 0;......me
3fc0: 6d 63 70 79 28 70 61 74 68 69 6e 66 6f 2c 20 26  mcpy(pathinfo, &
3fd0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
3fe0: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2c  cache[hash_idx],
3ff0: 20 73 69 7a 65 6f 66 28 2a 70 61 74 68 69 6e 66   sizeof(*pathinf
4000: 6f 29 29 3b 0a 09 09 09 09 70 61 74 68 69 6e 66  o));.....pathinf
4010: 6f 2d 3e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d  o->_cache_path =
4020: 20 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a   NULL;....}...}.
4030: 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74  .}...pthread_ret
4040: 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78   = pthread_mutex
4050: 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70  _unlock(&appfs_p
4060: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d  ath_info_cache_m
4070: 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72  utex);..if (pthr
4080: 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  ead_ret != 0) {.
4090: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55  ..APPFS_DEBUG("U
40a0: 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20  nable to unlock 
40b0: 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20  path_info cache 
40c0: 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65  mutex !");....re
40d0: 74 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69  turn(-1);..}...i
40e0: 66 20 28 72 65 74 76 61 6c 20 3d 3d 20 30 29 20  f (retval == 0) 
40f0: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
4100: 22 43 61 63 68 65 20 68 69 74 20 6f 6e 20 25 73  "Cache hit on %s
4110: 22 2c 20 70 61 74 68 29 3b 0a 09 7d 20 65 6c 73  ", path);..} els
4120: 65 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  e {...APPFS_DEBU
4130: 47 28 22 43 61 63 68 65 20 6d 69 73 73 20 6f 6e  G("Cache miss on
4140: 20 25 73 22 2c 20 70 61 74 68 29 3b 0a 09 7d 0a   %s", path);..}.
4150: 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
4160: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64  ;.}..static void
4170: 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f   appfs_get_path_
4180: 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64 64 28 63  info_cache_add(c
4190: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
41a0: 20 75 69 64 5f 74 20 75 69 64 2c 20 73 74 72 75   uid_t uid, stru
41b0: 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66  ct appfs_pathinf
41c0: 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09  o *pathinfo) {..
41d0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73  unsigned int has
41e0: 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72  h_idx;..int pthr
41f0: 65 61 64 5f 72 65 74 3b 0a 0a 09 70 74 68 72 65  ead_ret;...pthre
4200: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  ad_ret = pthread
4210: 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70  _mutex_lock(&app
4220: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4230: 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28  he_mutex);..if (
4240: 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30  pthread_ret != 0
4250: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
4260: 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63  G("Unable to loc
4270: 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68  k path_info cach
4280: 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09  e mutex !");....
4290: 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20  return;..}...if 
42a0: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  (appfs_path_info
42b0: 5f 63 61 63 68 65 20 3d 3d 20 4e 55 4c 4c 29 20  _cache == NULL) 
42c0: 7b 0a 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69  {...appfs_path_i
42d0: 6e 66 6f 5f 63 61 63 68 65 20 3d 20 63 61 6c 6c  nfo_cache = call
42e0: 6f 63 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  oc(appfs_path_in
42f0: 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 2c 20 73  fo_cache_size, s
4300: 69 7a 65 6f 66 28 2a 61 70 70 66 73 5f 70 61 74  izeof(*appfs_pat
4310: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 29 29 3b 0a  h_info_cache));.
4320: 09 7d 0a 0a 09 68 61 73 68 5f 69 64 78 20 3d 20  .}...hash_idx = 
4330: 28 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  (appfs_get_path_
4340: 69 6e 6f 64 65 28 70 61 74 68 2c 20 75 69 64 29  inode(path, uid)
4350: 29 20 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69  ) % appfs_path_i
4360: 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a  nfo_cache_size;.
4370: 0a 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68  ..if (appfs_path
4380: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
4390: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  _idx]._cache_pat
43a0: 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66  h != NULL) {...f
43b0: 72 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69  ree(appfs_path_i
43c0: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69  nfo_cache[hash_i
43d0: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 29  dx]._cache_path)
43e0: 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79 28 26 61  ;..}...memcpy(&a
43f0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4400: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2c 20  ache[hash_idx], 
4410: 70 61 74 68 69 6e 66 6f 2c 20 73 69 7a 65 6f 66  pathinfo, sizeof
4420: 28 2a 70 61 74 68 69 6e 66 6f 29 29 3b 0a 0a 09  (*pathinfo));...
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 70 61 74 68 20 3d 20 73 74  _cache_path = st
4460: 72 64 75 70 28 70 61 74 68 29 3b 0a 09 61 70 70  rdup(path);..app
4470: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4480: 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61  he[hash_idx]._ca
4490: 63 68 65 5f 75 69 64 20 20 3d 20 75 69 64 3b 0a  che_uid  = uid;.
44a0: 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20  ..pthread_ret = 
44b0: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e  pthread_mutex_un
44c0: 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68  lock(&appfs_path
44d0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65  _info_cache_mute
44e0: 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64  x);..if (pthread
44f0: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41  _ret != 0) {...A
4500: 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62  PPFS_DEBUG("Unab
4510: 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74  le to unlock pat
4520: 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74  h_info cache mut
4530: 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72  ex !");....retur
4540: 6e 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a  n;..}...return;.
4550: 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  }..static void a
4560: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
4570: 66 6f 5f 63 61 63 68 65 5f 72 6d 28 63 6f 6e 73  fo_cache_rm(cons
4580: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 75 69  t char *path, ui
4590: 64 5f 74 20 75 69 64 29 20 7b 0a 09 75 6e 73 69  d_t uid) {..unsi
45a0: 67 6e 65 64 20 69 6e 74 20 68 61 73 68 5f 69 64  gned int hash_id
45b0: 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f  x;..int pthread_
45c0: 72 65 74 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72  ret;...pthread_r
45d0: 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74  et = pthread_mut
45e0: 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70  ex_lock(&appfs_p
45f0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d  ath_info_cache_m
4600: 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72  utex);..if (pthr
4610: 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  ead_ret != 0) {.
4620: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55  ..APPFS_DEBUG("U
4630: 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61  nable to lock pa
4640: 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75  th_info cache mu
4650: 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75  tex !");....retu
4660: 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70  rn;..}...if (app
4670: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4680: 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  he != NULL) {...
4690: 68 61 73 68 5f 69 64 78 20 3d 20 28 61 70 70 66  hash_idx = (appf
46a0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65  s_get_path_inode
46b0: 28 70 61 74 68 2c 20 75 69 64 29 29 20 25 20 61  (path, uid)) % a
46c0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
46d0: 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 09 69 66  ache_size;....if
46e0: 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66   (appfs_path_inf
46f0: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78  o_cache[hash_idx
4700: 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d  ]._cache_path !=
4710: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 66 72 65 65   NULL) {....free
4720: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  (appfs_path_info
4730: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d  _cache[hash_idx]
4740: 2e 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a 0a  ._cache_path);..
4750: 09 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  ...appfs_path_in
4760: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
4770: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d  x]._cache_path =
4780: 20 4e 55 4c 4c 3b 0a 09 09 7d 0a 09 7d 0a 0a 09   NULL;...}..}...
4790: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
47a0: 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f  hread_mutex_unlo
47b0: 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69  ck(&appfs_path_i
47c0: 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29  nfo_cache_mutex)
47d0: 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72  ;..if (pthread_r
47e0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50  et != 0) {...APP
47f0: 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65  FS_DEBUG("Unable
4800: 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f   to unlock path_
4810: 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78  info cache mutex
4820: 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b   !");....return;
4830: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a  ..}...return;.}.
4840: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
4850: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
4860: 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 75 69 64  _cache_flush(uid
4870: 5f 74 20 75 69 64 2c 20 69 6e 74 20 6e 65 77 5f  _t uid, int new_
4880: 73 69 7a 65 29 20 7b 0a 09 75 6e 73 69 67 6e 65  size) {..unsigne
4890: 64 20 69 6e 74 20 69 64 78 3b 0a 09 69 6e 74 20  d int idx;..int 
48a0: 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 41  pthread_ret;...A
48b0: 50 50 46 53 5f 44 45 42 55 47 28 22 46 6c 75 73  PPFS_DEBUG("Flus
48c0: 68 69 6e 67 20 41 70 70 46 53 20 63 61 63 68 65  hing AppFS cache
48d0: 20 28 75 69 64 20 3d 20 25 6c 6c 69 2c 20 6e 65   (uid = %lli, ne
48e0: 77 5f 73 69 7a 65 20 3d 20 25 69 29 22 2c 20 28  w_size = %i)", (
48f0: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69 64 2c 20  long long) uid, 
4900: 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a 09 70 74 68  new_size);...pth
4910: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
4920: 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61  ad_mutex_lock(&a
4930: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4940: 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66  ache_mutex);..if
4950: 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d   (pthread_ret !=
4960: 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45   0) {...APPFS_DE
4970: 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c  BUG("Unable to l
4980: 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61  ock path_info ca
4990: 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a  che mutex !");..
49a0: 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69  ..return;..}...i
49b0: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
49c0: 66 6f 5f 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c  fo_cache != NULL
49d0: 29 20 7b 0a 09 09 66 6f 72 20 28 69 64 78 20 3d  ) {...for (idx =
49e0: 20 30 3b 20 69 64 78 20 3c 20 61 70 70 66 73 5f   0; idx < appfs_
49f0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
4a00: 73 69 7a 65 3b 20 69 64 78 2b 2b 29 20 7b 0a 09  size; idx++) {..
4a10: 09 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68  ..if (appfs_path
4a20: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d  _info_cache[idx]
4a30: 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20  ._cache_path != 
4a40: 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 69 66 20 28  NULL) {.....if (
4a50: 75 69 64 20 21 3d 20 28 28 75 69 64 5f 74 29 20  uid != ((uid_t) 
4a60: 2d 31 29 29 20 7b 0a 09 09 09 09 09 69 66 20 28  -1)) {......if (
4a70: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4a80: 63 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68  cache[idx]._cach
4a90: 65 5f 75 69 64 20 21 3d 20 75 69 64 29 20 7b 0a  e_uid != uid) {.
4aa0: 09 09 09 09 09 09 63 6f 6e 74 69 6e 75 65 3b 0a  ......continue;.
4ab0: 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09  .....}.....}....
4ac0: 09 09 66 72 65 65 28 61 70 70 66 73 5f 70 61 74  ..free(appfs_pat
4ad0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78  h_info_cache[idx
4ae0: 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a  ]._cache_path);.
4af0: 0a 09 09 09 09 61 70 70 66 73 5f 70 61 74 68 5f  .....appfs_path_
4b00: 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e  info_cache[idx].
4b10: 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20 4e 55  _cache_path = NU
4b20: 4c 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a  LL;....}...}..}.
4b30: 0a 09 69 66 20 28 75 69 64 20 3d 3d 20 28 28 75  ..if (uid == ((u
4b40: 69 64 5f 74 29 20 2d 31 29 29 20 7b 0a 09 09 66  id_t) -1)) {...f
4b50: 72 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69  ree(appfs_path_i
4b60: 6e 66 6f 5f 63 61 63 68 65 29 3b 0a 0a 09 09 61  nfo_cache);....a
4b70: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4b80: 61 63 68 65 20 3d 20 4e 55 4c 4c 3b 0a 0a 09 09  ache = NULL;....
4b90: 69 66 20 28 6e 65 77 5f 73 69 7a 65 20 21 3d 20  if (new_size != 
4ba0: 2d 31 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 70  -1) {....appfs_p
4bb0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73  ath_info_cache_s
4bc0: 69 7a 65 20 3d 20 6e 65 77 5f 73 69 7a 65 3b 0a  ize = new_size;.
4bd0: 09 09 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64  ..}..}...pthread
4be0: 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d  _ret = pthread_m
4bf0: 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70  utex_unlock(&app
4c00: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4c10: 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28  he_mutex);..if (
4c20: 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30  pthread_ret != 0
4c30: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
4c40: 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c  G("Unable to unl
4c50: 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61  ock path_info ca
4c60: 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a  che mutex !");..
4c70: 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72  ..return;..}...r
4c80: 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20 47 65 74  eturn;.}../* Get
4c90: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f   information abo
4ca0: 75 74 20 61 20 70 61 74 68 2c 20 61 6e 64 20 6f  ut a path, and o
4cb0: 70 74 69 6f 6e 61 6c 6c 79 20 6c 69 73 74 20 63  ptionally list c
4cc0: 68 69 6c 64 72 65 6e 20 2a 2f 0a 73 74 61 74 69  hildren */.stati
4cd0: 63 20 69 6e 74 20 61 70 70 66 73 5f 67 65 74 5f  c int appfs_get_
4ce0: 70 61 74 68 5f 69 6e 66 6f 28 63 6f 6e 73 74 20  path_info(const 
4cf0: 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75  char *path, stru
4d00: 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66  ct appfs_pathinf
4d10: 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09  o *pathinfo) {..
4d20: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
4d30: 72 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 61 74  rp;..Tcl_Obj *at
4d40: 74 72 73 5f 64 69 63 74 2c 20 2a 61 74 74 72 5f  trs_dict, *attr_
4d50: 76 61 6c 75 65 3b 0a 09 63 6f 6e 73 74 20 63 68  value;..const ch
4d60: 61 72 20 2a 61 74 74 72 5f 76 61 6c 75 65 5f 73  ar *attr_value_s
4d70: 74 72 2c 20 2a 61 74 74 72 5f 76 61 6c 75 65 5f  tr, *attr_value_
4d80: 73 74 72 5f 69 3b 0a 09 54 63 6c 5f 57 69 64 65  str_i;..Tcl_Wide
4d90: 49 6e 74 20 61 74 74 72 5f 76 61 6c 75 65 5f 77  Int attr_value_w
4da0: 69 64 65 3b 0a 09 69 6e 74 20 61 74 74 72 5f 76  ide;..int attr_v
4db0: 61 6c 75 65 5f 69 6e 74 3b 0a 09 73 74 61 74 69  alue_int;..stati
4dc0: 63 20 5f 5f 74 68 72 65 61 64 20 54 63 6c 5f 4f  c __thread Tcl_O
4dd0: 62 6a 20 2a 61 74 74 72 5f 6b 65 79 5f 74 79 70  bj *attr_key_typ
4de0: 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f  e = NULL, *attr_
4df0: 6b 65 79 5f 70 65 72 6d 73 20 3d 20 4e 55 4c 4c  key_perms = NULL
4e00: 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65  , *attr_key_size
4e10: 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b   = NULL, *attr_k
4e20: 65 79 5f 74 69 6d 65 20 3d 20 4e 55 4c 4c 2c 20  ey_time = NULL, 
4e30: 2a 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65  *attr_key_source
4e40: 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b   = NULL, *attr_k
4e50: 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20  ey_childcount = 
4e60: 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f  NULL, *attr_key_
4e70: 70 61 63 6b 61 67 65 64 20 3d 20 4e 55 4c 4c 3b  packaged = NULL;
4e80: 0a 09 69 6e 74 20 63 61 63 68 65 5f 72 65 74 3b  ..int cache_ret;
4e90: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 09  ..int tcl_ret;..
4ea0: 69 6e 74 20 72 65 74 76 61 6c 3b 0a 09 75 69 64  int retval;..uid
4eb0: 5f 74 20 66 73 75 69 64 3b 0a 0a 09 72 65 74 76  _t fsuid;...retv
4ec0: 61 6c 20 3d 20 30 3b 0a 0a 09 66 73 75 69 64 20  al = 0;...fsuid 
4ed0: 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  = appfs_get_fsui
4ee0: 64 28 29 3b 0a 0a 09 63 61 63 68 65 5f 72 65 74  d();...cache_ret
4ef0: 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74   = appfs_get_pat
4f00: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74  h_info_cache_get
4f10: 28 70 61 74 68 2c 20 66 73 75 69 64 2c 20 70 61  (path, fsuid, pa
4f20: 74 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 63 61  thinfo);..if (ca
4f30: 63 68 65 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a  che_ret == 0) {.
4f40: 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2d 3e  ..if (pathinfo->
4f50: 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50 41  type == APPFS_PA
4f60: 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f  THTYPE_DOES_NOT_
4f70: 45 58 49 53 54 29 20 7b 0a 09 09 09 41 50 50 46  EXIST) {....APPF
4f80: 53 5f 44 45 42 55 47 28 22 52 65 74 75 72 6e 69  S_DEBUG("Returni
4f90: 6e 67 20 66 72 6f 6d 20 63 61 63 68 65 3a 20 64  ng from cache: d
4fa0: 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20 5c 22  oes not exist \"
4fb0: 25 73 5c 22 22 2c 20 70 61 74 68 29 3b 0a 0a 09  %s\"", path);...
4fc0: 09 09 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54  ..return(-ENOENT
4fd0: 29 3b 0a 09 09 7d 0a 0a 09 09 69 66 20 28 70 61  );...}....if (pa
4fe0: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d 20  thinfo->type == 
4ff0: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49  APPFS_PATHTYPE_I
5000: 4e 56 41 4c 49 44 29 20 7b 0a 09 09 09 41 50 50  NVALID) {....APP
5010: 46 53 5f 44 45 42 55 47 28 22 52 65 74 75 72 6e  FS_DEBUG("Return
5020: 69 6e 67 20 66 72 6f 6d 20 63 61 63 68 65 3a 20  ing from cache: 
5030: 69 6e 76 61 6c 69 64 20 6f 62 6a 65 63 74 20 5c  invalid object \
5040: 22 25 73 5c 22 22 2c 20 70 61 74 68 29 3b 0a 0a  "%s\"", path);..
5050: 09 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
5060: 0a 09 09 7d 0a 0a 09 09 72 65 74 75 72 6e 28 30  ...}....return(0
5070: 29 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72 70 20 3d  );..}...interp =
5080: 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70   appfs_TclInterp
5090: 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  ();..if (interp 
50a0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50  == NULL) {...APP
50b0: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
50c0: 20 55 6e 61 62 6c 65 20 74 6f 20 67 65 74 20 61   Unable to get a
50d0: 6e 20 69 6e 74 65 72 70 72 65 74 65 72 22 29 3b  n interpreter");
50e0: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  ....return(-EIO)
50f0: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
5100: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65  l_libtcl(Tcl_Pre
5110: 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a  serve(interp);).
5120: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66  ..tcl_ret = appf
5130: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  s_Tcl_Eval(inter
5140: 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  p, 2, "::appfs::
5150: 67 65 74 61 74 74 72 22 2c 20 70 61 74 68 29 3b  getattr", path);
5160: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
5170: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
5180: 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66  FS_DEBUG("::appf
5190: 73 3a 3a 67 65 74 61 74 74 72 28 25 73 29 20 66  s::getattr(%s) f
51a0: 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a  ailed.", path);.
51b0: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
51c0: 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45  tcl(....APPFS_DE
51d0: 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69  BUG("Tcl Error i
51e0: 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53  s: %s", Tcl_GetS
51f0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
5200: 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 70 61 74  rp));...)....pat
5210: 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50  hinfo->type = AP
5220: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 4f 45  PFS_PATHTYPE_DOE
5230: 53 5f 4e 4f 54 5f 45 58 49 53 54 3b 0a 0a 09 09  S_NOT_EXIST;....
5240: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
5250: 6e 66 6f 5f 63 61 63 68 65 5f 61 64 64 28 70 61  nfo_cache_add(pa
5260: 74 68 2c 20 66 73 75 69 64 2c 20 70 61 74 68 69  th, fsuid, pathi
5270: 6e 66 6f 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63  nfo);....appfs_c
5280: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
5290: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
52a0: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 4e 4f 45  ....return(-ENOE
52b0: 4e 54 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 74  NT);..}...if (at
52c0: 74 72 5f 6b 65 79 5f 74 79 70 65 20 3d 3d 20 4e  tr_key_type == N
52d0: 55 4c 4c 29 20 7b 0a 09 09 61 70 70 66 73 5f 63  ULL) {...appfs_c
52e0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 61  all_libtcl(....a
52f0: 74 74 72 5f 6b 65 79 5f 74 79 70 65 20 20 20 20  ttr_key_type    
5300: 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69     = Tcl_NewStri
5310: 6e 67 4f 62 6a 28 22 74 79 70 65 22 2c 20 2d 31  ngObj("type", -1
5320: 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 70  );....attr_key_p
5330: 65 72 6d 73 20 20 20 20 20 20 3d 20 54 63 6c 5f  erms      = Tcl_
5340: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 70 65  NewStringObj("pe
5350: 72 6d 73 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74  rms", -1);....at
5360: 74 72 5f 6b 65 79 5f 73 69 7a 65 20 20 20 20 20  tr_key_size     
5370: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e    = Tcl_NewStrin
5380: 67 4f 62 6a 28 22 73 69 7a 65 22 2c 20 2d 31 29  gObj("size", -1)
5390: 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 74 69  ;....attr_key_ti
53a0: 6d 65 20 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e  me       = Tcl_N
53b0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 74 69 6d  ewStringObj("tim
53c0: 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72  e", -1);....attr
53d0: 5f 6b 65 79 5f 73 6f 75 72 63 65 20 20 20 20 20  _key_source     
53e0: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
53f0: 62 6a 28 22 73 6f 75 72 63 65 22 2c 20 2d 31 29  bj("source", -1)
5400: 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 63 68  ;....attr_key_ch
5410: 69 6c 64 63 6f 75 6e 74 20 3d 20 54 63 6c 5f 4e  ildcount = Tcl_N
5420: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 63 68 69  ewStringObj("chi
5430: 6c 64 63 6f 75 6e 74 22 2c 20 2d 31 29 3b 0a 09  ldcount", -1);..
5440: 09 09 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61  ..attr_key_packa
5450: 67 65 64 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53  ged   = Tcl_NewS
5460: 74 72 69 6e 67 4f 62 6a 28 22 70 61 63 6b 61 67  tringObj("packag
5470: 65 64 22 2c 20 2d 31 29 3b 0a 0a 09 09 09 54 63  ed", -1);.....Tc
5480: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61  l_IncrRefCount(a
5490: 74 74 72 5f 6b 65 79 5f 74 79 70 65 29 3b 0a 09  ttr_key_type);..
54a0: 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75  ..Tcl_IncrRefCou
54b0: 6e 74 28 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d  nt(attr_key_perm
54c0: 73 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52  s);....Tcl_IncrR
54d0: 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79  efCount(attr_key
54e0: 5f 73 69 7a 65 29 3b 0a 09 09 09 54 63 6c 5f 49  _size);....Tcl_I
54f0: 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72  ncrRefCount(attr
5500: 5f 6b 65 79 5f 74 69 6d 65 29 3b 0a 09 09 09 54  _key_time);....T
5510: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
5520: 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65 29  attr_key_source)
5530: 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66  ;....Tcl_IncrRef
5540: 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 63  Count(attr_key_c
5550: 68 69 6c 64 63 6f 75 6e 74 29 3b 0a 09 09 09 54  hildcount);....T
5560: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
5570: 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65  attr_key_package
5580: 64 29 3b 0a 09 09 29 0a 09 7d 0a 0a 09 61 70 70  d);...)..}...app
5590: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
55a0: 09 09 61 74 74 72 73 5f 64 69 63 74 20 3d 20 54  ..attrs_dict = T
55b0: 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_GetObjResult(
55c0: 69 6e 74 65 72 70 29 3b 0a 09 09 74 63 6c 5f 72  interp);...tcl_r
55d0: 65 74 20 3d 20 54 63 6c 5f 44 69 63 74 4f 62 6a  et = Tcl_DictObj
55e0: 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72  Get(interp, attr
55f0: 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79  s_dict, attr_key
5600: 5f 74 79 70 65 2c 20 26 61 74 74 72 5f 76 61 6c  _type, &attr_val
5610: 75 65 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c  ue);..)..if (tcl
5620: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  _ret != TCL_OK) 
5630: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
5640: 22 5b 64 69 63 74 20 67 65 74 20 5c 22 74 79 70  "[dict get \"typ
5650: 65 5c 22 5d 20 66 61 69 6c 65 64 22 29 3b 0a 09  e\"] failed");..
5660: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
5670: 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42  cl(....APPFS_DEB
5680: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
5690: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
56a0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
56b0: 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66  p));...)....appf
56c0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
56d0: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
56e0: 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45  );)....return(-E
56f0: 49 4f 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 74  IO);..}...if (at
5700: 74 72 5f 76 61 6c 75 65 20 3d 3d 20 4e 55 4c 4c  tr_value == NULL
5710: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
5720: 47 28 22 65 72 72 6f 72 3a 20 55 6e 61 62 6c 65  G("error: Unable
5730: 20 74 6f 20 67 65 74 20 74 79 70 65 20 66 6f 72   to get type for
5740: 20 5c 22 25 73 5c 22 20 66 72 6f 6d 20 54 63 6c   \"%s\" from Tcl
5750: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 09 61 70 70  ", path);....app
5760: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
5770: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
5780: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d  p);)....return(-
5790: 45 49 4f 29 3b 0a 09 7d 0a 0a 09 70 61 74 68 69  EIO);..}...pathi
57a0: 6e 66 6f 2d 3e 70 61 63 6b 61 67 65 64 20 3d 20  nfo->packaged = 
57b0: 30 3b 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  0;...appfs_call_
57c0: 6c 69 62 74 63 6c 28 0a 09 09 61 74 74 72 5f 76  libtcl(...attr_v
57d0: 61 6c 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f 47  alue_str = Tcl_G
57e0: 65 74 53 74 72 69 6e 67 28 61 74 74 72 5f 76 61  etString(attr_va
57f0: 6c 75 65 29 3b 0a 0a 09 09 73 77 69 74 63 68 20  lue);....switch 
5800: 28 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5b  (attr_value_str[
5810: 30 5d 29 20 7b 0a 09 09 09 63 61 73 65 20 27 64  0]) {....case 'd
5820: 27 3a 20 2f 2a 20 64 69 72 65 63 74 6f 72 79 20  ': /* directory 
5830: 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  */.....pathinfo-
5840: 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41  >type = APPFS_PA
5850: 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59  THTYPE_DIRECTORY
5860: 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  ;.....pathinfo->
5870: 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69  typeinfo.dir.chi
5880: 6c 64 63 6f 75 6e 74 20 3d 20 30 3b 0a 0a 09 09  ldcount = 0;....
5890: 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74  ..Tcl_DictObjGet
58a0: 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64  (interp, attrs_d
58b0: 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 63 68  ict, attr_key_ch
58c0: 69 6c 64 63 6f 75 6e 74 2c 20 26 61 74 74 72 5f  ildcount, &attr_
58d0: 76 61 6c 75 65 29 3b 0a 09 09 09 09 69 66 20 28  value);.....if (
58e0: 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55  attr_value != NU
58f0: 4c 4c 29 20 7b 0a 09 09 09 09 09 74 63 6c 5f 72  LL) {......tcl_r
5900: 65 74 20 3d 20 54 63 6c 5f 47 65 74 57 69 64 65  et = Tcl_GetWide
5910: 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c  IntFromObj(NULL,
5920: 20 61 74 74 72 5f 76 61 6c 75 65 2c 20 26 61 74   attr_value, &at
5930: 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 29 3b 0a  tr_value_wide);.
5940: 09 09 09 09 09 69 66 20 28 74 63 6c 5f 72 65 74  .....if (tcl_ret
5950: 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   == TCL_OK) {...
5960: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
5970: 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64  peinfo.dir.child
5980: 63 6f 75 6e 74 20 3d 20 61 74 74 72 5f 76 61 6c  count = attr_val
5990: 75 65 5f 77 69 64 65 3b 0a 09 09 09 09 09 7d 0a  ue_wide;......}.
59a0: 09 09 09 09 7d 0a 0a 09 09 09 09 62 72 65 61 6b  ....}......break
59b0: 3b 0a 09 09 09 63 61 73 65 20 27 66 27 3a 20 2f  ;....case 'f': /
59c0: 2a 20 66 69 6c 65 20 2a 2f 0a 09 09 09 09 70 61  * file */.....pa
59d0: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41  thinfo->type = A
59e0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49  PPFS_PATHTYPE_FI
59f0: 4c 45 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f  LE;.....pathinfo
5a00: 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e  ->typeinfo.file.
5a10: 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 09 70 61  size = 0;.....pa
5a20: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
5a30: 2e 66 69 6c 65 2e 65 78 65 63 75 74 61 62 6c 65  .file.executable
5a40: 20 3d 20 30 3b 0a 09 09 09 09 70 61 74 68 69 6e   = 0;.....pathin
5a50: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  fo->typeinfo.fil
5a60: 65 2e 73 75 69 64 52 6f 6f 74 20 3d 20 30 3b 0a  e.suidRoot = 0;.
5a70: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
5a80: 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 77 6f 72 6c  peinfo.file.worl
5a90: 64 61 63 63 65 73 73 69 62 6c 65 20 3d 20 30 3b  daccessible = 0;
5aa0: 0a 0a 09 09 09 09 54 63 6c 5f 44 69 63 74 4f 62  ......Tcl_DictOb
5ab0: 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74  jGet(interp, att
5ac0: 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65  rs_dict, attr_ke
5ad0: 79 5f 73 69 7a 65 2c 20 26 61 74 74 72 5f 76 61  y_size, &attr_va
5ae0: 6c 75 65 29 3b 0a 09 09 09 09 69 66 20 28 61 74  lue);.....if (at
5af0: 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c  tr_value != NULL
5b00: 29 20 7b 0a 09 09 09 09 09 74 63 6c 5f 72 65 74  ) {......tcl_ret
5b10: 20 3d 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e   = Tcl_GetWideIn
5b20: 74 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61  tFromObj(NULL, a
5b30: 74 74 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72  ttr_value, &attr
5b40: 5f 76 61 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09  _value_wide);...
5b50: 09 09 09 69 66 20 28 74 63 6c 5f 72 65 74 20 3d  ...if (tcl_ret =
5b60: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09  = TCL_OK) {.....
5b70: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
5b80: 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 3d  info.file.size =
5b90: 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65   attr_value_wide
5ba0: 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a  ;......}.....}..
5bb0: 09 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47  ....Tcl_DictObjG
5bc0: 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73  et(interp, attrs
5bd0: 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f  _dict, attr_key_
5be0: 70 65 72 6d 73 2c 20 26 61 74 74 72 5f 76 61 6c  perms, &attr_val
5bf0: 75 65 29 3b 0a 09 09 09 09 69 66 20 28 61 74 74  ue);.....if (att
5c00: 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29  r_value != NULL)
5c10: 20 7b 0a 09 09 09 09 09 61 74 74 72 5f 76 61 6c   {......attr_val
5c20: 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f 47 65 74  ue_str = Tcl_Get
5c30: 53 74 72 69 6e 67 28 61 74 74 72 5f 76 61 6c 75  String(attr_valu
5c40: 65 29 3b 0a 09 09 09 09 09 66 6f 72 20 28 61 74  e);......for (at
5c50: 74 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 20 3d  tr_value_str_i =
5c60: 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72   &attr_value_str
5c70: 5b 30 5d 3b 20 2a 61 74 74 72 5f 76 61 6c 75 65  [0]; *attr_value
5c80: 5f 73 74 72 5f 69 20 21 3d 20 27 5c 30 27 3b 20  _str_i != '\0'; 
5c90: 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69  attr_value_str_i
5ca0: 2b 2b 29 20 7b 0a 09 09 09 09 09 09 73 77 69 74  ++) {.......swit
5cb0: 63 68 20 28 2a 61 74 74 72 5f 76 61 6c 75 65 5f  ch (*attr_value_
5cc0: 73 74 72 5f 69 29 20 7b 0a 09 09 09 09 09 09 09  str_i) {........
5cd0: 63 61 73 65 20 27 78 27 3a 0a 09 09 09 09 09 09  case 'x':.......
5ce0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
5cf0: 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74  info.file.execut
5d00: 61 62 6c 65 20 3d 20 31 3b 0a 0a 09 09 09 09 09  able = 1;.......
5d10: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 09 09  ...break;.......
5d20: 09 63 61 73 65 20 27 55 27 3a 0a 09 09 09 09 09  .case 'U':......
5d30: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
5d40: 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 75 69 64 52  einfo.file.suidR
5d50: 6f 6f 74 20 3d 20 31 3b 0a 0a 09 09 09 09 09 09  oot = 1;........
5d60: 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 09 09 09  ..break;........
5d70: 63 61 73 65 20 27 2d 27 3a 0a 09 09 09 09 09 09  case '-':.......
5d80: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
5d90: 69 6e 66 6f 2e 66 69 6c 65 2e 77 6f 72 6c 64 61  info.file.worlda
5da0: 63 63 65 73 73 69 62 6c 65 20 3d 20 31 3b 0a 0a  ccessible = 1;..
5db0: 09 09 09 09 09 09 09 09 62 72 65 61 6b 3b 0a 09  ........break;..
5dc0: 09 09 09 09 09 7d 0a 09 09 09 09 09 7d 0a 09 09  .....}......}...
5dd0: 09 09 7d 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09  ..}.....break;..
5de0: 09 09 63 61 73 65 20 27 73 27 3a 20 2f 2a 20 73  ..case 's': /* s
5df0: 79 6d 6c 69 6e 6b 20 2a 2f 0a 09 09 09 09 70 61  ymlink */.....pa
5e00: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41  thinfo->type = A
5e10: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59  PPFS_PATHTYPE_SY
5e20: 4d 4c 49 4e 4b 3b 0a 09 09 09 09 70 61 74 68 69  MLINK;.....pathi
5e30: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79  nfo->typeinfo.sy
5e40: 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20 30 3b 0a  mlink.size = 0;.
5e50: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
5e60: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
5e70: 6f 75 72 63 65 5b 30 5d 20 3d 20 27 5c 30 27 3b  ource[0] = '\0';
5e80: 0a 0a 09 09 09 09 54 63 6c 5f 44 69 63 74 4f 62  ......Tcl_DictOb
5e90: 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74  jGet(interp, att
5ea0: 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65  rs_dict, attr_ke
5eb0: 79 5f 73 6f 75 72 63 65 2c 20 26 61 74 74 72 5f  y_source, &attr_
5ec0: 76 61 6c 75 65 29 3b 0a 09 09 09 09 69 66 20 28  value);.....if (
5ed0: 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55  attr_value != NU
5ee0: 4c 4c 29 20 7b 0a 09 09 09 09 09 61 74 74 72 5f  LL) {......attr_
5ef0: 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f  value_str = Tcl_
5f00: 47 65 74 53 74 72 69 6e 67 46 72 6f 6d 4f 62 6a  GetStringFromObj
5f10: 28 61 74 74 72 5f 76 61 6c 75 65 2c 20 26 61 74  (attr_value, &at
5f20: 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 20 0a  tr_value_int); .
5f30: 0a 09 09 09 09 09 69 66 20 28 28 61 74 74 72 5f  ......if ((attr_
5f40: 76 61 6c 75 65 5f 69 6e 74 20 2b 20 31 29 20 3c  value_int + 1) <
5f50: 3d 20 73 69 7a 65 6f 66 28 70 61 74 68 69 6e 66  = sizeof(pathinf
5f60: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c  o->typeinfo.syml
5f70: 69 6e 6b 2e 73 6f 75 72 63 65 29 29 20 7b 0a 09  ink.source)) {..
5f80: 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
5f90: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e  ypeinfo.symlink.
5fa0: 73 69 7a 65 20 3d 20 61 74 74 72 5f 76 61 6c 75  size = attr_valu
5fb0: 65 5f 69 6e 74 3b 0a 09 09 09 09 09 09 70 61 74  e_int;.......pat
5fc0: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
5fd0: 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b 61  symlink.source[a
5fe0: 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 5d 20 3d  ttr_value_int] =
5ff0: 20 27 5c 30 27 3b 0a 0a 09 09 09 09 09 09 6d 65   '\0';........me
6000: 6d 63 70 79 28 70 61 74 68 69 6e 66 6f 2d 3e 74  mcpy(pathinfo->t
6010: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e  ypeinfo.symlink.
6020: 73 6f 75 72 63 65 2c 20 61 74 74 72 5f 76 61 6c  source, attr_val
6030: 75 65 5f 73 74 72 2c 20 61 74 74 72 5f 76 61 6c  ue_str, attr_val
6040: 75 65 5f 69 6e 74 29 3b 0a 09 09 09 09 09 7d 0a  ue_int);......}.
6050: 09 09 09 09 7d 0a 09 09 09 09 62 72 65 61 6b 3b  ....}.....break;
6060: 0a 09 09 09 63 61 73 65 20 27 46 27 3a 20 2f 2a  ....case 'F': /*
6070: 20 70 69 70 65 2f 66 69 66 6f 20 2a 2f 0a 09 09   pipe/fifo */...
6080: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
6090: 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50   = APPFS_PATHTYP
60a0: 45 5f 46 49 46 4f 3b 0a 09 09 09 09 62 72 65 61  E_FIFO;.....brea
60b0: 6b 3b 0a 09 09 09 63 61 73 65 20 27 53 27 3a 20  k;....case 'S': 
60c0: 2f 2a 20 55 4e 49 58 20 64 6f 6d 61 69 6e 20 73  /* UNIX domain s
60d0: 6f 63 6b 65 74 20 2a 2f 0a 09 09 09 09 70 61 74  ocket */.....pat
60e0: 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50  hinfo->type = AP
60f0: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 4f 43  PFS_PATHTYPE_SOC
6100: 4b 45 54 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a  KET;.....break;.
6110: 09 09 09 64 65 66 61 75 6c 74 3a 0a 09 09 09 09  ...default:.....
6120: 72 65 74 76 61 6c 20 3d 20 2d 45 49 4f 3b 0a 09  retval = -EIO;..
6130: 09 7d 0a 0a 09 09 54 63 6c 5f 44 69 63 74 4f 62  .}....Tcl_DictOb
6140: 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74  jGet(interp, att
6150: 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65  rs_dict, attr_ke
6160: 79 5f 70 61 63 6b 61 67 65 64 2c 20 26 61 74 74  y_packaged, &att
6170: 72 5f 76 61 6c 75 65 29 3b 0a 09 09 69 66 20 28  r_value);...if (
6180: 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55  attr_value != NU
6190: 4c 4c 29 20 7b 0a 09 09 09 70 61 74 68 69 6e 66  LL) {....pathinf
61a0: 6f 2d 3e 70 61 63 6b 61 67 65 64 20 3d 20 31 3b  o->packaged = 1;
61b0: 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44 69 63 74  ...}....Tcl_Dict
61c0: 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61  ObjGet(interp, a
61d0: 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f  ttrs_dict, attr_
61e0: 6b 65 79 5f 74 69 6d 65 2c 20 26 61 74 74 72 5f  key_time, &attr_
61f0: 76 61 6c 75 65 29 3b 0a 09 09 69 66 20 28 61 74  value);...if (at
6200: 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c  tr_value != NULL
6210: 29 20 7b 0a 09 09 09 74 63 6c 5f 72 65 74 20 3d  ) {....tcl_ret =
6220: 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46   Tcl_GetWideIntF
6230: 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74  romObj(NULL, att
6240: 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76  r_value, &attr_v
6250: 61 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 69  alue_wide);....i
6260: 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43  f (tcl_ret == TC
6270: 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 70 61 74 68  L_OK) {.....path
6280: 69 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20 61 74 74  info->time = att
6290: 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09  r_value_wide;...
62a0: 09 7d 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09  .}...} else {...
62b0: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 69 6d 65 20  .pathinfo->time 
62c0: 3d 20 61 70 70 66 73 5f 62 6f 6f 74 74 69 6d 65  = appfs_boottime
62d0: 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 52 65 6c  ;...}....Tcl_Rel
62e0: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 09 29  ease(interp);..)
62f0: 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2d  ...if (pathinfo-
6300: 3e 70 61 63 6b 61 67 65 64 29 20 7b 0a 09 09 70  >packaged) {...p
6310: 61 74 68 69 6e 66 6f 2d 3e 69 6e 6f 64 65 20 3d  athinfo->inode =
6320: 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f   appfs_get_path_
6330: 69 6e 6f 64 65 28 70 61 74 68 2c 20 2d 31 29 3b  inode(path, -1);
6340: 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 70 61 74  ..} else {...pat
6350: 68 69 6e 66 6f 2d 3e 69 6e 6f 64 65 20 3d 20 61  hinfo->inode = a
6360: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
6370: 6f 64 65 28 70 61 74 68 2c 20 66 73 75 69 64 29  ode(path, fsuid)
6380: 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65 74 76 61  ;..}...if (retva
6390: 6c 20 3d 3d 20 30 29 20 7b 0a 09 09 61 70 70 66  l == 0) {...appf
63a0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
63b0: 63 61 63 68 65 5f 61 64 64 28 70 61 74 68 2c 20  cache_add(path, 
63c0: 66 73 75 69 64 2c 20 70 61 74 68 69 6e 66 6f 29  fsuid, pathinfo)
63d0: 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 41 50  ;..} else {...AP
63e0: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
63f0: 3a 20 49 6e 76 61 6c 69 64 20 74 79 70 65 20 66  : Invalid type f
6400: 6f 72 20 5c 22 25 73 5c 22 20 66 72 6f 6d 20 54  or \"%s\" from T
6410: 63 6c 22 2c 20 70 61 74 68 29 3b 0a 09 7d 0a 0a  cl", path);..}..
6420: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
6430: 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61 72 20  .}..static char 
6440: 2a 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74  *appfs_prepare_t
6450: 6f 5f 63 72 65 61 74 65 28 63 6f 6e 73 74 20 63  o_create(const c
6460: 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54 63  har *path) {..Tc
6470: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
6480: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72  ;..const char *r
6490: 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74  eal_path;..int t
64a0: 63 6c 5f 72 65 74 3b 0a 0a 09 61 70 70 66 73 5f  cl_ret;...appfs_
64b0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
64c0: 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73 5f  che_flush(appfs_
64d0: 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31 29  get_fsuid(), -1)
64e0: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  ;...interp = app
64f0: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a  fs_TclInterp();.
6500: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
6510: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
6520: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  NULL);..}...appf
6530: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
6540: 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72  l_Preserve(inter
6550: 70 29 3b 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c  p);)...appfs_cal
6560: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f  l_libtcl(...tcl_
6570: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
6580: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20  Eval(interp, 2, 
6590: 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65 70 61 72  "::appfs::prepar
65a0: 65 5f 74 6f 5f 63 72 65 61 74 65 22 2c 20 70 61  e_to_create", pa
65b0: 74 68 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c  th);..)..if (tcl
65c0: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  _ret != TCL_OK) 
65d0: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
65e0: 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65 70 61 72  "::appfs::prepar
65f0: 65 5f 74 6f 5f 63 72 65 61 74 65 28 25 73 29 20  e_to_create(%s) 
6600: 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b  failed.", path);
6610: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
6620: 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44  btcl(....APPFS_D
6630: 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20  EBUG("Tcl Error 
6640: 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74  is: %s", Tcl_Get
6650: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
6660: 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70  erp));...)....ap
6670: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
6680: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
6690: 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28  rp);)....return(
66a0: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  NULL);..}...appf
66b0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
66c0: 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c  .real_path = Tcl
66d0: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
66e0: 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61  (interp);..)...a
66f0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
6700: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
6710: 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72 65 61  erp);)...if (rea
6720: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
6730: 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  {...return(NULL)
6740: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 73 74  ;..}...return(st
6750: 72 64 75 70 28 72 65 61 6c 5f 70 61 74 68 29 29  rdup(real_path))
6760: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61 72  ;.}..static char
6770: 20 2a 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61 74   *appfs_localpat
6780: 68 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  h(const char *pa
6790: 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  th) {..Tcl_Inter
67a0: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73  p *interp;..cons
67b0: 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74  t char *real_pat
67c0: 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b  h;..int tcl_ret;
67d0: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66  ...interp = appf
67e0: 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09  s_TclInterp();..
67f0: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
6800: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e  LL) {...return(N
6810: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  ULL);..}...appfs
6820: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
6830: 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70  _Preserve(interp
6840: 29 3b 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  );)...appfs_call
6850: 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72  _libtcl(...tcl_r
6860: 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45  et = appfs_Tcl_E
6870: 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22  val(interp, 2, "
6880: 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63 61 6c 70 61  ::appfs::localpa
6890: 74 68 22 2c 20 70 61 74 68 29 3b 0a 09 29 0a 09  th", path);..)..
68a0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
68b0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
68c0: 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a  _DEBUG("::appfs:
68d0: 3a 6c 6f 63 61 6c 70 61 74 68 28 25 73 29 20 66  :localpath(%s) f
68e0: 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a  ailed.", path);.
68f0: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
6900: 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45  tcl(....APPFS_DE
6910: 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69  BUG("Tcl Error i
6920: 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53  s: %s", Tcl_GetS
6930: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
6940: 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 72 65 74  rp));...)....ret
6950: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
6960: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
6970: 6c 28 0a 09 09 72 65 61 6c 5f 70 61 74 68 20 3d  l(...real_path =
6980: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
6990: 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 29  sult(interp);..)
69a0: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
69b0: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
69c0: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 69 66 20  (interp);)...if 
69d0: 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55  (real_path == NU
69e0: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e  LL) {...return(N
69f0: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  ULL);..}...retur
6a00: 6e 28 73 74 72 64 75 70 28 72 65 61 6c 5f 70 61  n(strdup(real_pa
6a10: 74 68 29 29 3b 0a 7d 0a 0a 23 69 66 20 28 64 65  th));.}..#if (de
6a20: 66 69 6e 65 64 28 44 45 42 55 47 29 20 26 26 20  fined(DEBUG) && 
6a30: 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58  defined(APPFS_EX
6a40: 49 54 5f 50 41 54 48 29 29 20 7c 7c 20 64 65 66  IT_PATH)) || def
6a50: 69 6e 65 64 28 41 50 50 46 53 5f 45 58 49 54 5f  ined(APPFS_EXIT_
6a60: 50 41 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f  PATH_ENABLE_MAJO
6a70: 52 5f 53 45 43 55 52 49 54 59 5f 48 4f 4c 45 29  R_SECURITY_HOLE)
6a80: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
6a90: 66 73 5f 65 78 69 74 28 76 6f 69 64 29 20 7b 0a  fs_exit(void) {.
6aa0: 09 69 6e 74 20 67 6c 6f 62 61 6c 5f 69 6e 74 65  .int global_inte
6ab0: 72 70 5f 72 65 73 65 74 5f 6b 65 79 3b 0a 0a 09  rp_reset_key;...
6ac0: 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65  global_interp_re
6ad0: 73 65 74 5f 6b 65 79 20 3d 20 5f 5f 73 79 6e 63  set_key = __sync
6ae0: 5f 66 65 74 63 68 5f 61 6e 64 5f 61 64 64 28 26  _fetch_and_add(&
6af0: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
6b00: 2c 20 30 29 3b 0a 09 5f 5f 73 79 6e 63 5f 66 65  , 0);..__sync_fe
6b10: 74 63 68 5f 61 6e 64 5f 73 75 62 28 26 69 6e 74  tch_and_sub(&int
6b20: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 67  erp_reset_key, g
6b30: 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73  lobal_interp_res
6b40: 65 74 5f 6b 65 79 29 3b 0a 0a 09 77 68 69 6c 65  et_key);...while
6b50: 20 28 5f 5f 73 79 6e 63 5f 73 75 62 5f 61 6e 64   (__sync_sub_and
6b60: 5f 66 65 74 63 68 28 26 69 6e 74 65 72 70 5f 72  _fetch(&interp_r
6b70: 65 73 65 74 5f 6b 65 79 2c 20 31 29 20 3e 3d 20  eset_key, 1) >= 
6b80: 30 29 20 7b 0a 09 09 2f 2a 20 42 75 73 79 20 4c  0) {.../* Busy L
6b90: 6f 6f 70 20 2a 2f 0a 09 7d 0a 0a 09 67 6c 6f 62  oop */..}...glob
6ba0: 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  al_interp_reset_
6bb0: 6b 65 79 20 3d 20 5f 5f 73 79 6e 63 5f 66 65 74  key = __sync_fet
6bc0: 63 68 5f 61 6e 64 5f 61 64 64 28 26 69 6e 74 65  ch_and_add(&inte
6bd0: 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 30 29  rp_reset_key, 0)
6be0: 3b 0a 09 69 66 20 28 67 6c 6f 62 61 6c 5f 69 6e  ;..if (global_in
6bf0: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 21  terp_reset_key !
6c00: 3d 20 2d 31 29 20 7b 0a 09 09 41 50 50 46 53 5f  = -1) {...APPFS_
6c10: 44 45 42 55 47 28 22 45 72 72 6f 72 20 73 65 6e  DEBUG("Error sen
6c20: 64 69 6e 67 20 6b 69 6c 6c 20 73 69 67 6e 61 6c  ding kill signal
6c30: 20 74 6f 20 61 6c 6c 20 74 68 72 65 61 64 73 2c   to all threads,
6c40: 20 61 62 6f 72 74 69 6e 67 20 61 6e 79 77 61 79   aborting anyway
6c50: 2e 22 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  .");..}...appfs_
6c60: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
6c70: 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c 20 2d 31  che_flush(-1, -1
6c80: 29 3b 0a 0a 09 66 75 73 65 5f 65 78 69 74 28 66  );...fuse_exit(f
6c90: 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65 78 74 28  use_get_context(
6ca0: 29 2d 3e 66 75 73 65 29 3b 0a 0a 09 72 65 74 75  )->fuse);...retu
6cb0: 72 6e 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 73 74  rn;.}.#endif..st
6cc0: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
6cd0: 75 73 65 5f 72 65 61 64 6c 69 6e 6b 28 63 6f 6e  use_readlink(con
6ce0: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 63  st char *path, c
6cf0: 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74  har *buf, size_t
6d00: 20 73 69 7a 65 29 20 7b 0a 09 73 74 72 75 63 74   size) {..struct
6d10: 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20   appfs_pathinfo 
6d20: 70 61 74 68 69 6e 66 6f 3b 0a 09 69 6e 74 20 72  pathinfo;..int r
6d30: 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 41 50 50  etval = 0;...APP
6d40: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
6d50: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
6d60: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 70 61 74 68  ", path);...path
6d70: 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41 50 50 46  info.type = APPF
6d80: 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c  S_PATHTYPE_INVAL
6d90: 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 61  ID;...retval = a
6da0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
6db0: 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69 6e  fo(path, &pathin
6dc0: 66 6f 29 3b 0a 09 69 66 20 28 72 65 74 76 61 6c  fo);..if (retval
6dd0: 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72   != 0) {...retur
6de0: 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09  n(retval);..}...
6df0: 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70  if (pathinfo.typ
6e00: 65 20 21 3d 20 41 50 50 46 53 5f 50 41 54 48 54  e != APPFS_PATHT
6e10: 59 50 45 5f 53 59 4d 4c 49 4e 4b 29 20 7b 0a 09  YPE_SYMLINK) {..
6e20: 09 72 65 74 75 72 6e 28 2d 45 49 4e 56 41 4c 29  .return(-EINVAL)
6e30: 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 73 74 72 6c  ;..}...if ((strl
6e40: 65 6e 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65  en(pathinfo.type
6e50: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75  info.symlink.sou
6e60: 72 63 65 29 20 2b 20 31 29 20 3e 20 73 69 7a 65  rce) + 1) > size
6e70: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 4e  ) {...return(-EN
6e80: 41 4d 45 54 4f 4f 4c 4f 4e 47 29 3b 0a 09 7d 0a  AMETOOLONG);..}.
6e90: 0a 09 6d 65 6d 63 70 79 28 62 75 66 2c 20 70 61  ..memcpy(buf, pa
6ea0: 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e  thinfo.typeinfo.
6eb0: 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c 20  symlink.source, 
6ec0: 73 74 72 6c 65 6e 28 70 61 74 68 69 6e 66 6f 2e  strlen(pathinfo.
6ed0: 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b  typeinfo.symlink
6ee0: 2e 73 6f 75 72 63 65 29 20 2b 20 31 29 3b 0a 0a  .source) + 1);..
6ef0: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
6f00: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
6f10: 66 75 73 65 5f 67 65 74 61 74 74 72 28 63 6f 6e  fuse_getattr(con
6f20: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73  st char *path, s
6f30: 74 72 75 63 74 20 73 74 61 74 20 2a 73 74 62 75  truct stat *stbu
6f40: 66 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70 70  f) {..struct app
6f50: 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74 68  fs_pathinfo path
6f60: 69 6e 66 6f 3b 0a 09 69 6e 74 20 63 68 61 6e 67  info;..int chang
6f70: 65 4f 77 6e 65 72 54 6f 55 73 65 72 49 66 50 61  eOwnerToUserIfPa
6f80: 63 6b 61 67 65 64 3b 0a 09 69 6e 74 20 72 65 74  ckaged;..int ret
6f90: 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  val;...retval = 
6fa0: 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  0;...APPFS_DEBUG
6fb0: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
6fc0: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
6fd0: 3b 0a 0a 23 69 66 20 28 64 65 66 69 6e 65 64 28  ;..#if (defined(
6fe0: 44 45 42 55 47 29 20 26 26 20 64 65 66 69 6e 65  DEBUG) && define
6ff0: 64 28 41 50 50 46 53 5f 45 58 49 54 5f 50 41 54  d(APPFS_EXIT_PAT
7000: 48 29 29 20 7c 7c 20 64 65 66 69 6e 65 64 28 41  H)) || defined(A
7010: 50 50 46 53 5f 45 58 49 54 5f 50 41 54 48 5f 45  PPFS_EXIT_PATH_E
7020: 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f 53 45 43 55  NABLE_MAJOR_SECU
7030: 52 49 54 59 5f 48 4f 4c 45 29 0a 09 2f 2a 0a 09  RITY_HOLE)../*..
7040: 20 2a 20 54 68 69 73 20 69 73 20 61 20 6d 61 6a   * This is a maj
7050: 6f 72 20 73 65 63 75 72 69 74 79 20 69 73 73 75  or security issu
7060: 65 20 73 6f 20 77 65 20 63 61 6e 6e 6f 74 20 6c  e so we cannot l
7070: 65 74 20 69 74 20 62 65 20 63 6f 6d 70 69 6c 65  et it be compile
7080: 64 20 69 6e 74 6f 0a 09 20 2a 20 61 6e 79 20 72  d into.. * any r
7090: 65 6c 65 61 73 65 0a 09 20 2a 2f 0a 0a 09 69 66  elease.. */...if
70a0: 20 28 73 74 72 63 6d 70 28 70 61 74 68 2c 20 22   (strcmp(path, "
70b0: 2f 65 78 69 74 22 29 20 3d 3d 20 30 29 20 7b 0a  /exit") == 0) {.
70c0: 09 09 61 70 70 66 73 5f 65 78 69 74 28 29 3b 0a  ..appfs_exit();.
70d0: 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 70 61 74 68  .}.#endif...path
70e0: 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41 50 50 46  info.type = APPF
70f0: 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c  S_PATHTYPE_INVAL
7100: 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 61  ID;...retval = a
7110: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
7120: 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69 6e  fo(path, &pathin
7130: 66 6f 29 3b 0a 09 69 66 20 28 72 65 74 76 61 6c  fo);..if (retval
7140: 20 21 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 72   != 0) {...if (r
7150: 65 74 76 61 6c 20 3d 3d 20 2d 45 4e 4f 45 4e 54  etval == -ENOENT
7160: 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42  ) {....APPFS_DEB
7170: 55 47 28 22 67 65 74 5f 70 61 74 68 5f 69 6e 66  UG("get_path_inf
7180: 6f 20 72 65 74 75 72 6e 65 64 20 45 4e 4f 45 4e  o returned ENOEN
7190: 54 2c 20 72 65 74 75 72 6e 69 6e 67 20 69 74 20  T, returning it 
71a0: 61 73 20 77 65 6c 6c 2e 22 29 3b 0a 09 09 7d 20  as well.");...} 
71b0: 65 6c 73 65 20 7b 0a 09 09 09 41 50 50 46 53 5f  else {....APPFS_
71c0: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 67 65  DEBUG("error: ge
71d0: 74 5f 70 61 74 68 5f 69 6e 66 6f 20 66 61 69 6c  t_path_info fail
71e0: 65 64 22 29 3b 0a 09 09 7d 0a 0a 09 09 72 65 74  ed");...}....ret
71f0: 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d 0a  urn(retval);..}.
7200: 0a 09 6d 65 6d 73 65 74 28 73 74 62 75 66 2c 20  ..memset(stbuf, 
7210: 30 2c 20 73 69 7a 65 6f 66 28 73 74 72 75 63 74  0, sizeof(struct
7220: 20 73 74 61 74 29 29 3b 0a 0a 09 73 74 62 75 66   stat));...stbuf
7230: 2d 3e 73 74 5f 6d 74 69 6d 65 20 3d 20 70 61 74  ->st_mtime = pat
7240: 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62  hinfo.time;..stb
7250: 75 66 2d 3e 73 74 5f 63 74 69 6d 65 20 3d 20 70  uf->st_ctime = p
7260: 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73  athinfo.time;..s
7270: 74 62 75 66 2d 3e 73 74 5f 61 74 69 6d 65 20 3d  tbuf->st_atime =
7280: 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a   pathinfo.time;.
7290: 09 73 74 62 75 66 2d 3e 73 74 5f 69 6e 6f 20 20  .stbuf->st_ino  
72a0: 20 3d 20 70 61 74 68 69 6e 66 6f 2e 69 6e 6f 64   = pathinfo.inod
72b0: 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  e;..stbuf->st_mo
72c0: 64 65 20 20 3d 20 30 3b 0a 0a 09 63 68 61 6e 67  de  = 0;...chang
72d0: 65 4f 77 6e 65 72 54 6f 55 73 65 72 49 66 50 61  eOwnerToUserIfPa
72e0: 63 6b 61 67 65 64 20 3d 20 31 3b 0a 0a 09 73 77  ckaged = 1;...sw
72f0: 69 74 63 68 20 28 70 61 74 68 69 6e 66 6f 2e 74  itch (pathinfo.t
7300: 79 70 65 29 20 7b 0a 09 09 63 61 73 65 20 41 50  ype) {...case AP
7310: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52  PFS_PATHTYPE_DIR
7320: 45 43 54 4f 52 59 3a 0a 09 09 09 73 74 62 75 66  ECTORY:....stbuf
7330: 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46  ->st_mode = S_IF
7340: 44 49 52 20 7c 20 30 35 35 35 3b 0a 09 09 09 73  DIR | 0555;....s
7350: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d  tbuf->st_nlink =
7360: 20 32 20 2b 20 70 61 74 68 69 6e 66 6f 2e 74 79   2 + pathinfo.ty
7370: 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64  peinfo.dir.child
7380: 63 6f 75 6e 74 3b 0a 09 09 09 62 72 65 61 6b 3b  count;....break;
7390: 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41  ...case APPFS_PA
73a0: 54 48 54 59 50 45 5f 46 49 4c 45 3a 0a 09 09 09  THTYPE_FILE:....
73b0: 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d  stbuf->st_mode =
73c0: 20 53 5f 49 46 52 45 47 20 7c 20 30 34 34 34 3b   S_IFREG | 0444;
73d0: 0a 0a 09 09 09 69 66 20 28 70 61 74 68 69 6e 66  .....if (pathinf
73e0: 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e  o.typeinfo.file.
73f0: 65 78 65 63 75 74 61 62 6c 65 29 20 7b 0a 09 09  executable) {...
7400: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65  ..stbuf->st_mode
7410: 20 7c 3d 20 30 31 31 31 3b 0a 09 09 09 7d 0a 0a   |= 0111;....}..
7420: 09 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e  ...if (pathinfo.
7430: 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 75  typeinfo.file.su
7440: 69 64 52 6f 6f 74 29 20 7b 0a 09 09 09 09 63 68  idRoot) {.....ch
7450: 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65 72 49  angeOwnerToUserI
7460: 66 50 61 63 6b 61 67 65 64 20 3d 20 30 3b 0a 0a  fPackaged = 0;..
7470: 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
7480: 64 65 20 7c 3d 20 30 34 30 30 30 3b 0a 09 09 09  de |= 04000;....
7490: 7d 0a 0a 09 09 09 69 66 20 28 70 61 74 68 69 6e  }.....if (pathin
74a0: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  fo.typeinfo.file
74b0: 2e 77 6f 72 6c 64 61 63 63 65 73 73 69 62 6c 65  .worldaccessible
74c0: 29 20 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e 73  ) {.....stbuf->s
74d0: 74 5f 6d 6f 64 65 20 26 3d 20 7e 30 37 37 3b 0a  t_mode &= ~077;.
74e0: 09 09 09 7d 0a 0a 09 09 09 73 74 62 75 66 2d 3e  ...}.....stbuf->
74f0: 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09  st_nlink = 1;...
7500: 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20  .stbuf->st_size 
7510: 3d 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69  = pathinfo.typei
7520: 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 3b 0a 0a  nfo.file.size;..
7530: 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65  ...break;...case
7540: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
7550: 53 59 4d 4c 49 4e 4b 3a 0a 09 09 09 73 74 62 75  SYMLINK:....stbu
7560: 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49  f->st_mode = S_I
7570: 46 4c 4e 4b 20 7c 20 30 35 35 35 3b 0a 09 09 09  FLNK | 0555;....
7580: 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20  stbuf->st_nlink 
7590: 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  = 1;....stbuf->s
75a0: 74 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e 66  t_size = pathinf
75b0: 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69  o.typeinfo.symli
75c0: 6e 6b 2e 73 69 7a 65 3b 0a 09 09 09 62 72 65 61  nk.size;....brea
75d0: 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f  k;...case APPFS_
75e0: 50 41 54 48 54 59 50 45 5f 53 4f 43 4b 45 54 3a  PATHTYPE_SOCKET:
75f0: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
7600: 64 65 20 3d 20 53 5f 49 46 53 4f 43 4b 20 7c 20  de = S_IFSOCK | 
7610: 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e  0555;....stbuf->
7620: 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09  st_nlink = 1;...
7630: 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20  .stbuf->st_size 
7640: 3d 20 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09  = 0;....break;..
7650: 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48  .case APPFS_PATH
7660: 54 59 50 45 5f 46 49 46 4f 3a 0a 09 09 09 73 74  TYPE_FIFO:....st
7670: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53  buf->st_mode = S
7680: 5f 49 46 49 46 4f 20 7c 20 30 35 35 35 3b 0a 09  _IFIFO | 0555;..
7690: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e  ..stbuf->st_nlin
76a0: 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d  k = 1;....stbuf-
76b0: 3e 73 74 5f 73 69 7a 65 20 3d 20 30 3b 0a 09 09  >st_size = 0;...
76c0: 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41  .break;...case A
76d0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 4f  PPFS_PATHTYPE_DO
76e0: 45 53 5f 4e 4f 54 5f 45 58 49 53 54 3a 0a 09 09  ES_NOT_EXIST:...
76f0: 09 72 65 74 76 61 6c 20 3d 20 2d 45 4e 4f 45 4e  .retval = -ENOEN
7700: 54 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09  T;.....break;...
7710: 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54  case APPFS_PATHT
7720: 59 50 45 5f 49 4e 56 41 4c 49 44 3a 0a 09 09 09  YPE_INVALID:....
7730: 72 65 74 76 61 6c 20 3d 20 2d 45 49 4f 3b 0a 0a  retval = -EIO;..
7740: 09 09 09 62 72 65 61 6b 3b 0a 09 7d 0a 0a 09 69  ...break;..}...i
7750: 66 20 28 70 61 74 68 69 6e 66 6f 2e 70 61 63 6b  f (pathinfo.pack
7760: 61 67 65 64 20 26 26 20 63 68 61 6e 67 65 4f 77  aged && changeOw
7770: 6e 65 72 54 6f 55 73 65 72 49 66 50 61 63 6b 61  nerToUserIfPacka
7780: 67 65 64 29 20 7b 0a 09 09 73 74 62 75 66 2d 3e  ged) {...stbuf->
7790: 73 74 5f 75 69 64 20 20 20 3d 20 61 70 70 66 73  st_uid   = appfs
77a0: 5f 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 09 09  _get_fsuid();...
77b0: 73 74 62 75 66 2d 3e 73 74 5f 67 69 64 20 20 20  stbuf->st_gid   
77c0: 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69  = appfs_get_fsgi
77d0: 64 28 29 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74  d();...stbuf->st
77e0: 5f 6d 6f 64 65 20 7c 3d 20 30 32 30 30 3b 0a 09  _mode |= 0200;..
77f0: 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61  }...return(retva
7800: 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  l);.}..static in
7810: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61  t appfs_fuse_rea
7820: 64 64 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20  ddir(const char 
7830: 2a 70 61 74 68 2c 20 76 6f 69 64 20 2a 62 75 66  *path, void *buf
7840: 2c 20 66 75 73 65 5f 66 69 6c 6c 5f 64 69 72 5f  , fuse_fill_dir_
7850: 74 20 66 69 6c 6c 65 72 2c 20 6f 66 66 5f 74 20  t filler, off_t 
7860: 6f 66 66 73 65 74 2c 20 73 74 72 75 63 74 20 66  offset, struct f
7870: 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66  use_file_info *f
7880: 69 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  i) {..Tcl_Interp
7890: 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c 5f 4f   *interp;..Tcl_O
78a0: 62 6a 20 2a 2a 63 68 69 6c 64 72 65 6e 3b 0a 09  bj **children;..
78b0: 69 6e 74 20 63 68 69 6c 64 72 65 6e 5f 63 6f 75  int children_cou
78c0: 6e 74 2c 20 69 64 78 3b 0a 09 69 6e 74 20 74 63  nt, idx;..int tc
78d0: 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  l_ret;...APPFS_D
78e0: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
78f0: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
7900: 61 74 68 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d  ath);...interp =
7910: 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70   appfs_TclInterp
7920: 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  ();..if (interp 
7930: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50  == NULL) {...APP
7940: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
7950: 20 55 6e 61 62 6c 65 20 74 6f 20 67 65 74 20 61   Unable to get a
7960: 6e 20 69 6e 74 65 72 70 72 65 74 65 72 22 29 3b  n interpreter");
7970: 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09  ....return(0);..
7980: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
7990: 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72  ibtcl(Tcl_Preser
79a0: 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 66  ve(interp);)...f
79b0: 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e 22 2c 20  iller(buf, ".", 
79c0: 4e 55 4c 4c 2c 20 30 29 3b 0a 09 66 69 6c 6c 65  NULL, 0);..fille
79d0: 72 28 62 75 66 2c 20 22 2e 2e 22 2c 20 4e 55 4c  r(buf, "..", NUL
79e0: 4c 2c 20 30 29 3b 0a 0a 09 74 63 6c 5f 72 65 74  L, 0);...tcl_ret
79f0: 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61   = appfs_Tcl_Eva
7a00: 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a  l(interp, 2, "::
7a10: 61 70 70 66 73 3a 3a 67 65 74 63 68 69 6c 64 72  appfs::getchildr
7a20: 65 6e 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20  en", path);..if 
7a30: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
7a40: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
7a50: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65  BUG("::appfs::ge
7a60: 74 63 68 69 6c 64 72 65 6e 28 25 73 29 20 66 61  tchildren(%s) fa
7a70: 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09  iled.", path);..
7a80: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
7a90: 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42  cl(....APPFS_DEB
7aa0: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
7ab0: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
7ac0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
7ad0: 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66  p));...)....appf
7ae0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
7af0: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
7b00: 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 30 29  );)....return(0)
7b10: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
7b20: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f  l_libtcl(...tcl_
7b30: 72 65 74 20 3d 20 54 63 6c 5f 4c 69 73 74 4f 62  ret = Tcl_ListOb
7b40: 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e 74  jGetElements(int
7b50: 65 72 70 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52  erp, Tcl_GetObjR
7b60: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 26  esult(interp), &
7b70: 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c 20  children_count, 
7b80: 26 63 68 69 6c 64 72 65 6e 29 3b 0a 09 29 0a 09  &children);..)..
7b90: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
7ba0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
7bb0: 5f 44 45 42 55 47 28 22 50 61 72 73 69 6e 67 20  _DEBUG("Parsing 
7bc0: 6c 69 73 74 20 6f 66 20 63 68 69 6c 64 72 65 6e  list of children
7bd0: 20 6f 6e 20 70 61 74 68 20 25 73 20 66 61 69 6c   on path %s fail
7be0: 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61  ed.", path);...a
7bf0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
7c00: 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  (....APPFS_DEBUG
7c10: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20  ("Tcl Error is: 
7c20: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  %s", Tcl_GetStri
7c30: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
7c40: 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f  );...)....appfs_
7c50: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
7c60: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
7c70: 29 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a  )....return(0);.
7c80: 09 7d 0a 0a 09 66 6f 72 20 28 69 64 78 20 3d 20  .}...for (idx = 
7c90: 30 3b 20 69 64 78 20 3c 20 63 68 69 6c 64 72 65  0; idx < childre
7ca0: 6e 5f 63 6f 75 6e 74 3b 20 69 64 78 2b 2b 29 20  n_count; idx++) 
7cb0: 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  {...appfs_call_l
7cc0: 69 62 74 63 6c 28 0a 09 09 09 66 69 6c 6c 65 72  ibtcl(....filler
7cd0: 28 62 75 66 2c 20 54 63 6c 5f 47 65 74 53 74 72  (buf, Tcl_GetStr
7ce0: 69 6e 67 28 63 68 69 6c 64 72 65 6e 5b 69 64 78  ing(children[idx
7cf0: 5d 29 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 09  ]), NULL, 0);...
7d00: 29 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  )..}...appfs_cal
7d10: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
7d20: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
7d30: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
7d40: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
7d50: 66 75 73 65 5f 6f 70 65 6e 28 63 6f 6e 73 74 20  fuse_open(const 
7d60: 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75  char *path, stru
7d70: 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66  ct fuse_file_inf
7d80: 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c 5f 49 6e  o *fi) {..Tcl_In
7d90: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 73  terp *interp;..s
7da0: 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68  truct appfs_path
7db0: 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09  info pathinfo;..
7dc0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c  const char *real
7dd0: 5f 70 61 74 68 2c 20 2a 6d 6f 64 65 3b 0a 09 69  _path, *mode;..i
7de0: 6e 74 20 67 70 69 5f 72 65 74 2c 20 74 63 6c 5f  nt gpi_ret, tcl_
7df0: 72 65 74 3b 0a 09 69 6e 74 20 66 68 3b 0a 0a 09  ret;..int fh;...
7e00: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
7e10: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
7e20: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 67  ..)", path);...g
7e30: 70 69 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 67  pi_ret = appfs_g
7e40: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61 74  et_path_info(pat
7e50: 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a 0a  h, &pathinfo);..
7e60: 09 69 66 20 28 28 66 69 2d 3e 66 6c 61 67 73 20  .if ((fi->flags 
7e70: 26 20 28 4f 5f 57 52 4f 4e 4c 59 7c 4f 5f 43 52  & (O_WRONLY|O_CR
7e80: 45 41 54 29 29 20 3d 3d 20 28 4f 5f 43 52 45 41  EAT)) == (O_CREA
7e90: 54 7c 4f 5f 57 52 4f 4e 4c 59 29 29 20 7b 0a 09  T|O_WRONLY)) {..
7ea0: 09 2f 2a 20 54 68 65 20 66 69 6c 65 20 77 69 6c  ./* The file wil
7eb0: 6c 20 62 65 20 63 72 65 61 74 65 64 20 69 66 20  l be created if 
7ec0: 69 74 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73  it does not exis
7ed0: 74 20 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f 72  t */...if (gpi_r
7ee0: 65 74 20 21 3d 20 30 20 26 26 20 67 70 69 5f 72  et != 0 && gpi_r
7ef0: 65 74 20 21 3d 20 2d 45 4e 4f 45 4e 54 29 20 7b  et != -ENOENT) {
7f00: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
7f10: 22 65 72 72 6f 72 3a 20 67 65 74 5f 70 61 74 68  "error: get_path
7f20: 5f 69 6e 66 6f 20 66 61 69 6c 65 64 22 29 3b 0a  _info failed");.
7f30: 0a 09 09 09 72 65 74 75 72 6e 28 67 70 69 5f 72  ....return(gpi_r
7f40: 65 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d 6f 64 65  et);...}....mode
7f50: 20 3d 20 22 63 72 65 61 74 65 22 3b 0a 0a 09 09   = "create";....
7f60: 2f 2a 0a 09 09 20 2a 20 57 65 20 68 61 76 65 20  /*... * We have 
7f70: 74 6f 20 63 6c 65 61 72 20 74 68 65 20 63 61 63  to clear the cac
7f80: 68 65 20 68 65 72 65 20 73 6f 20 74 68 61 74 20  he here so that 
7f90: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a 09 09  the number of...
7fa0: 20 2a 20 6c 69 6e 6b 73 20 67 65 74 73 20 6d 61   * links gets ma
7fb0: 69 6e 74 61 69 6e 65 64 20 6f 6e 20 74 68 65 20  intained on the 
7fc0: 70 61 72 65 6e 74 20 64 69 72 65 63 74 6f 72 79  parent directory
7fd0: 0a 09 09 20 2a 2f 0a 09 09 61 70 70 66 73 5f 67  ... */...appfs_g
7fe0: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
7ff0: 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73 5f 67  he_flush(appfs_g
8000: 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31 29 3b  et_fsuid(), -1);
8010: 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 2f 2a 20  ..} else {.../* 
8020: 54 68 65 20 66 69 6c 65 20 6d 75 73 74 20 61 6c  The file must al
8030: 72 65 61 64 79 20 65 78 69 73 74 20 2a 2f 0a 09  ready exist */..
8040: 09 69 66 20 28 67 70 69 5f 72 65 74 20 21 3d 20  .if (gpi_ret != 
8050: 30 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45  0) {....APPFS_DE
8060: 42 55 47 28 22 65 72 72 6f 72 3a 20 67 65 74 5f  BUG("error: get_
8070: 70 61 74 68 5f 69 6e 66 6f 20 66 61 69 6c 65 64  path_info failed
8080: 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 67  ");.....return(g
8090: 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09  pi_ret);...}....
80a0: 6d 6f 64 65 20 3d 20 22 22 3b 0a 0a 09 09 69 66  mode = "";....if
80b0: 20 28 28 66 69 2d 3e 66 6c 61 67 73 20 26 20 4f   ((fi->flags & O
80c0: 5f 57 52 4f 4e 4c 59 29 20 3d 3d 20 4f 5f 57 52  _WRONLY) == O_WR
80d0: 4f 4e 4c 59 29 20 7b 0a 09 09 09 6d 6f 64 65 20  ONLY) {....mode 
80e0: 3d 20 22 77 72 69 74 65 22 3b 0a 09 09 7d 0a 09  = "write";...}..
80f0: 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f  }...if (pathinfo
8100: 2e 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50  .type == APPFS_P
8110: 41 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52  ATHTYPE_DIRECTOR
8120: 59 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  Y) {...APPFS_DEB
8130: 55 47 28 22 65 72 72 6f 72 3a 20 41 73 6b 65 64  UG("error: Asked
8140: 20 74 6f 20 6f 70 65 6e 20 61 20 64 69 72 65 63   to open a direc
8150: 74 6f 72 79 2e 22 29 3b 0a 0a 09 09 72 65 74 75  tory.");....retu
8160: 72 6e 28 2d 45 49 53 44 49 52 29 3b 0a 09 7d 0a  rn(-EISDIR);..}.
8170: 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
8180: 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69  _TclInterp();..i
8190: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
81a0: 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  L) {...APPFS_DEB
81b0: 55 47 28 22 65 72 72 6f 72 3a 20 55 6e 61 62 6c  UG("error: Unabl
81c0: 65 20 74 6f 20 67 65 74 20 61 6e 20 69 6e 74 65  e to get an inte
81d0: 72 70 72 65 74 65 72 22 29 3b 0a 0a 09 09 72 65  rpreter");....re
81e0: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
81f0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
8200: 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28  cl(Tcl_Preserve(
8210: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f  interp);)...tcl_
8220: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
8230: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 33 2c 20  Eval(interp, 3, 
8240: 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61  "::appfs::openpa
8250: 74 68 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65 29  th", path, mode)
8260: 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  ;..if (tcl_ret !
8270: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50  = TCL_OK) {...AP
8280: 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70  PFS_DEBUG("::app
8290: 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28 25 73 2c  fs::openpath(%s,
82a0: 20 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70   %s) failed.", p
82b0: 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 09 09 61 70  ath, mode);...ap
82c0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
82d0: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
82e0: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
82f0: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
8300: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
8310: 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63  ;...)....appfs_c
8320: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
8330: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
8340: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  ....return(-EIO)
8350: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
8360: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 61 6c  l_libtcl(...real
8370: 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74 53  _path = Tcl_GetS
8380: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
8390: 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f  rp);..)...appfs_
83a0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
83b0: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
83c0: 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74  )...if (real_pat
83d0: 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41  h == NULL) {...A
83e0: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
83f0: 72 3a 20 72 65 61 6c 5f 70 61 74 68 20 77 61 73  r: real_path was
8400: 20 4e 55 4c 4c 2e 22 29 0a 0a 09 09 72 65 74 75   NULL.")....retu
8410: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 41  rn(-EIO);..}...A
8420: 50 50 46 53 5f 44 45 42 55 47 28 22 54 72 61 6e  PPFS_DEBUG("Tran
8430: 73 6c 61 74 65 64 20 72 65 71 75 65 73 74 20 74  slated request t
8440: 6f 20 6f 70 65 6e 20 25 73 20 74 6f 20 6f 70 65  o open %s to ope
8450: 6e 69 6e 67 20 25 73 20 28 6d 6f 64 65 20 3d 20  ning %s (mode = 
8460: 5c 22 25 73 5c 22 29 22 2c 20 70 61 74 68 2c 20  \"%s\")", path, 
8470: 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29  real_path, mode)
8480: 3b 0a 0a 09 66 68 20 3d 20 6f 70 65 6e 28 72 65  ;...fh = open(re
8490: 61 6c 5f 70 61 74 68 2c 20 66 69 2d 3e 66 6c 61  al_path, fi->fla
84a0: 67 73 2c 20 30 36 30 30 29 3b 0a 0a 09 69 66 20  gs, 0600);...if 
84b0: 28 66 68 20 3c 20 30 29 20 7b 0a 09 09 41 50 50  (fh < 0) {...APP
84c0: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
84d0: 20 6f 70 65 6e 20 66 61 69 6c 65 64 22 29 3b 0a   open failed");.
84e0: 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20  ...return(errno 
84f0: 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66 69 2d 3e  * -1);..}...fi->
8500: 66 68 20 3d 20 66 68 3b 0a 0a 09 72 65 74 75 72  fh = fh;...retur
8510: 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n(0);.}..static 
8520: 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 63  int appfs_fuse_c
8530: 6c 6f 73 65 28 63 6f 6e 73 74 20 63 68 61 72 20  lose(const char 
8540: 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20 66 75  *path, struct fu
8550: 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69  se_file_info *fi
8560: 29 20 7b 0a 09 69 6e 74 20 63 6c 6f 73 65 5f 72  ) {..int close_r
8570: 65 74 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f  et;...appfs_get_
8580: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
8590: 72 6d 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67  rm(path, appfs_g
85a0: 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 63  et_fsuid());...c
85b0: 6c 6f 73 65 5f 72 65 74 20 3d 20 63 6c 6f 73 65  lose_ret = close
85c0: 28 66 69 2d 3e 66 68 29 3b 0a 09 69 66 20 28 63  (fi->fh);..if (c
85d0: 6c 6f 73 65 5f 72 65 74 20 21 3d 20 30 29 20 7b  lose_ret != 0) {
85e0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
85f0: 65 72 72 6f 72 3a 20 63 6c 6f 73 65 20 66 61 69  error: close fai
8600: 6c 65 64 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  led");....return
8610: 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d  (errno * -1);..}
8620: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a  ...return(0);.}.
8630: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
8640: 73 5f 66 75 73 65 5f 72 65 61 64 28 63 6f 6e 73  s_fuse_read(cons
8650: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 63 68  t char *path, ch
8660: 61 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20  ar *buf, size_t 
8670: 73 69 7a 65 2c 20 6f 66 66 5f 74 20 6f 66 66 73  size, off_t offs
8680: 65 74 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f  et, struct fuse_
8690: 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b  file_info *fi) {
86a0: 0a 09 73 73 69 7a 65 5f 74 20 72 65 61 64 5f 72  ..ssize_t read_r
86b0: 65 74 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b  et;..int retval;
86c0: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
86d0: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
86e0: 2c 20 62 75 66 2c 20 25 6c 6c 69 2c 20 25 6c 6c  , buf, %lli, %ll
86f0: 69 2c 20 66 64 3d 25 6c 6c 69 29 22 2c 20 70 61  i, fd=%lli)", pa
8700: 74 68 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20  th, (long long) 
8710: 73 69 7a 65 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67  size, (long long
8720: 29 20 6f 66 66 73 65 74 2c 20 28 6c 6f 6e 67 20  ) offset, (long 
8730: 6c 6f 6e 67 29 20 66 69 2d 3e 66 68 29 3b 0a 0a  long) fi->fh);..
8740: 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 77  .retval = 0;...w
8750: 68 69 6c 65 20 28 73 69 7a 65 20 21 3d 20 30 29  hile (size != 0)
8760: 20 7b 0a 09 09 72 65 61 64 5f 72 65 74 20 3d 20   {...read_ret = 
8770: 70 72 65 61 64 28 66 69 2d 3e 66 68 2c 20 62 75  pread(fi->fh, bu
8780: 66 2c 20 73 69 7a 65 2c 20 6f 66 66 73 65 74 29  f, size, offset)
8790: 3b 0a 0a 09 09 69 66 20 28 72 65 61 64 5f 72 65  ;....if (read_re
87a0: 74 20 3c 20 30 29 20 7b 0a 09 09 09 41 50 50 46  t < 0) {....APPF
87b0: 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20  S_DEBUG("error: 
87c0: 72 65 61 64 20 66 61 69 6c 65 64 22 29 3b 0a 0a  read failed");..
87d0: 09 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20  ...return(errno 
87e0: 2a 20 2d 31 29 3b 0a 09 09 7d 0a 0a 09 09 69 66  * -1);...}....if
87f0: 20 28 72 65 61 64 5f 72 65 74 20 3d 3d 20 30 29   (read_ret == 0)
8800: 20 7b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 7d   {....break;...}
8810: 0a 0a 09 09 73 69 7a 65 20 2d 3d 20 72 65 61 64  ....size -= read
8820: 5f 72 65 74 3b 0a 09 09 62 75 66 20 20 2b 3d 20  _ret;...buf  += 
8830: 72 65 61 64 5f 72 65 74 3b 0a 09 09 6f 66 66 73  read_ret;...offs
8840: 65 74 20 2b 3d 20 72 65 61 64 5f 72 65 74 3b 0a  et += read_ret;.
8850: 09 09 72 65 74 76 61 6c 20 2b 3d 20 72 65 61 64  ..retval += read
8860: 5f 72 65 74 3b 0a 09 7d 0a 0a 09 69 66 20 28 73  _ret;..}...if (s
8870: 69 7a 65 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ize != 0) {...AP
8880: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
8890: 3a 20 69 6e 63 6f 6d 70 6c 65 74 65 20 72 65 61  : incomplete rea
88a0: 64 20 28 74 68 69 73 20 6d 69 67 68 74 20 62 65  d (this might be
88b0: 20 61 6e 20 65 72 72 6f 72 20 62 65 63 61 75 73   an error becaus
88c0: 65 20 46 55 53 45 20 77 69 6c 6c 20 72 65 71 75  e FUSE will requ
88d0: 65 73 74 20 74 68 65 20 65 78 61 63 74 20 6c 65  est the exact le
88e0: 6e 67 74 68 20 6f 66 20 74 68 65 20 66 69 6c 65  ngth of the file
88f0: 29 22 29 3b 0a 09 7d 0a 0a 09 41 50 50 46 53 5f  )");..}...APPFS_
8900: 44 45 42 55 47 28 22 52 65 74 75 72 6e 69 6e 67  DEBUG("Returning
8910: 3a 20 25 69 22 2c 20 72 65 74 76 61 6c 29 3b 0a  : %i", retval);.
8920: 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
8930: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
8940: 61 70 70 66 73 5f 66 75 73 65 5f 77 72 69 74 65  appfs_fuse_write
8950: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
8960: 68 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 62  h, const char *b
8970: 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65 2c  uf, size_t size,
8980: 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20 73   off_t offset, s
8990: 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f  truct fuse_file_
89a0: 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 73 73 69  info *fi) {..ssi
89b0: 7a 65 5f 74 20 77 72 69 74 65 5f 72 65 74 3b 0a  ze_t write_ret;.
89c0: 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09 41  .int retval;...A
89d0: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
89e0: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
89f0: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70  .)", path);...ap
8a00: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
8a10: 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c  o_cache_rm(path,
8a20: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
8a30: 28 29 29 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  ());...retval = 
8a40: 30 3b 0a 0a 09 77 68 69 6c 65 20 28 73 69 7a 65  0;...while (size
8a50: 20 21 3d 20 30 29 20 7b 0a 09 09 77 72 69 74 65   != 0) {...write
8a60: 5f 72 65 74 20 3d 20 70 77 72 69 74 65 28 66 69  _ret = pwrite(fi
8a70: 2d 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a 65 2c  ->fh, buf, size,
8a80: 20 6f 66 66 73 65 74 29 3b 0a 0a 09 09 69 66 20   offset);....if 
8a90: 28 77 72 69 74 65 5f 72 65 74 20 3c 20 30 29 20  (write_ret < 0) 
8aa0: 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  {....APPFS_DEBUG
8ab0: 28 22 65 72 72 6f 72 3a 20 77 72 69 74 65 20 66  ("error: write f
8ac0: 61 69 6c 65 64 22 29 3b 0a 0a 09 09 09 72 65 74  ailed");.....ret
8ad0: 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b  urn(errno * -1);
8ae0: 0a 09 09 7d 0a 0a 09 09 69 66 20 28 77 72 69 74  ...}....if (writ
8af0: 65 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09 09  e_ret == 0) {...
8b00: 09 62 72 65 61 6b 3b 0a 09 09 7d 0a 0a 09 09 73  .break;...}....s
8b10: 69 7a 65 20 2d 3d 20 77 72 69 74 65 5f 72 65 74  ize -= write_ret
8b20: 3b 0a 09 09 62 75 66 20 20 2b 3d 20 77 72 69 74  ;...buf  += writ
8b30: 65 5f 72 65 74 3b 0a 09 09 6f 66 66 73 65 74 20  e_ret;...offset 
8b40: 2b 3d 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 09  += write_ret;...
8b50: 72 65 74 76 61 6c 20 2b 3d 20 77 72 69 74 65 5f  retval += write_
8b60: 72 65 74 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 69  ret;..}...if (si
8b70: 7a 65 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50  ze != 0) {...APP
8b80: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
8b90: 20 69 6e 63 6f 6d 70 6c 65 74 65 20 77 72 69 74   incomplete writ
8ba0: 65 22 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  e");..}...return
8bb0: 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61  (retval);.}..sta
8bc0: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
8bd0: 73 65 5f 6d 6b 6e 6f 64 28 63 6f 6e 73 74 20 63  se_mknod(const c
8be0: 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f  har *path, mode_
8bf0: 74 20 6d 6f 64 65 2c 20 64 65 76 5f 74 20 64 65  t mode, dev_t de
8c00: 76 69 63 65 29 20 7b 0a 09 63 68 61 72 20 2a 72  vice) {..char *r
8c10: 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 6d  eal_path;..int m
8c20: 6b 6e 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46  knod_ret;...APPF
8c30: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
8c40: 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22  path = %s, ...)"
8c50: 2c 20 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 28  , path);...if ((
8c60: 6d 6f 64 65 20 26 20 53 5f 49 46 43 48 52 29 20  mode & S_IFCHR) 
8c70: 3d 3d 20 53 5f 49 46 43 48 52 29 20 7b 0a 09 09  == S_IFCHR) {...
8c80: 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a  return(-EPERM);.
8c90: 09 7d 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26  .}...if ((mode &
8ca0: 20 53 5f 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49   S_IFBLK) == S_I
8cb0: 46 42 4c 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e  FBLK) {...return
8cc0: 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72  (-EPERM);..}...r
8cd0: 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73  eal_path = appfs
8ce0: 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61  _prepare_to_crea
8cf0: 74 65 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72  te(path);..if (r
8d00: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
8d10: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
8d20: 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73  O);..}...appfs_s
8d30: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
8d40: 65 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b 6e 6f 64  enter();...mknod
8d50: 5f 72 65 74 20 3d 20 6d 6b 6e 6f 64 28 72 65 61  _ret = mknod(rea
8d60: 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 2c 20 64 65  l_path, mode, de
8d70: 76 69 63 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73  vice);...appfs_s
8d80: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
8d90: 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28  leave();...free(
8da0: 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66  real_path);...if
8db0: 20 28 6d 6b 6e 6f 64 5f 72 65 74 20 21 3d 20 30   (mknod_ret != 0
8dc0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72  ) {...return(err
8dd0: 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72  no * -1);..}...r
8de0: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61  eturn(0);.}..sta
8df0: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
8e00: 73 65 5f 63 72 65 61 74 65 28 63 6f 6e 73 74 20  se_create(const 
8e10: 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65  char *path, mode
8e20: 5f 74 20 6d 6f 64 65 2c 20 73 74 72 75 63 74 20  _t mode, struct 
8e30: 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a  fuse_file_info *
8e40: 66 69 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61  fi) {..char *rea
8e50: 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 66 64 3b  l_path;..int fd;
8e60: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
8e70: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
8e80: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
8e90: 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f  ..if ((mode & S_
8ea0: 49 46 43 48 52 29 20 3d 3d 20 53 5f 49 46 43 48  IFCHR) == S_IFCH
8eb0: 52 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  R) {...return(-E
8ec0: 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  PERM);..}...if (
8ed0: 28 6d 6f 64 65 20 26 20 53 5f 49 46 42 4c 4b 29  (mode & S_IFBLK)
8ee0: 20 3d 3d 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09   == S_IFBLK) {..
8ef0: 09 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b  .return(-EPERM);
8f00: 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20  ..}...real_path 
8f10: 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f  = appfs_prepare_
8f20: 74 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b  to_create(path);
8f30: 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20  ..if (real_path 
8f40: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
8f50: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
8f60: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
8f70: 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a  ser_fs_enter();.
8f80: 0a 09 66 64 20 3d 20 63 72 65 61 74 28 72 65 61  ..fd = creat(rea
8f90: 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a  l_path, mode);..
8fa0: 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  .appfs_simulate_
8fb0: 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b  user_fs_leave();
8fc0: 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74  ...free(real_pat
8fd0: 68 29 3b 0a 0a 09 69 66 20 28 66 64 20 3c 20 30  h);...if (fd < 0
8fe0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72  ) {...return(err
8ff0: 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66  no * -1);..}...f
9000: 69 2d 3e 66 68 20 3d 20 66 64 3b 0a 0a 09 72 65  i->fh = fd;...re
9010: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
9020: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
9030: 65 5f 74 72 75 6e 63 61 74 65 28 63 6f 6e 73 74  e_truncate(const
9040: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6f 66 66   char *path, off
9050: 5f 74 20 73 69 7a 65 29 20 7b 0a 09 63 68 61 72  _t size) {..char
9060: 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e   *real_path;..in
9070: 74 20 74 72 75 6e 63 61 74 65 5f 72 65 74 3b 0a  t truncate_ret;.
9080: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45  ..APPFS_DEBUG("E
9090: 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c  nter (path = %s,
90a0: 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a   ...)", path);..
90b0: 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70  .real_path = app
90c0: 66 73 5f 6c 6f 63 61 6c 70 61 74 68 28 70 61 74  fs_localpath(pat
90d0: 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61  h);..if (real_pa
90e0: 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th == NULL) {...
90f0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
9100: 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74  ...appfs_get_pat
9110: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28  h_info_cache_rm(
9120: 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f  path, appfs_get_
9130: 66 73 75 69 64 28 29 29 3b 0a 0a 09 61 70 70 66  fsuid());...appf
9140: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
9150: 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 74 72  fs_enter();...tr
9160: 75 6e 63 61 74 65 5f 72 65 74 20 3d 20 74 72 75  uncate_ret = tru
9170: 6e 63 61 74 65 28 72 65 61 6c 5f 70 61 74 68 2c  ncate(real_path,
9180: 20 73 69 7a 65 29 3b 0a 0a 09 61 70 70 66 73 5f   size);...appfs_
9190: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
91a0: 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65  _leave();...free
91b0: 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69  (real_path);...i
91c0: 66 20 28 74 72 75 6e 63 61 74 65 5f 72 65 74 20  f (truncate_ret 
91d0: 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e  != 0) {...return
91e0: 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d  (errno * -1);..}
91f0: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a  ...return(0);.}.
9200: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
9210: 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d  s_fuse_unlink_rm
9220: 64 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  dir(const char *
9230: 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74  path) {..Tcl_Int
9240: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 69 6e  erp *interp;..in
9250: 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50  t tcl_ret;...APP
9260: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
9270: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
9280: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66  ", path);...appf
9290: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
92a0: 63 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66  cache_flush(appf
92b0: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d  s_get_fsuid(), -
92c0: 31 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61  1);...interp = a
92d0: 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29  ppfs_TclInterp()
92e0: 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ;..if (interp ==
92f0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
9300: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70  n(-EIO);..}...ap
9310: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
9320: 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74  Tcl_Preserve(int
9330: 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72 65 74  erp);)...tcl_ret
9340: 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61   = appfs_Tcl_Eva
9350: 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a  l(interp, 2, "::
9360: 61 70 70 66 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74  appfs::unlinkpat
9370: 68 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28  h", path);..if (
9380: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
9390: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
93a0: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c  UG("::appfs::unl
93b0: 69 6e 6b 70 61 74 68 28 25 73 29 20 66 61 69 6c  inkpath(%s) fail
93c0: 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61  ed.", path);...a
93d0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
93e0: 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  (....APPFS_DEBUG
93f0: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20  ("Tcl Error is: 
9400: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  %s", Tcl_GetStri
9410: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
9420: 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f  );...)....appfs_
9430: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
9440: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
9450: 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f  )....return(-EIO
9460: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61  );..}...appfs_ca
9470: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
9480: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
9490: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
94a0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
94b0: 5f 66 75 73 65 5f 6d 6b 64 69 72 28 63 6f 6e 73  _fuse_mkdir(cons
94c0: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f  t char *path, mo
94d0: 64 65 5f 74 20 6d 6f 64 65 29 20 7b 0a 09 63 68  de_t mode) {..ch
94e0: 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09  ar *real_path;..
94f0: 69 6e 74 20 6d 6b 64 69 72 5f 72 65 74 3b 0a 0a  int mkdir_ret;..
9500: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
9510: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
9520: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09  ...)", path);...
9530: 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66  real_path = appf
9540: 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65  s_prepare_to_cre
9550: 61 74 65 28 70 61 74 68 29 3b 0a 09 69 66 20 28  ate(path);..if (
9560: 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c  real_path == NUL
9570: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  L) {...return(-E
9580: 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  IO);..}...appfs_
9590: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
95a0: 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b 64 69  _enter();...mkdi
95b0: 72 5f 72 65 74 20 3d 20 6d 6b 64 69 72 28 72 65  r_ret = mkdir(re
95c0: 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a  al_path, mode);.
95d0: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  ..appfs_simulate
95e0: 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29  _user_fs_leave()
95f0: 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61  ;...free(real_pa
9600: 74 68 29 3b 0a 0a 09 69 66 20 28 6d 6b 64 69 72  th);...if (mkdir
9610: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 69  _ret != 0) {...i
9620: 66 20 28 65 72 72 6e 6f 20 21 3d 20 45 45 58 49  f (errno != EEXI
9630: 53 54 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28  ST) {....return(
9640: 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 09 7d  errno * -1);...}
9650: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  ..}...return(0);
9660: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
9670: 70 70 66 73 5f 66 75 73 65 5f 63 68 6d 6f 64 28  ppfs_fuse_chmod(
9680: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
9690: 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 29 20 7b  , mode_t mode) {
96a0: 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  ..Tcl_Interp *in
96b0: 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61  terp;..const cha
96c0: 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69  r *real_path;..i
96d0: 6e 74 20 74 63 6c 5f 72 65 74 2c 20 63 68 6d 6f  nt tcl_ret, chmo
96e0: 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  d_ret;...APPFS_D
96f0: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
9700: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
9710: 61 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65  ath);...appfs_ge
9720: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
9730: 65 5f 72 6d 28 70 61 74 68 2c 20 61 70 70 66 73  e_rm(path, appfs
9740: 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a  _get_fsuid());..
9750: 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f  .interp = appfs_
9760: 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66  TclInterp();..if
9770: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
9780: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
9790: 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63  O);..}...appfs_c
97a0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50  all_libtcl(Tcl_P
97b0: 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b  reserve(interp);
97c0: 29 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70  )...tcl_ret = ap
97d0: 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74  pfs_Tcl_Eval(int
97e0: 65 72 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73  erp, 3, "::appfs
97f0: 3a 3a 6f 70 65 6e 70 61 74 68 22 2c 20 70 61 74  ::openpath", pat
9800: 68 2c 20 22 77 72 69 74 65 22 29 3b 0a 09 69 66  h, "write");..if
9810: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
9820: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
9830: 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6f  EBUG("::appfs::o
9840: 70 65 6e 70 61 74 68 28 25 73 2c 20 25 73 29 20  penpath(%s, %s) 
9850: 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 2c 20  failed.", path, 
9860: 22 77 72 69 74 65 22 29 3b 0a 09 09 61 70 70 66  "write");...appf
9870: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
9880: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
9890: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22  cl Error is: %s"
98a0: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
98b0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
98c0: 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c  ..)....appfs_cal
98d0: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
98e0: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
98f0: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
9900: 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .}...appfs_call_
9910: 6c 69 62 74 63 6c 28 0a 09 09 72 65 61 6c 5f 70  libtcl(...real_p
9920: 61 74 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  ath = Tcl_GetStr
9930: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
9940: 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61  );..)...appfs_ca
9950: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
9960: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
9970: 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20  ..if (real_path 
9980: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
9990: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
99a0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
99b0: 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a  ser_fs_enter();.
99c0: 0a 09 63 68 6d 6f 64 5f 72 65 74 20 3d 20 63 68  ..chmod_ret = ch
99d0: 6d 6f 64 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d  mod(real_path, m
99e0: 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  ode);...appfs_si
99f0: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
9a00: 65 61 76 65 28 29 3b 0a 0a 09 72 65 74 75 72 6e  eave();...return
9a10: 28 63 68 6d 6f 64 5f 72 65 74 29 3b 0a 7d 0a 0a  (chmod_ret);.}..
9a20: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
9a30: 5f 66 75 73 65 5f 73 79 6d 6c 69 6e 6b 28 63 6f  _fuse_symlink(co
9a40: 6e 73 74 20 63 68 61 72 20 2a 6f 6c 64 70 61 74  nst char *oldpat
9a50: 68 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 6e  h, const char *n
9a60: 65 77 70 61 74 68 29 20 7b 0a 09 63 68 61 72 20  ewpath) {..char 
9a70: 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74  *real_path;..int
9a80: 20 73 79 6d 6c 69 6e 6b 5f 72 65 74 3b 0a 0a 09   symlink_ret;...
9a90: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
9aa0: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 25  er (path = %s, %
9ab0: 73 29 22 2c 20 6f 6c 64 70 61 74 68 2c 20 6e 65  s)", oldpath, ne
9ac0: 77 70 61 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70  wpath);...real_p
9ad0: 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70  ath = appfs_prep
9ae0: 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 6e 65  are_to_create(ne
9af0: 77 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61  wpath);..if (rea
9b00: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
9b10: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
9b20: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d  ;..}...appfs_sim
9b30: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
9b40: 74 65 72 28 29 3b 0a 0a 09 73 79 6d 6c 69 6e 6b  ter();...symlink
9b50: 5f 72 65 74 20 3d 20 73 79 6d 6c 69 6e 6b 28 6f  _ret = symlink(o
9b60: 6c 64 70 61 74 68 2c 20 72 65 61 6c 5f 70 61 74  ldpath, real_pat
9b70: 68 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  h);...appfs_simu
9b80: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
9b90: 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61  ve();...free(rea
9ba0: 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 73  l_path);...if (s
9bb0: 79 6d 6c 69 6e 6b 5f 72 65 74 20 21 3d 20 30 29  ymlink_ret != 0)
9bc0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e   {...return(errn
9bd0: 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65  o * -1);..}...re
9be0: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20  turn(0);.}../*. 
9bf0: 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 3a 20  * SQLite3 mode: 
9c00: 45 78 65 63 75 74 65 20 72 61 77 20 53 51 4c 20  Execute raw SQL 
9c10: 61 6e 64 20 72 65 74 75 72 6e 20 73 75 63 63 65  and return succe
9c20: 73 73 20 6f 72 20 66 61 69 6c 75 72 65 0a 20 2a  ss or failure. *
9c30: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  /.static int app
9c40: 66 73 5f 73 71 6c 69 74 65 33 28 63 6f 6e 73 74  fs_sqlite3(const
9c50: 20 63 68 61 72 20 2a 73 71 6c 29 20 7b 0a 09 54   char *sql) {..T
9c60: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
9c70: 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a  p;..const char *
9c80: 73 71 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 74 63  sql_ret;..int tc
9c90: 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20  l_ret;...interp 
9ca0: 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54  = appfs_create_T
9cb0: 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a  clInterp(NULL);.
9cc0: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
9cd0: 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  ULL) {...fprintf
9ce0: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
9cf0: 20 74 6f 20 63 72 65 61 74 65 20 61 20 54 63 6c   to create a Tcl
9d00: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41   interpreter.  A
9d10: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09  borting.\n");...
9d20: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a  .return(1);..}..
9d30: 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73  .tcl_ret = appfs
9d40: 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70  _Tcl_Eval(interp
9d50: 2c 20 35 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 64  , 5, "::appfs::d
9d60: 62 22 2c 20 22 65 76 61 6c 22 2c 20 73 71 6c 2c  b", "eval", sql,
9d70: 20 22 72 6f 77 22 2c 20 22 75 6e 73 65 74 20 2d   "row", "unset -
9d80: 6e 6f 63 6f 6d 70 6c 61 69 6e 20 72 6f 77 28 2a  nocomplain row(*
9d90: 29 3b 20 70 61 72 72 61 79 20 72 6f 77 3b 20 70  ); parray row; p
9da0: 75 74 73 20 5c 22 2d 2d 2d 2d 5c 22 22 29 3b 0a  uts \"----\"");.
9db0: 09 73 71 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47  .sql_ret = Tcl_G
9dc0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
9dd0: 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 74 63  nterp);...if (tc
9de0: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
9df0: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
9e00: 65 72 72 2c 20 22 5b 65 72 72 6f 72 5d 20 25 73  err, "[error] %s
9e10: 5c 6e 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a 0a  \n", sql_ret);..
9e20: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
9e30: 0a 09 69 66 20 28 73 71 6c 5f 72 65 74 20 26 26  ..if (sql_ret &&
9e40: 20 73 71 6c 5f 72 65 74 5b 30 5d 20 21 3d 20 27   sql_ret[0] != '
9e50: 5c 30 27 29 20 7b 0a 09 09 70 72 69 6e 74 66 28  \0') {...printf(
9e60: 22 25 73 5c 6e 22 2c 20 73 71 6c 5f 72 65 74 29  "%s\n", sql_ret)
9e70: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29  ;..}...return(0)
9e80: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 63 6c 20 6d  ;.}../*. * Tcl m
9e90: 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72 61 77  ode: Execute raw
9ea0: 20 54 63 6c 20 61 6e 64 20 72 65 74 75 72 6e 20   Tcl and return 
9eb0: 73 75 63 63 65 73 73 20 6f 72 20 66 61 69 6c 75  success or failu
9ec0: 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  re. */.static in
9ed0: 74 20 61 70 70 66 73 5f 74 63 6c 28 63 6f 6e 73  t appfs_tcl(cons
9ee0: 74 20 63 68 61 72 20 2a 74 63 6c 29 20 7b 0a 09  t char *tcl) {..
9ef0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
9f00: 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20  rp;..const char 
9f10: 2a 74 63 6c 5f 72 65 73 75 6c 74 3b 0a 09 69 6e  *tcl_result;..in
9f20: 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74  t tcl_ret;...int
9f30: 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61  erp = appfs_crea
9f40: 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c  te_TclInterp(NUL
9f50: 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  L);..if (interp 
9f60: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72  == NULL) {...fpr
9f70: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
9f80: 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20 61  able to create a
9f90: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
9fa0: 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29  .  Aborting.\n")
9fb0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a  ;....return(1);.
9fc0: 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54  .}...tcl_ret = T
9fd0: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
9fe0: 74 63 6c 29 3b 0a 09 74 63 6c 5f 72 65 73 75 6c  tcl);..tcl_resul
9ff0: 74 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  t = Tcl_GetStrin
a000: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  gResult(interp);
a010: 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  ...if (tcl_ret !
a020: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70  = TCL_OK) {...fp
a030: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 5b  rintf(stderr, "[
a040: 65 72 72 6f 72 5d 20 25 73 5c 6e 22 2c 20 54 63  error] %s\n", Tc
a050: 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72 70 2c  l_GetVar(interp,
a060: 20 22 65 72 72 6f 72 49 6e 66 6f 22 2c 20 54 43   "errorInfo", TC
a070: 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 29 3b  L_GLOBAL_ONLY));
a080: 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  ....return(1);..
a090: 7d 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 73 75  }...if (tcl_resu
a0a0: 6c 74 20 26 26 20 74 63 6c 5f 72 65 73 75 6c 74  lt && tcl_result
a0b0: 5b 30 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09  [0] != '\0') {..
a0c0: 09 70 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20  .printf("%s\n", 
a0d0: 74 63 6c 5f 72 65 73 75 6c 74 29 3b 0a 09 7d 0a  tcl_result);..}.
a0e0: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
a0f0: 2f 2a 0a 20 2a 20 41 70 70 46 53 64 20 50 61 63  /*. * AppFSd Pac
a100: 6b 61 67 65 20 66 6f 72 20 54 63 6c 3a 0a 20 2a  kage for Tcl:. *
a110: 20 20 20 20 20 20 20 20 20 42 72 69 64 67 65 20           Bridge 
a120: 66 6f 72 20 49 2f 4f 20 6f 70 65 72 61 74 69 6f  for I/O operatio
a130: 6e 73 20 74 6f 20 72 65 71 75 65 73 74 20 69 6e  ns to request in
a140: 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20  formation about 
a150: 74 68 65 20 63 75 72 72 65 6e 74 0a 20 2a 20 20  the current. *  
a160: 20 20 20 20 20 20 20 74 72 61 6e 73 61 63 74 69         transacti
a170: 6f 6e 0a 20 2a 2f 0a 2f 2a 0a 20 2a 20 54 63 6c  on. */./*. * Tcl
a180: 20 69 6e 74 65 72 66 61 63 65 20 74 6f 20 67 65   interface to ge
a190: 74 20 74 68 65 20 68 6f 6d 65 20 64 69 72 65 63  t the home direc
a1a0: 74 6f 72 79 20 66 6f 72 20 74 68 65 20 75 73 65  tory for the use
a1b0: 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 22 63 75  r making the "cu
a1c0: 72 72 65 6e 74 22 0a 20 2a 20 46 55 53 45 20 49  rrent". * FUSE I
a1d0: 2f 4f 20 72 65 71 75 65 73 74 0a 20 2a 2f 0a 73  /O request. */.s
a1e0: 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70  tatic int tcl_ap
a1f0: 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28  pfs_get_homedir(
a200: 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54  ClientData cd, T
a210: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
a220: 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c  p, int objc, Tcl
a230: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
a240: 5b 5d 29 20 7b 0a 09 63 68 61 72 20 2a 68 6f 6d  []) {..char *hom
a250: 65 64 69 72 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a  edir;..Tcl_Obj *
a260: 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 75 69  homedir_obj;..ui
a270: 64 5f 74 20 66 73 75 69 64 3b 0a 09 73 74 61 74  d_t fsuid;..stat
a280: 69 63 20 5f 5f 74 68 72 65 61 64 20 54 63 6c 5f  ic __thread Tcl_
a290: 4f 62 6a 20 2a 6c 61 73 74 5f 68 6f 6d 65 64 69  Obj *last_homedi
a2a0: 72 5f 6f 62 6a 20 3d 20 4e 55 4c 4c 3b 0a 09 73  r_obj = NULL;..s
a2b0: 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64 20 75  tatic __thread u
a2c0: 69 64 5f 74 20 6c 61 73 74 5f 66 73 75 69 64 20  id_t last_fsuid 
a2d0: 3d 20 2d 31 3b 0a 0a 20 20 20 20 20 20 20 20 69  = -1;..        i
a2e0: 66 20 28 6f 62 6a 63 20 21 3d 20 31 29 20 7b 0a  f (objc != 1) {.
a2f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a300: 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73  Tcl_WrongNumArgs
a310: 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76  (interp, 1, objv
a320: 2c 20 4e 55 4c 4c 29 3b 0a 20 20 20 20 20 20 20  , NULL);.       
a330: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 28           return(
a340: 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 20 20 20 20  TCL_ERROR);.    
a350: 20 20 20 20 7d 0a 0a 09 66 73 75 69 64 20 3d 20      }...fsuid = 
a360: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28  appfs_get_fsuid(
a370: 29 3b 0a 0a 09 69 66 20 28 66 73 75 69 64 20 3d  );...if (fsuid =
a380: 3d 20 6c 61 73 74 5f 66 73 75 69 64 20 26 26 20  = last_fsuid && 
a390: 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a  last_homedir_obj
a3a0: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 6f   != NULL) {...ho
a3b0: 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 6c 61 73 74  medir_obj = last
a3c0: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 0a 09  _homedir_obj;...
a3d0: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
a3e0: 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a  t(homedir_obj);.
a3f0: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 68 6f 6d 65  .} else {...home
a400: 64 69 72 20 3d 20 61 70 70 66 73 5f 67 65 74 5f  dir = appfs_get_
a410: 68 6f 6d 65 64 69 72 28 61 70 70 66 73 5f 67 65  homedir(appfs_ge
a420: 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 09 69  t_fsuid());....i
a430: 66 20 28 68 6f 6d 65 64 69 72 20 3d 3d 20 4e 55  f (homedir == NU
a440: 4c 4c 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28  LL) {....return(
a450: 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 09 7d 0a  TCL_ERROR);...}.
a460: 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d  ...homedir_obj =
a470: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
a480: 6a 28 68 6f 6d 65 64 69 72 2c 20 2d 31 29 3b 0a  j(homedir, -1);.
a490: 0a 09 09 66 72 65 65 28 68 6f 6d 65 64 69 72 29  ...free(homedir)
a4a0: 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66  ;....Tcl_IncrRef
a4b0: 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62  Count(homedir_ob
a4c0: 6a 29 3b 0a 0a 09 09 69 66 20 28 6c 61 73 74 5f  j);....if (last_
a4d0: 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 21 3d 20 4e  homedir_obj != N
a4e0: 55 4c 4c 29 20 7b 0a 09 09 09 54 63 6c 5f 44 65  ULL) {....Tcl_De
a4f0: 63 72 52 65 66 43 6f 75 6e 74 28 6c 61 73 74 5f  crRefCount(last_
a500: 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 09  homedir_obj);...
a510: 7d 0a 0a 09 09 6c 61 73 74 5f 68 6f 6d 65 64 69  }....last_homedi
a520: 72 5f 6f 62 6a 20 3d 20 68 6f 6d 65 64 69 72 5f  r_obj = homedir_
a530: 6f 62 6a 3b 0a 09 09 6c 61 73 74 5f 66 73 75 69  obj;...last_fsui
a540: 64 20 3d 20 66 73 75 69 64 3b 0a 0a 09 09 54 63  d = fsuid;....Tc
a550: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 68  l_IncrRefCount(h
a560: 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 7d 0a  omedir_obj);..}.
a570: 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74  .       .Tcl_Set
a580: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
a590: 2c 20 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a  , homedir_obj);.
a5a0: 0a 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75  ..Tcl_DecrRefCou
a5b0: 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b  nt(homedir_obj);
a5c0: 0a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ..        return
a5d0: 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61  (TCL_OK);.}..sta
a5e0: 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66  tic int tcl_appf
a5f0: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
a600: 66 73 5f 65 6e 74 65 72 28 43 6c 69 65 6e 74 44  fs_enter(ClientD
a610: 61 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65  ata cd, Tcl_Inte
a620: 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20  rp *interp, int 
a630: 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43  objc, Tcl_Obj *C
a640: 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09  ONST objv[]) {..
a650: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
a660: 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a  ser_fs_enter();.
a670: 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29  ..return(TCL_OK)
a680: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
a690: 74 63 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61  tcl_appfs_simula
a6a0: 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65  te_user_fs_leave
a6b0: 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20  (ClientData cd, 
a6c0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
a6d0: 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63  rp, int objc, Tc
a6e0: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
a6f0: 76 5b 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73 69  v[]) {..appfs_si
a700: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
a710: 65 61 76 65 28 29 3b 0a 0a 09 72 65 74 75 72 6e  eave();...return
a720: 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61  (TCL_OK);.}..sta
a730: 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66  tic int tcl_appf
a740: 73 5f 67 65 74 5f 66 73 75 69 64 28 43 6c 69 65  s_get_fsuid(Clie
a750: 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49  ntData cd, Tcl_I
a760: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69  nterp *interp, i
a770: 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a  nt objc, Tcl_Obj
a780: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20   *CONST objv[]) 
a790: 7b 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a  {..uid_t fsuid;.
a7a0: 0a 09 66 73 75 69 64 20 3d 20 61 70 70 66 73 5f  ..fsuid = appfs_
a7b0: 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 0a 20 20  get_fsuid();..  
a7c0: 20 20 20 20 20 09 54 63 6c 5f 53 65 74 4f 62 6a       .Tcl_SetObj
a7d0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54  Result(interp, T
a7e0: 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a  cl_NewWideIntObj
a7f0: 28 66 73 75 69 64 29 29 3b 0a 0a 09 72 65 74 75  (fsuid));...retu
a800: 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73  rn(TCL_OK);.}..s
a810: 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70  tatic int tcl_ap
a820: 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28 43 6c  pfs_get_fsgid(Cl
a830: 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c  ientData cd, Tcl
a840: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
a850: 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f   int objc, Tcl_O
a860: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
a870: 29 20 7b 0a 09 67 69 64 5f 74 20 66 73 67 69 64  ) {..gid_t fsgid
a880: 3b 0a 0a 09 66 73 67 69 64 20 3d 20 61 70 70 66  ;...fsgid = appf
a890: 73 5f 67 65 74 5f 66 73 67 69 64 28 29 3b 0a 0a  s_get_fsgid();..
a8a0: 20 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74 4f         .Tcl_SetO
a8b0: 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  bjResult(interp,
a8c0: 20 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f   Tcl_NewWideIntO
a8d0: 62 6a 28 66 73 67 69 64 29 29 3b 0a 0a 09 72 65  bj(fsgid));...re
a8e0: 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a  turn(TCL_OK);.}.
a8f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f  .static int tcl_
a900: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
a910: 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28  nfo_cache_flush(
a920: 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54  ClientData cd, T
a930: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
a940: 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c  p, int objc, Tcl
a950: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
a960: 5b 5d 29 20 7b 0a 09 69 6e 74 20 74 63 6c 5f 72  []) {..int tcl_r
a970: 65 74 3b 0a 09 69 6e 74 20 6e 65 77 5f 73 69 7a  et;..int new_siz
a980: 65 3b 0a 0a 09 6e 65 77 5f 73 69 7a 65 20 3d 20  e;...new_size = 
a990: 2d 31 3b 0a 0a 09 69 66 20 28 6f 62 6a 63 20 3d  -1;...if (objc =
a9a0: 3d 20 32 29 20 7b 0a 09 09 74 63 6c 5f 72 65 74  = 2) {...tcl_ret
a9b0: 20 3d 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f   = Tcl_GetIntFro
a9c0: 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a  mObj(interp, obj
a9d0: 76 5b 31 5d 2c 20 26 6e 65 77 5f 73 69 7a 65 29  v[1], &new_size)
a9e0: 3b 0a 09 09 69 66 20 28 74 63 6c 5f 72 65 74 20  ;...if (tcl_ret 
a9f0: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09  != TCL_OK) {....
aa00: 72 65 74 75 72 6e 28 74 63 6c 5f 72 65 74 29 3b  return(tcl_ret);
aa10: 0a 09 09 7d 0a 09 7d 20 65 6c 73 65 20 69 66 20  ...}..} else if 
aa20: 28 6f 62 6a 63 20 3e 20 32 20 7c 7c 20 6f 62 6a  (objc > 2 || obj
aa30: 63 20 3c 20 31 29 20 7b 0a 20 20 20 20 20 20 20  c < 1) {.       
aa40: 20 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f           Tcl_Wro
aa50: 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70  ngNumArgs(interp
aa60: 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 3f 6e 65 77  , 1, objv, "?new
aa70: 5f 63 61 63 68 65 5f 73 69 7a 65 3f 22 29 3b 0a  _cache_size?");.
aa80: 09 09 72 65 74 75 72 6e 28 54 43 4c 5f 45 52 52  ..return(TCL_ERR
aa90: 4f 52 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  OR);..}...appfs_
aaa0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
aab0: 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c 20 6e 65  che_flush(-1, ne
aac0: 77 5f 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72  w_size);...retur
aad0: 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74  n(TCL_OK);.}..st
aae0: 61 74 69 63 20 69 6e 74 20 41 70 70 66 73 64 5f  atic int Appfsd_
aaf0: 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20  Init(Tcl_Interp 
ab00: 2a 69 6e 74 65 72 70 29 20 7b 0a 23 69 66 64 65  *interp) {.#ifde
ab10: 66 20 55 53 45 5f 54 43 4c 5f 53 54 55 42 53 0a  f USE_TCL_STUBS.
ab20: 09 69 66 20 28 54 63 6c 5f 49 6e 69 74 53 74 75  .if (Tcl_InitStu
ab30: 62 73 28 69 6e 74 65 72 70 2c 20 54 43 4c 5f 56  bs(interp, TCL_V
ab40: 45 52 53 49 4f 4e 2c 20 30 29 20 3d 3d 20 30 4c  ERSION, 0) == 0L
ab50: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 54 43 4c  ) {...return(TCL
ab60: 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 23 65 6e 64  _ERROR);..}.#end
ab70: 69 66 0a 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f  if...Tcl_CreateO
ab80: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
ab90: 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 68  , "appfsd::get_h
aba0: 6f 6d 65 64 69 72 22 2c 20 74 63 6c 5f 61 70 70  omedir", tcl_app
abb0: 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 2c 20  fs_get_homedir, 
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 67 65 74 5f 66 73 75 69 64 22 2c 20  sd::get_fsuid", 
ac00: 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73  tcl_appfs_get_fs
ac10: 75 69 64 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29  uid, NULL, NULL)
ac20: 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a  ;..Tcl_CreateObj
ac30: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
ac40: 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 66 73 67  "appfsd::get_fsg
ac50: 69 64 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67  id", tcl_appfs_g
ac60: 65 74 5f 66 73 67 69 64 2c 20 4e 55 4c 4c 2c 20  et_fsgid, NULL, 
ac70: 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61  NULL);..Tcl_Crea
ac80: 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74  teObjCommand(int
ac90: 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 73 69  erp, "appfsd::si
aca0: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65  mulate_user_fs_e
acb0: 6e 74 65 72 22 2c 20 74 63 6c 5f 61 70 70 66 73  nter", tcl_appfs
acc0: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
acd0: 73 5f 65 6e 74 65 72 2c 20 4e 55 4c 4c 2c 20 4e  s_enter, NULL, N
ace0: 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74  ULL);..Tcl_Creat
acf0: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
ad00: 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 73 69 6d  rp, "appfsd::sim
ad10: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65  ulate_user_fs_le
ad20: 61 76 65 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f  ave", tcl_appfs_
ad30: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
ad40: 5f 6c 65 61 76 65 2c 20 4e 55 4c 4c 2c 20 4e 55  _leave, NULL, NU
ad50: 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65  LL);..Tcl_Create
ad60: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
ad70: 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f  p, "appfsd::get_
ad80: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
ad90: 66 6c 75 73 68 22 2c 20 74 63 6c 5f 61 70 70 66  flush", tcl_appf
ada0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
adb0: 63 61 63 68 65 5f 66 6c 75 73 68 2c 20 4e 55 4c  cache_flush, NUL
adc0: 4c 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 54 63 6c 5f  L, NULL);...Tcl_
add0: 50 6b 67 50 72 6f 76 69 64 65 28 69 6e 74 65 72  PkgProvide(inter
ade0: 70 2c 20 22 61 70 70 66 73 64 22 2c 20 22 31 2e  p, "appfsd", "1.
adf0: 30 22 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43  0");...return(TC
ae00: 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  L_OK);.}../*. * 
ae10: 48 6f 74 2d 72 65 73 74 61 72 74 20 73 75 70 70  Hot-restart supp
ae20: 6f 72 74 0a 20 2a 2f 0a 2f 2a 20 49 6e 69 74 69  ort. */./* Initi
ae30: 61 74 65 20 61 20 68 6f 74 2d 72 65 73 74 61 72  ate a hot-restar
ae40: 74 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  t */.static void
ae50: 20 61 70 70 66 73 5f 68 6f 74 5f 72 65 73 74 61   appfs_hot_resta
ae60: 72 74 28 76 6f 69 64 29 20 7b 0a 09 41 50 50 46  rt(void) {..APPF
ae70: 53 5f 44 45 42 55 47 28 22 41 73 6b 65 64 20 74  S_DEBUG("Asked t
ae80: 6f 20 69 6e 69 74 69 61 74 65 20 68 6f 74 20 72  o initiate hot r
ae90: 65 73 74 61 72 74 22 29 3b 0a 0a 09 61 70 70 66  estart");...appf
aea0: 73 5f 74 63 6c 5f 52 65 73 65 74 49 6e 74 65 72  s_tcl_ResetInter
aeb0: 70 73 28 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65  ps();...appfs_ge
aec0: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
aed0: 65 5f 66 6c 75 73 68 28 2d 31 2c 20 2d 31 29 3b  e_flush(-1, -1);
aee0: 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a  ...return;.}../*
aef0: 0a 20 2a 20 53 69 67 6e 61 6c 20 68 61 6e 64 6c  . * Signal handl
af00: 65 72 0a 20 2a 20 20 20 20 20 20 20 20 20 53 49  er. *         SI
af10: 47 48 55 50 20 69 6e 69 74 69 61 74 65 73 20 61  GHUP initiates a
af20: 20 68 6f 74 20 72 65 73 74 61 72 74 0a 20 2a 2f   hot restart. */
af30: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
af40: 66 73 5f 73 69 67 6e 61 6c 5f 68 61 6e 64 6c 65  fs_signal_handle
af50: 72 28 69 6e 74 20 73 69 67 29 20 7b 0a 09 2f 2a  r(int sig) {../*
af60: 20 44 6f 20 6e 6f 74 20 68 61 6e 64 6c 65 20 73   Do not handle s
af70: 69 67 6e 61 6c 73 20 75 6e 74 69 6c 20 46 55 53  ignals until FUS
af80: 45 20 68 61 73 20 62 65 65 6e 20 73 74 61 72 74  E has been start
af90: 65 64 20 2a 2f 0a 09 69 66 20 28 21 61 70 70 66  ed */..if (!appf
afa0: 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 29 20  s_fuse_started) 
afb0: 7b 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a  {...return;..}..
afc0: 09 2f 2a 20 52 65 71 75 65 73 74 20 74 6f 20 70  ./* Request to p
afd0: 65 72 66 6f 72 6d 20 61 20 22 68 6f 74 22 20 72  erform a "hot" r
afe0: 65 73 74 61 72 74 20 2a 2f 0a 09 69 66 20 28 73  estart */..if (s
aff0: 69 67 20 3d 3d 20 53 49 47 48 55 50 29 20 7b 0a  ig == SIGHUP) {.
b000: 09 09 61 70 70 66 73 5f 68 6f 74 5f 72 65 73 74  ..appfs_hot_rest
b010: 61 72 74 28 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  art();..}...retu
b020: 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 65 72  rn;.}../*. * Ter
b030: 6d 69 6e 61 74 65 20 61 20 74 68 72 65 61 64 0a  minate a thread.
b040: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
b050: 61 70 70 66 73 5f 74 65 72 6d 69 6e 61 74 65 5f  appfs_terminate_
b060: 69 6e 74 65 72 70 5f 61 6e 64 5f 74 68 72 65 61  interp_and_threa
b070: 64 28 76 6f 69 64 20 2a 5f 69 6e 74 65 72 70 29  d(void *_interp)
b080: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
b090: 69 6e 74 65 72 70 3b 0a 0a 09 41 50 50 46 53 5f  interp;...APPFS_
b0a0: 44 45 42 55 47 28 22 43 61 6c 6c 65 64 3a 20 5f  DEBUG("Called: _
b0b0: 69 6e 74 65 72 70 20 3d 20 25 70 22 2c 20 5f 69  interp = %p", _i
b0c0: 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 5f 69  nterp);...if (_i
b0d0: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
b0e0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
b0f0: 54 65 72 6d 69 6e 61 74 69 6e 67 20 74 68 72 65  Terminating thre
b100: 61 64 20 77 69 74 68 20 6e 6f 20 69 6e 74 65 72  ad with no inter
b110: 70 72 65 74 65 72 22 29 3b 0a 0a 09 09 72 65 74  preter");....ret
b120: 75 72 6e 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72 70  urn;..}...interp
b130: 20 3d 20 5f 69 6e 74 65 72 70 3b 0a 0a 09 41 50   = _interp;...AP
b140: 50 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69  PFS_DEBUG("Termi
b150: 6e 61 74 69 6e 67 20 69 6e 74 65 72 70 72 65 74  nating interpret
b160: 65 72 20 64 75 65 20 74 6f 20 74 68 72 65 61 64  er due to thread
b170: 20 74 65 72 6d 69 6e 61 74 69 6f 6e 22 29 3b 0a   termination");.
b180: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
b190: 74 63 6c 28 0a 09 09 54 63 6c 5f 44 65 6c 65 74  tcl(...Tcl_Delet
b1a0: 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b  eInterp(interp);
b1b0: 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..)...appfs_call
b1c0: 5f 6c 69 62 74 63 6c 28 0a 09 09 54 63 6c 5f 46  _libtcl(...Tcl_F
b1d0: 69 6e 61 6c 69 7a 65 54 68 72 65 61 64 28 29 3b  inalizeThread();
b1e0: 0a 09 29 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a  ..)...return;.}.
b1f0: 0a 2f 2a 0a 20 2a 20 43 6f 6d 6d 61 6e 64 2d 6c  ./*. * Command-l
b200: 69 6e 65 20 70 61 72 73 69 6e 67 20 74 6f 6f 6c  ine parsing tool
b210: 73 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  s. */.static voi
b220: 64 20 61 70 70 66 73 5f 70 72 69 6e 74 5f 68 65  d appfs_print_he
b230: 6c 70 28 46 49 4c 45 20 2a 63 68 61 6e 6e 65 6c  lp(FILE *channel
b240: 29 20 7b 0a 09 66 70 72 69 6e 74 66 28 63 68 61  ) {..fprintf(cha
b250: 6e 6e 65 6c 2c 20 22 55 73 61 67 65 3a 20 7b 61  nnel, "Usage: {a
b260: 70 70 66 73 64 7c 6d 6f 75 6e 74 2e 61 70 70 66  ppfsd|mount.appf
b270: 73 7d 20 5b 2d 6f 20 3c 6f 70 74 69 6f 6e 3e 5d  s} [-o <option>]
b280: 20 5b 2d 64 66 73 68 5d 20 3c 63 61 63 68 65 64   [-dfsh] <cached
b290: 69 72 3e 20 3c 6d 6f 75 6e 74 70 6f 69 6e 74 3e  ir> <mountpoint>
b2a0: 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63  \n");..fprintf(c
b2b0: 68 61 6e 6e 65 6c 2c 20 22 5c 6e 22 29 3b 0a 09  hannel, "\n");..
b2c0: 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c  fprintf(channel,
b2d0: 20 22 4f 70 74 69 6f 6e 73 3a 5c 6e 22 29 3b 0a   "Options:\n");.
b2e0: 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c  .fprintf(channel
b2f0: 2c 20 22 20 20 2d 64 20 20 20 20 20 20 20 20 20  , "  -d         
b300: 20 20 20 20 20 45 6e 61 62 6c 65 20 46 55 53 45       Enable FUSE
b310: 20 64 65 62 75 67 20 6d 6f 64 65 2e 5c 6e 22 29   debug mode.\n")
b320: 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e  ;..fprintf(chann
b330: 65 6c 2c 20 22 20 20 2d 66 20 20 20 20 20 20 20  el, "  -f       
b340: 20 20 20 20 20 20 20 52 75 6e 20 69 6e 20 66 6f         Run in fo
b350: 72 65 67 72 6f 75 6e 64 2e 5c 6e 22 29 3b 0a 09  reground.\n");..
b360: 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c  fprintf(channel,
b370: 20 22 20 20 2d 73 20 20 20 20 20 20 20 20 20 20   "  -s          
b380: 20 20 20 20 45 6e 61 62 6c 65 20 73 69 6e 67 6c      Enable singl
b390: 65 20 74 68 72 65 61 64 65 64 20 6d 6f 64 65 2e  e threaded mode.
b3a0: 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63  \n");..fprintf(c
b3b0: 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 68 20 20 20  hannel, "  -h   
b3c0: 20 20 20 20 20 20 20 20 20 20 20 47 69 76 65 20             Give 
b3d0: 74 68 69 73 20 68 65 6c 70 2e 5c 6e 22 29 3b 0a  this help.\n");.
b3e0: 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c  .fprintf(channel
b3f0: 2c 20 22 20 20 2d 6f 20 6e 6f 74 68 72 65 61 64  , "  -o nothread
b400: 73 20 20 20 20 45 6e 61 62 6c 65 20 73 69 6e 67  s    Enable sing
b410: 6c 65 20 74 68 72 65 61 64 65 64 20 6d 6f 64 65  le threaded mode
b420: 2e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28  .\n");..fprintf(
b430: 63 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 6f 20 61  channel, "  -o a
b440: 6c 6c 6f 77 5f 6f 74 68 65 72 20 20 41 6c 6c 6f  llow_other  Allo
b450: 77 20 6f 74 68 65 72 20 75 73 65 72 73 20 74 6f  w other users to
b460: 20 61 63 63 65 73 73 20 74 68 69 73 20 6d 6f 75   access this mou
b470: 6e 74 70 6f 69 6e 74 20 28 64 65 66 61 75 6c 74  ntpoint (default
b480: 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63  \n");..fprintf(c
b490: 68 61 6e 6e 65 6c 2c 20 22 20 20 20 20 20 20 20  hannel, "       
b4a0: 20 20 20 20 20 20 20 20 20 20 20 69 66 20 72 6f             if ro
b4b0: 6f 74 29 2e 5c 6e 22 29 3b 0a 0a 09 72 65 74 75  ot).\n");...retu
b4c0: 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  rn;.}..static in
b4d0: 74 20 61 70 70 66 73 5f 6f 70 74 5f 70 61 72 73  t appfs_opt_pars
b4e0: 65 28 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72  e(int argc, char
b4f0: 20 2a 2a 61 72 67 76 2c 20 20 73 74 72 75 63 74   **argv,  struct
b500: 20 66 75 73 65 5f 61 72 67 73 20 2a 61 72 67 73   fuse_args *args
b510: 29 20 7b 0a 09 69 6e 74 20 63 68 3b 0a 09 63 68  ) {..int ch;..ch
b520: 61 72 20 2a 6f 70 74 73 74 72 2c 20 2a 6f 70 74  ar *optstr, *opt
b530: 73 74 72 5f 6e 65 78 74 2c 20 2a 6f 70 74 73 74  str_next, *optst
b540: 72 5f 73 3b 0a 09 63 68 61 72 20 66 61 6b 65 5f  r_s;..char fake_
b550: 61 72 67 5b 33 5d 20 3d 20 7b 27 2d 27 2c 20 30  arg[3] = {'-', 0
b560: 2c 20 30 7d 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 44  , 0};.../*.. * D
b570: 65 66 61 75 6c 74 20 76 61 6c 75 65 73 0a 09 20  efault values.. 
b580: 2a 2f 0a 23 69 66 64 65 66 20 54 43 4c 5f 54 48  */.#ifdef TCL_TH
b590: 52 45 41 44 53 0a 09 61 70 70 66 73 5f 74 68 72  READS..appfs_thr
b5a0: 65 61 64 65 64 5f 74 63 6c 20 3d 20 31 3b 0a 23  eaded_tcl = 1;.#
b5b0: 65 6c 73 65 0a 09 61 70 70 66 73 5f 74 68 72 65  else..appfs_thre
b5c0: 61 64 65 64 5f 74 63 6c 20 3d 20 30 3b 0a 23 65  aded_tcl = 0;.#e
b5d0: 6e 64 69 66 0a 0a 09 2f 2a 2a 0a 09 20 2a 2a 20  ndif.../**.. ** 
b5e0: 41 64 64 20 46 55 53 45 20 61 72 67 75 6d 65 6e  Add FUSE argumen
b5f0: 74 73 20 77 68 69 63 68 20 77 65 20 61 6c 77 61  ts which we alwa
b600: 79 73 20 73 75 70 70 6c 79 0a 09 20 2a 2a 2f 0a  ys supply.. **/.
b610: 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72  .fuse_opt_add_ar
b620: 67 28 61 72 67 73 2c 20 22 2d 6f 64 65 66 61 75  g(args, "-odefau
b630: 6c 74 5f 70 65 72 6d 69 73 73 69 6f 6e 73 2c 66  lt_permissions,f
b640: 73 6e 61 6d 65 3d 61 70 70 66 73 2c 73 75 62 74  sname=appfs,subt
b650: 79 70 65 3d 61 70 70 66 73 64 2c 75 73 65 5f 69  ype=appfsd,use_i
b660: 6e 6f 2c 6b 65 72 6e 65 6c 5f 63 61 63 68 65 2c  no,kernel_cache,
b670: 65 6e 74 72 79 5f 74 69 6d 65 6f 75 74 3d 30 2c  entry_timeout=0,
b680: 61 74 74 72 5f 74 69 6d 65 6f 75 74 3d 30 2c 62  attr_timeout=0,b
b690: 69 67 5f 77 72 69 74 65 73 2c 69 6e 74 72 2c 68  ig_writes,intr,h
b6a0: 61 72 64 5f 72 65 6d 6f 76 65 22 29 3b 0a 0a 09  ard_remove");...
b6b0: 69 66 20 28 67 65 74 75 69 64 28 29 20 3d 3d 20  if (getuid() == 
b6c0: 30 29 20 7b 0a 09 09 66 75 73 65 5f 6f 70 74 5f  0) {...fuse_opt_
b6d0: 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c  parse(args, NULL
b6e0: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09  , NULL, NULL);..
b6f0: 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72  .fuse_opt_add_ar
b700: 67 28 61 72 67 73 2c 20 22 2d 6f 61 6c 6c 6f 77  g(args, "-oallow
b710: 5f 6f 74 68 65 72 22 29 3b 0a 0a 09 09 2f 2a 0a  _other");..../*.
b720: 09 09 20 2a 20 54 68 69 73 20 73 68 6f 75 6c 64  .. * This should
b730: 20 67 65 6e 65 72 61 6c 6c 79 20 62 65 20 61 76   generally be av
b740: 6f 69 64 65 64 2c 20 62 75 74 20 69 66 20 74 68  oided, but if th
b750: 65 72 65 20 61 72 65 20 73 65 63 75 72 69 74 79  ere are security
b760: 0a 09 09 20 2a 20 63 6f 6e 63 65 72 6e 73 20 73  ... * concerns s
b770: 75 69 64 20 63 61 6e 20 62 65 20 64 69 73 61 62  uid can be disab
b780: 6c 65 64 20 63 6f 6d 70 6c 65 74 65 6c 79 20 6f  led completely o
b790: 6e 20 74 68 65 20 63 6f 6d 6d 61 6e 64 6c 69 6e  n the commandlin
b7a0: 65 0a 09 09 20 2a 2f 0a 09 09 66 75 73 65 5f 6f  e... */...fuse_o
b7b0: 70 74 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e  pt_parse(args, N
b7c0: 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29  ULL, NULL, NULL)
b7d0: 3b 0a 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64  ;...fuse_opt_add
b7e0: 5f 61 72 67 28 61 72 67 73 2c 20 22 2d 6f 73 75  _arg(args, "-osu
b7f0: 69 64 22 29 3b 0a 09 7d 0a 0a 09 77 68 69 6c 65  id");..}...while
b800: 20 28 28 63 68 20 3d 20 67 65 74 6f 70 74 28 61   ((ch = getopt(a
b810: 72 67 63 2c 20 61 72 67 76 2c 20 22 64 66 73 68  rgc, argv, "dfsh
b820: 76 6f 3a 22 29 29 20 21 3d 20 2d 31 29 20 7b 0a  vo:")) != -1) {.
b830: 09 09 73 77 69 74 63 68 20 28 63 68 29 20 7b 0a  ..switch (ch) {.
b840: 09 09 09 63 61 73 65 20 27 76 27 3a 0a 09 09 09  ...case 'v':....
b850: 09 2f 2a 20 49 67 6e 6f 72 65 64 20 2a 2f 0a 09  ./* Ignored */..
b860: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73  ...break;....cas
b870: 65 20 27 6f 27 3a 0a 09 09 09 09 6f 70 74 73 74  e 'o':.....optst
b880: 72 5f 6e 65 78 74 20 3d 20 6f 70 74 73 74 72 20  r_next = optstr 
b890: 3d 20 6f 70 74 73 74 72 5f 73 20 3d 20 73 74 72  = optstr_s = str
b8a0: 64 75 70 28 6f 70 74 61 72 67 29 3b 0a 0a 09 09  dup(optarg);....
b8b0: 09 09 77 68 69 6c 65 20 28 31 29 20 7b 0a 09 09  ..while (1) {...
b8c0: 09 09 09 6f 70 74 73 74 72 20 3d 20 6f 70 74 73  ...optstr = opts
b8d0: 74 72 5f 6e 65 78 74 3b 0a 0a 09 09 09 09 09 69  tr_next;.......i
b8e0: 66 20 28 21 6f 70 74 73 74 72 29 20 7b 0a 09 09  f (!optstr) {...
b8f0: 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 09  ....break;......
b900: 7d 0a 0a 09 09 09 09 09 6f 70 74 73 74 72 5f 6e  }.......optstr_n
b910: 65 78 74 20 3d 20 73 74 72 63 68 72 28 6f 70 74  ext = strchr(opt
b920: 73 74 72 2c 20 27 2c 27 29 3b 0a 09 09 09 09 09  str, ',');......
b930: 69 66 20 28 6f 70 74 73 74 72 5f 6e 65 78 74 29  if (optstr_next)
b940: 20 7b 0a 09 09 09 09 09 09 2a 6f 70 74 73 74 72   {.......*optstr
b950: 5f 6e 65 78 74 20 3d 20 27 5c 30 27 3b 0a 09 09  _next = '\0';...
b960: 09 09 09 09 6f 70 74 73 74 72 5f 6e 65 78 74 2b  ....optstr_next+
b970: 2b 3b 0a 09 09 09 09 09 7d 0a 0a 09 09 09 09 09  +;......}.......
b980: 69 66 20 28 73 74 72 63 6d 70 28 6f 70 74 73 74  if (strcmp(optst
b990: 72 2c 20 22 6e 6f 74 68 72 65 61 64 73 22 29 20  r, "nothreads") 
b9a0: 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09 09 41 50  == 0) {.......AP
b9b0: 50 46 53 5f 44 45 42 55 47 28 22 50 61 73 73 69  PFS_DEBUG("Passi
b9c0: 6e 67 20 6f 70 74 69 6f 6e 20 74 6f 20 46 55 53  ng option to FUS
b9d0: 45 3a 20 2d 73 22 29 3b 0a 0a 09 09 09 09 09 09  E: -s");........
b9e0: 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61  fuse_opt_parse(a
b9f0: 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c  rgs, NULL, NULL,
ba00: 20 4e 55 4c 4c 29 3b 0a 09 09 09 09 09 09 66 75   NULL);.......fu
ba10: 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 61  se_opt_add_arg(a
ba20: 72 67 73 2c 20 22 2d 73 22 29 3b 0a 0a 09 09 09  rgs, "-s");.....
ba30: 09 09 09 61 70 70 66 73 5f 74 68 72 65 61 64 65  ...appfs_threade
ba40: 64 5f 74 63 6c 20 3d 20 30 3b 0a 09 09 09 09 09  d_tcl = 0;......
ba50: 7d 20 65 6c 73 65 20 69 66 20 28 73 74 72 63 6d  } else if (strcm
ba60: 70 28 6f 70 74 73 74 72 2c 20 22 61 6c 6c 6f 77  p(optstr, "allow
ba70: 5f 6f 74 68 65 72 22 29 20 3d 3d 20 30 29 20 7b  _other") == 0) {
ba80: 0a 09 09 09 09 09 09 41 50 50 46 53 5f 44 45 42  .......APPFS_DEB
ba90: 55 47 28 22 50 61 73 73 69 6e 67 20 6f 70 74 69  UG("Passing opti
baa0: 6f 6e 20 74 6f 20 46 55 53 45 3a 20 2d 6f 20 61  on to FUSE: -o a
bab0: 6c 6c 6f 77 5f 4f 74 68 65 72 22 29 3b 0a 0a 09  llow_Other");...
bac0: 09 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 70 61  .....fuse_opt_pa
bad0: 72 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20  rse(args, NULL, 
bae0: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09 09  NULL, NULL);....
baf0: 09 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f  ...fuse_opt_add_
bb00: 61 72 67 28 61 72 67 73 2c 20 22 2d 6f 61 6c 6c  arg(args, "-oall
bb10: 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 09 09 09 09  ow_other");.....
bb20: 09 7d 20 65 6c 73 65 20 69 66 20 28 73 74 72 63  .} else if (strc
bb30: 6d 70 28 6f 70 74 73 74 72 2c 20 22 72 77 22 29  mp(optstr, "rw")
bb40: 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09 09 2f   == 0) {......./
bb50: 2a 20 49 67 6e 6f 72 65 64 20 2a 2f 0a 09 09 09  * Ignored */....
bb60: 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 09  ..} else {......
bb70: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
bb80: 20 22 61 70 70 66 73 64 3a 20 69 6e 76 61 6c 69   "appfsd: invali
bb90: 64 20 6f 70 74 69 6f 6e 3a 20 5c 22 2d 6f 20 25  d option: \"-o %
bba0: 73 5c 22 5c 6e 22 2c 20 6f 70 74 73 74 72 29 3b  s\"\n", optstr);
bbb0: 0a 0a 09 09 09 09 09 09 66 72 65 65 28 6f 70 74  ........free(opt
bbc0: 73 74 72 5f 73 29 3b 0a 0a 09 09 09 09 09 09 72  str_s);........r
bbd0: 65 74 75 72 6e 28 31 29 3b 0a 09 09 09 09 09 7d  eturn(1);......}
bbe0: 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66 72 65 65  .....}......free
bbf0: 28 6f 70 74 73 74 72 5f 73 29 3b 0a 0a 09 09 09  (optstr_s);.....
bc00: 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20  .break;....case 
bc10: 27 64 27 3a 0a 09 09 09 63 61 73 65 20 27 66 27  'd':....case 'f'
bc20: 3a 0a 09 09 09 63 61 73 65 20 27 73 27 3a 0a 09  :....case 's':..
bc30: 09 09 09 69 66 20 28 63 68 20 3d 3d 20 27 73 27  ...if (ch == 's'
bc40: 29 20 7b 0a 09 09 09 09 09 61 70 70 66 73 5f 74  ) {......appfs_t
bc50: 68 72 65 61 64 65 64 5f 74 63 6c 20 3d 20 30 3b  hreaded_tcl = 0;
bc60: 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66 61 6b 65  .....}......fake
bc70: 5f 61 72 67 5b 31 5d 20 3d 20 63 68 3b 0a 0a 09  _arg[1] = ch;...
bc80: 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
bc90: 50 61 73 73 69 6e 67 20 6f 70 74 69 6f 6e 20 74  Passing option t
bca0: 6f 20 46 55 53 45 3a 20 25 73 22 2c 20 66 61 6b  o FUSE: %s", fak
bcb0: 65 5f 61 72 67 29 3b 0a 0a 09 09 09 09 66 75 73  e_arg);......fus
bcc0: 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67 73  e_opt_parse(args
bcd0: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55  , NULL, NULL, NU
bce0: 4c 4c 29 3b 0a 09 09 09 09 66 75 73 65 5f 6f 70  LL);.....fuse_op
bcf0: 74 5f 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20  t_add_arg(args, 
bd00: 66 61 6b 65 5f 61 72 67 29 3b 0a 09 09 09 09 62  fake_arg);.....b
bd10: 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 68  reak;....case 'h
bd20: 27 3a 0a 09 09 09 09 61 70 70 66 73 5f 70 72 69  ':.....appfs_pri
bd30: 6e 74 5f 68 65 6c 70 28 73 74 64 6f 75 74 29 3b  nt_help(stdout);
bd40: 0a 0a 09 09 09 09 72 65 74 75 72 6e 28 2d 31 29  ......return(-1)
bd50: 3b 0a 09 09 09 63 61 73 65 20 27 3a 27 3a 0a 09  ;....case ':':..
bd60: 09 09 63 61 73 65 20 27 3f 27 3a 0a 09 09 09 64  ..case '?':....d
bd70: 65 66 61 75 6c 74 3a 0a 09 09 09 09 61 70 70 66  efault:.....appf
bd80: 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28 73 74 64  s_print_help(std
bd90: 65 72 72 29 3b 0a 0a 09 09 09 09 72 65 74 75 72  err);......retur
bda0: 6e 28 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 69  n(1);...}..}...i
bdb0: 66 20 28 28 6f 70 74 69 6e 64 20 2b 20 32 29 20  f ((optind + 2) 
bdc0: 21 3d 20 61 72 67 63 29 20 7b 0a 09 09 69 66 20  != argc) {...if 
bdd0: 28 28 6f 70 74 69 6e 64 20 2b 20 32 29 20 3c 20  ((optind + 2) < 
bde0: 61 72 67 63 29 20 7b 0a 09 09 09 66 70 72 69 6e  argc) {....fprin
bdf0: 74 66 28 73 74 64 65 72 72 2c 20 22 54 6f 6f 20  tf(stderr, "Too 
be00: 6d 61 6e 79 20 61 72 67 75 6d 65 6e 74 73 5c 6e  many arguments\n
be10: 22 29 3b 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09  ");...} else {..
be20: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
be30: 2c 20 22 4d 69 73 73 69 6e 67 20 63 61 63 68 65  , "Missing cache
be40: 64 69 72 20 6f 72 20 6d 6f 75 6e 74 70 6f 69 6e  dir or mountpoin
be50: 74 5c 6e 22 29 3b 0a 09 09 7d 0a 0a 09 09 61 70  t\n");...}....ap
be60: 70 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28 73  pfs_print_help(s
be70: 74 64 65 72 72 29 3b 0a 0a 09 09 72 65 74 75 72  tderr);....retur
be80: 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  n(1);..}.../*.. 
be90: 2a 20 53 65 74 20 63 61 63 68 65 20 64 69 72 20  * Set cache dir 
bea0: 61 73 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e  as first argumen
beb0: 74 20 28 74 68 65 20 22 64 65 76 69 63 65 22 2c  t (the "device",
bec0: 20 65 73 73 65 6e 74 69 61 6c 6c 79 29 0a 09 20   essentially).. 
bed0: 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65 64  */..appfs_cached
bee0: 69 72 20 3d 20 61 72 67 76 5b 6f 70 74 69 6e 64  ir = argv[optind
bef0: 5d 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 50 61 73 73  ];.../*.. * Pass
bf00: 20 74 68 65 20 72 65 6d 61 69 6e 69 6e 67 20 61   the remaining a
bf10: 72 67 75 6d 65 6e 74 20 74 6f 20 46 55 53 45 20  rgument to FUSE 
bf20: 61 73 20 74 68 65 20 64 69 72 65 63 74 6f 72 79  as the directory
bf30: 0a 09 20 2a 2f 0a 09 66 75 73 65 5f 6f 70 74 5f  .. */..fuse_opt_
bf40: 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c  parse(args, NULL
bf50: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09  , NULL, NULL);..
bf60: 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67  fuse_opt_add_arg
bf70: 28 61 72 67 73 2c 20 61 72 67 76 5b 6f 70 74 69  (args, argv[opti
bf80: 6e 64 20 2b 20 31 5d 29 3b 0a 0a 09 72 65 74 75  nd + 1]);...retu
bf90: 72 6e 28 30 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 20 2a  rn(0);.}.../*. *
bfa0: 20 46 55 53 45 20 6f 70 65 72 61 74 69 6f 6e 73   FUSE operations
bfb0: 20 73 74 72 75 63 74 75 72 65 0a 20 2a 2f 0a 73   structure. */.s
bfc0: 74 61 74 69 63 20 73 74 72 75 63 74 20 66 75 73  tatic struct fus
bfd0: 65 5f 6f 70 65 72 61 74 69 6f 6e 73 20 61 70 70  e_operations app
bfe0: 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 20 3d 20  fs_operations = 
bff0: 7b 0a 09 2e 67 65 74 61 74 74 72 20 20 20 3d 20  {...getattr   = 
c000: 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74 61 74  appfs_fuse_getat
c010: 74 72 2c 0a 09 2e 72 65 61 64 64 69 72 20 20 20  tr,...readdir   
c020: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61  = appfs_fuse_rea
c030: 64 64 69 72 2c 0a 09 2e 72 65 61 64 6c 69 6e 6b  ddir,...readlink
c040: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72    = appfs_fuse_r
c050: 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f 70 65 6e 20  eadlink,...open 
c060: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
c070: 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65 6c 65 61 73  e_open,...releas
c080: 65 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  e   = appfs_fuse
c090: 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65 61 64 20 20  _close,...read  
c0a0: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
c0b0: 5f 72 65 61 64 2c 0a 09 2e 77 72 69 74 65 20 20  _read,...write  
c0c0: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
c0d0: 77 72 69 74 65 2c 0a 09 2e 6d 6b 6e 6f 64 20 20  write,...mknod  
c0e0: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
c0f0: 6d 6b 6e 6f 64 2c 0a 09 2e 63 72 65 61 74 65 20  mknod,...create 
c100: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
c110: 63 72 65 61 74 65 2c 0a 09 2e 74 72 75 6e 63 61  create,...trunca
c120: 74 65 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  te  = appfs_fuse
c130: 5f 74 72 75 6e 63 61 74 65 2c 0a 09 2e 75 6e 6c  _truncate,...unl
c140: 69 6e 6b 20 20 20 20 3d 20 61 70 70 66 73 5f 66  ink    = appfs_f
c150: 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72  use_unlink_rmdir
c160: 2c 0a 09 2e 72 6d 64 69 72 20 20 20 20 20 3d 20  ,...rmdir     = 
c170: 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e  appfs_fuse_unlin
c180: 6b 5f 72 6d 64 69 72 2c 0a 09 2e 6d 6b 64 69 72  k_rmdir,...mkdir
c190: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
c1a0: 65 5f 6d 6b 64 69 72 2c 0a 09 2e 63 68 6d 6f 64  e_mkdir,...chmod
c1b0: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
c1c0: 65 5f 63 68 6d 6f 64 2c 0a 09 2e 73 79 6d 6c 69  e_chmod,...symli
c1d0: 6e 6b 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73  nk   = appfs_fus
c1e0: 65 5f 73 79 6d 6c 69 6e 6b 2c 0a 7d 3b 0a 0a 2f  e_symlink,.};../
c1f0: 2a 0a 20 2a 20 45 6e 74 72 79 20 70 6f 69 6e 74  *. * Entry point
c200: 20 69 6e 74 6f 20 74 68 69 73 20 70 72 6f 67 72   into this progr
c210: 61 6d 2e 0a 20 2a 2f 0a 69 6e 74 20 6d 61 69 6e  am.. */.int main
c220: 28 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20  (int argc, char 
c230: 2a 2a 61 72 67 76 29 20 7b 0a 09 54 63 6c 5f 49  **argv) {..Tcl_I
c240: 6e 74 65 72 70 20 2a 74 65 73 74 5f 69 6e 74 65  nterp *test_inte
c250: 72 70 3b 0a 09 63 68 61 72 20 2a 74 65 73 74 5f  rp;..char *test_
c260: 69 6e 74 65 72 70 5f 65 72 72 6f 72 3b 0a 09 73  interp_error;..s
c270: 74 72 75 63 74 20 66 75 73 65 5f 61 72 67 73 20  truct fuse_args 
c280: 61 72 67 73 20 3d 20 46 55 53 45 5f 41 52 47 53  args = FUSE_ARGS
c290: 5f 49 4e 49 54 28 30 2c 20 4e 55 4c 4c 29 3b 0a  _INIT(0, NULL);.
c2a0: 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74  .int pthread_ret
c2b0: 2c 20 61 6f 70 5f 72 65 74 3b 0a 09 76 6f 69 64  , aop_ret;..void
c2c0: 20 2a 73 69 67 6e 61 6c 5f 72 65 74 3b 0a 09 63   *signal_ret;..c
c2d0: 68 61 72 20 2a 61 72 67 76 30 3b 0a 0a 09 2f 2a  har *argv0;.../*
c2e0: 0a 09 20 2a 20 53 6b 69 70 20 70 61 73 73 65 64  .. * Skip passed
c2f0: 20 70 72 6f 67 72 61 6d 20 6e 61 6d 65 0a 09 20   program name.. 
c300: 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20  */..if (argc == 
c310: 30 20 7c 7c 20 61 72 67 76 20 3d 3d 20 4e 55 4c  0 || argv == NUL
c320: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 31 29  L) {...return(1)
c330: 3b 0a 09 7d 0a 0a 09 61 72 67 76 30 20 3d 20 61  ;..}...argv0 = a
c340: 72 67 76 5b 30 5d 3b 0a 0a 09 61 72 67 63 2d 2d  rgv[0];...argc--
c350: 3b 0a 09 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a  ;..argv++;.../*.
c360: 09 20 2a 20 53 65 74 20 61 70 70 72 6f 70 72 69  . * Set appropri
c370: 61 74 65 20 75 6d 61 73 6b 0a 09 20 2a 2f 0a 09  ate umask.. */..
c380: 75 6d 61 73 6b 28 30 32 32 29 3b 0a 0a 09 2f 2a  umask(022);.../*
c390: 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20  .. * Set global 
c3a0: 76 61 72 69 61 62 6c 65 73 2c 20 74 68 65 73 65  variables, these
c3b0: 20 73 68 6f 75 6c 64 20 62 65 20 63 6f 6e 66 69   should be confi
c3c0: 67 75 72 61 74 69 6f 6e 20 6f 70 74 69 6f 6e 73  guration options
c3d0: 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61  ... */..appfs_ca
c3e0: 63 68 65 64 69 72 20 3d 20 41 50 50 46 53 5f 43  chedir = APPFS_C
c3f0: 41 43 48 45 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20  ACHEDIR;.../*.. 
c400: 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72  * Set global var
c410: 69 61 62 6c 65 20 66 6f 72 20 22 62 6f 6f 74 20  iable for "boot 
c420: 74 69 6d 65 22 20 74 6f 20 73 65 74 20 61 20 74  time" to set a t
c430: 69 6d 65 20 6f 6e 20 64 69 72 65 63 74 6f 72 69  ime on directori
c440: 65 73 0a 09 20 2a 20 74 68 61 74 20 77 65 20 66  es.. * that we f
c450: 61 6b 65 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73  ake... */..appfs
c460: 5f 62 6f 6f 74 74 69 6d 65 20 3d 20 74 69 6d 65  _boottime = time
c470: 28 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a  (NULL);.../*.. *
c480: 20 52 65 67 69 73 74 65 72 20 22 73 68 61 31 22   Register "sha1"
c490: 20 61 6e 64 20 22 61 70 70 66 73 64 22 20 70 61   and "appfsd" pa
c4a0: 63 6b 61 67 65 20 77 69 74 68 20 6c 69 62 74 63  ckage with libtc
c4b0: 6c 20 73 6f 20 74 68 61 74 20 61 6e 79 20 6e 65  l so that any ne
c4c0: 77 0a 09 20 2a 20 69 6e 74 65 72 70 72 65 74 65  w.. * interprete
c4d0: 72 73 20 63 72 65 61 74 65 64 20 28 77 68 69 63  rs created (whic
c4e0: 68 20 61 72 65 20 64 6f 6e 65 20 64 79 6e 61 6d  h are done dynam
c4f0: 69 63 61 6c 6c 79 20 62 79 20 46 55 53 45 29 20  ically by FUSE) 
c500: 63 61 6e 20 68 61 76 65 0a 09 20 2a 20 74 68 65  can have.. * the
c510: 20 61 70 70 72 6f 70 72 69 61 74 65 20 63 6f 6e   appropriate con
c520: 66 69 67 75 72 61 74 69 6f 6e 20 64 6f 6e 65 20  figuration done 
c530: 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 09  automatically...
c540: 20 2a 2f 0a 09 54 63 6c 5f 53 74 61 74 69 63 50   */..Tcl_StaticP
c550: 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 73 68  ackage(NULL, "sh
c560: 61 31 22 2c 20 53 68 61 31 5f 49 6e 69 74 2c 20  a1", Sha1_Init, 
c570: 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 53 74 61 74  NULL);..Tcl_Stat
c580: 69 63 50 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20  icPackage(NULL, 
c590: 22 61 70 70 66 73 64 22 2c 20 41 70 70 66 73 64  "appfsd", Appfsd
c5a0: 5f 49 6e 69 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09  _Init, NULL);...
c5b0: 2f 2a 0a 09 20 2a 20 43 72 65 61 74 65 20 61 20  /*.. * Create a 
c5c0: 74 68 72 65 61 64 2d 73 70 65 63 69 66 69 63 2d  thread-specific-
c5d0: 64 61 74 61 20 28 54 53 44 29 20 6b 65 79 20 66  data (TSD) key f
c5e0: 6f 72 20 65 61 63 68 20 74 68 72 65 61 64 20 74  or each thread t
c5f0: 6f 20 72 65 66 65 72 0a 09 20 2a 20 74 6f 20 69  o refer.. * to i
c600: 74 73 20 6f 77 6e 20 54 63 6c 20 69 6e 74 65 72  ts own Tcl inter
c610: 70 72 65 74 65 72 2e 20 20 54 63 6c 20 69 6e 74  preter.  Tcl int
c620: 65 72 70 72 65 74 65 72 73 20 6d 75 73 74 20 62  erpreters must b
c630: 65 20 75 6e 69 71 75 65 20 70 65 72 0a 09 20 2a  e unique per.. *
c640: 20 74 68 72 65 61 64 20 61 6e 64 20 6e 65 77 20   thread and new 
c650: 74 68 72 65 61 64 73 20 61 72 65 20 64 79 6e 61  threads are dyna
c660: 6d 69 63 61 6c 6c 79 20 63 72 65 61 74 65 64 20  mically created 
c670: 62 79 20 46 55 53 45 2e 0a 09 20 2a 2f 0a 09 70  by FUSE... */..p
c680: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68  thread_ret = pth
c690: 72 65 61 64 5f 6b 65 79 5f 63 72 65 61 74 65 28  read_key_create(
c6a0: 26 69 6e 74 65 72 70 4b 65 79 2c 20 61 70 70 66  &interpKey, appf
c6b0: 73 5f 74 65 72 6d 69 6e 61 74 65 5f 69 6e 74 65  s_terminate_inte
c6c0: 72 70 5f 61 6e 64 5f 74 68 72 65 61 64 29 3b 0a  rp_and_thread);.
c6d0: 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74  .if (pthread_ret
c6e0: 20 21 3d 20 30 29 20 7b 0a 09 09 66 70 72 69 6e   != 0) {...fprin
c6f0: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
c700: 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54 53 44  le to create TSD
c710: 20 6b 65 79 20 66 6f 72 20 54 63 6c 2e 20 20 41   key for Tcl.  A
c720: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09  borting.\n");...
c730: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a  .return(1);..}..
c740: 09 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61 6c 6c 79  ./*.. * Manually
c750: 20 73 70 65 63 69 66 79 20 63 61 63 68 65 20 64   specify cache d
c760: 69 72 65 63 74 6f 72 79 2c 20 77 69 74 68 6f 75  irectory, withou
c770: 74 20 46 55 53 45 20 63 61 6c 6c 62 61 63 6b 0a  t FUSE callback.
c780: 09 20 2a 20 54 68 69 73 20 6f 70 74 69 6f 6e 20  . * This option 
c790: 6f 6e 6c 79 20 77 6f 72 6b 73 20 77 68 65 6e 20  only works when 
c7a0: 6e 6f 74 20 75 73 69 6e 67 20 46 55 53 45 2c 20  not using FUSE, 
c7b0: 73 69 6e 63 65 20 77 65 0a 09 20 2a 20 64 6f 20  since we.. * do 
c7c0: 6e 6f 74 20 70 72 6f 63 65 73 73 20 69 74 20 77  not process it w
c7d0: 69 74 68 20 46 55 53 45 73 20 6f 70 74 69 6f 6e  ith FUSEs option
c7e0: 20 70 72 6f 63 65 73 73 69 6e 67 2e 0a 09 20 2a   processing... *
c7f0: 2f 0a 09 69 66 20 28 61 72 67 63 20 3e 3d 20 32  /..if (argc >= 2
c800: 29 20 7b 0a 09 09 69 66 20 28 73 74 72 63 6d 70  ) {...if (strcmp
c810: 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 63 61 63  (argv[0], "--cac
c820: 68 65 64 69 72 22 29 20 3d 3d 20 30 29 20 7b 0a  hedir") == 0) {.
c830: 09 09 09 61 70 70 66 73 5f 63 61 63 68 65 64 69  ...appfs_cachedi
c840: 72 20 3d 20 73 74 72 64 75 70 28 61 72 67 76 5b  r = strdup(argv[
c850: 31 5d 29 3b 0a 0a 09 09 09 61 72 67 63 20 2d 3d  1]);.....argc -=
c860: 20 32 3b 0a 09 09 09 61 72 67 76 20 2b 3d 20 32   2;....argv += 2
c870: 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  ;...}..}.../*.. 
c880: 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 2c 20  * SQLite3 mode, 
c890: 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77 20  for running raw 
c8a0: 53 51 4c 20 61 67 61 69 6e 73 74 20 74 68 65 20  SQL against the 
c8b0: 63 61 63 68 65 20 64 61 74 61 62 61 73 65 0a 09  cache database..
c8c0: 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d   */..if (argc ==
c8d0: 20 32 20 26 26 20 73 74 72 63 6d 70 28 61 72 67   2 && strcmp(arg
c8e0: 76 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69 74 65 33  v[0], "--sqlite3
c8f0: 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74  ") == 0) {...ret
c900: 75 72 6e 28 61 70 70 66 73 5f 73 71 6c 69 74 65  urn(appfs_sqlite
c910: 33 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a  3(argv[1]));..}.
c920: 0a 09 2f 2a 0a 09 20 2a 20 54 63 6c 20 6d 6f 64  ../*.. * Tcl mod
c930: 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72  e, for running r
c940: 61 77 20 54 63 6c 20 69 6e 20 74 68 65 20 73 61  aw Tcl in the sa
c950: 6d 65 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 41  me environment A
c960: 70 70 46 53 64 20 77 6f 75 6c 64 0a 09 20 2a 20  ppFSd would.. * 
c970: 72 75 6e 20 63 6f 64 65 2e 0a 09 20 2a 2f 0a 09  run code... */..
c980: 69 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26 26  if (argc == 2 &&
c990: 20 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c   strcmp(argv[0],
c9a0: 20 22 2d 2d 74 63 6c 22 29 20 3d 3d 20 30 29 20   "--tcl") == 0) 
c9b0: 7b 0a 09 09 72 65 74 75 72 6e 28 61 70 70 66 73  {...return(appfs
c9c0: 5f 74 63 6c 28 61 72 67 76 5b 31 5d 29 29 3b 0a  _tcl(argv[1]));.
c9d0: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 67 69  .}.../*.. * Regi
c9e0: 73 74 65 72 20 61 20 73 69 67 6e 61 6c 20 68 61  ster a signal ha
c9f0: 6e 64 6c 65 72 20 66 6f 72 20 68 6f 74 2d 72 65  ndler for hot-re
ca00: 73 74 61 72 74 20 72 65 71 75 65 73 74 73 0a 09  start requests..
ca10: 20 2a 2f 0a 09 73 69 67 6e 61 6c 5f 72 65 74 20   */..signal_ret 
ca20: 3d 20 73 69 67 6e 61 6c 28 53 49 47 48 55 50 2c  = signal(SIGHUP,
ca30: 20 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f 68 61   appfs_signal_ha
ca40: 6e 64 6c 65 72 29 3b 0a 09 69 66 20 28 73 69 67  ndler);..if (sig
ca50: 6e 61 6c 5f 72 65 74 20 3d 3d 20 53 49 47 5f 45  nal_ret == SIG_E
ca60: 52 52 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28  RR) {...fprintf(
ca70: 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20  stderr, "Unable 
ca80: 74 6f 20 69 6e 73 74 61 6c 6c 20 73 69 67 6e 61  to install signa
ca90: 6c 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 68 6f  l handler for ho
caa0: 74 2d 72 65 73 74 61 72 74 5c 6e 22 29 3b 0a 09  t-restart\n");..
cab0: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
cac0: 20 22 48 6f 74 2d 72 65 73 74 61 72 74 20 77 69   "Hot-restart wi
cad0: 6c 6c 20 6e 6f 74 20 62 65 20 61 76 61 69 6c 61  ll not be availa
cae0: 62 6c 65 2e 5c 6e 22 29 3b 0a 09 7d 0a 0a 09 2f  ble.\n");..}.../
caf0: 2a 0a 09 20 2a 20 50 61 72 73 65 20 63 6f 6d 6d  *.. * Parse comm
cb00: 61 6e 64 20 6c 69 6e 65 20 61 72 67 75 6d 65 6e  and line argumen
cb10: 74 73 0a 09 20 2a 2f 0a 09 2f 2a 2a 0a 09 20 2a  ts.. */../**.. *
cb20: 2a 20 52 65 73 74 6f 72 65 20 61 72 67 63 2f 61  * Restore argc/a
cb30: 72 67 76 20 74 6f 20 6f 72 69 67 69 6e 61 6c 20  rgv to original 
cb40: 76 61 6c 75 65 73 2c 20 72 65 70 6c 61 63 69 6e  values, replacin
cb50: 67 20 61 72 67 76 5b 30 5d 20 69 6e 20 63 61 73  g argv[0] in cas
cb60: 65 0a 09 20 2a 2a 20 69 74 20 77 61 73 20 6d 6f  e.. ** it was mo
cb70: 69 66 69 65 64 20 62 79 20 2d 2d 63 61 63 68 65  ified by --cache
cb80: 64 69 72 20 6f 70 74 69 6f 6e 2e 0a 09 20 2a 2a  dir option... **
cb90: 2f 0a 09 61 72 67 63 2b 2b 3b 0a 09 61 72 67 76  /..argc++;..argv
cba0: 2d 2d 3b 0a 09 61 72 67 76 5b 30 5d 20 3d 20 61  --;..argv[0] = a
cbb0: 72 67 76 30 3b 0a 0a 09 2f 2a 2a 0a 09 20 2a 2a  rgv0;.../**.. **
cbc0: 20 50 65 72 66 6f 72 6d 20 74 68 65 20 61 72 67   Perform the arg
cbd0: 75 6d 65 6e 74 20 70 61 72 73 69 6e 67 0a 09 20  ument parsing.. 
cbe0: 2a 2a 2f 0a 09 61 6f 70 5f 72 65 74 20 3d 20 61  **/..aop_ret = a
cbf0: 70 70 66 73 5f 6f 70 74 5f 70 61 72 73 65 28 61  ppfs_opt_parse(a
cc00: 72 67 63 2c 20 61 72 67 76 2c 20 26 61 72 67 73  rgc, argv, &args
cc10: 29 3b 0a 09 69 66 20 28 61 6f 70 5f 72 65 74 20  );..if (aop_ret 
cc20: 21 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 61 6f  != 0) {...if (ao
cc30: 70 5f 72 65 74 20 3c 20 30 29 20 7b 0a 09 09 09  p_ret < 0) {....
cc40: 72 65 74 75 72 6e 28 30 29 3b 0a 09 09 7d 0a 0a  return(0);...}..
cc50: 09 09 72 65 74 75 72 6e 28 61 6f 70 5f 72 65 74  ..return(aop_ret
cc60: 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43  );..}.../*.. * C
cc70: 72 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65  reate a Tcl inte
cc80: 72 70 72 65 74 65 72 20 6a 75 73 74 20 74 6f 20  rpreter just to 
cc90: 76 65 72 69 66 79 20 74 68 61 74 20 74 68 69 6e  verify that thin
cca0: 67 73 20 61 72 65 20 69 6e 20 77 6f 72 6b 69 6e  gs are in workin
ccb0: 67 20 0a 09 20 2a 20 6f 72 64 65 72 20 62 65 66  g .. * order bef
ccc0: 6f 72 65 20 77 65 20 62 65 63 6f 6d 65 20 61 20  ore we become a 
ccd0: 64 61 65 6d 6f 6e 2e 0a 09 20 2a 2f 0a 09 74 65  daemon... */..te
cce0: 73 74 5f 69 6e 74 65 72 70 20 3d 20 61 70 70 66  st_interp = appf
ccf0: 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65  s_create_TclInte
cd00: 72 70 28 26 74 65 73 74 5f 69 6e 74 65 72 70 5f  rp(&test_interp_
cd10: 65 72 72 6f 72 29 3b 0a 09 69 66 20 28 74 65 73  error);..if (tes
cd20: 74 5f 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c  t_interp == NULL
cd30: 29 20 7b 0a 09 09 69 66 20 28 74 65 73 74 5f 69  ) {...if (test_i
cd40: 6e 74 65 72 70 5f 65 72 72 6f 72 20 3d 3d 20 4e  nterp_error == N
cd50: 55 4c 4c 29 20 7b 0a 09 09 09 74 65 73 74 5f 69  ULL) {....test_i
cd60: 6e 74 65 72 70 5f 65 72 72 6f 72 20 3d 20 22 55  nterp_error = "U
cd70: 6e 6b 6e 6f 77 6e 20 65 72 72 6f 72 22 3b 0a 09  nknown error";..
cd80: 09 7d 0a 0a 09 09 66 70 72 69 6e 74 66 28 73 74  .}....fprintf(st
cd90: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f  derr, "Unable to
cda0: 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20   initialize Tcl 
cdb0: 69 6e 74 65 72 70 72 65 74 65 72 20 66 6f 72 20  interpreter for 
cdc0: 41 70 70 46 53 64 3a 5c 6e 22 29 3b 0a 09 09 66  AppFSd:\n");...f
cdd0: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
cde0: 25 73 5c 6e 22 2c 20 74 65 73 74 5f 69 6e 74 65  %s\n", test_inte
cdf0: 72 70 5f 65 72 72 6f 72 29 3b 0a 0a 09 09 72 65  rp_error);....re
ce00: 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 54 63  turn(1);..}...Tc
ce10: 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 74  l_DeleteInterp(t
ce20: 65 73 74 5f 69 6e 74 65 72 70 29 3b 0a 0a 09 69  est_interp);...i
ce30: 66 20 28 61 70 70 66 73 5f 74 68 72 65 61 64 65  f (appfs_threade
ce40: 64 5f 74 63 6c 29 20 7b 0a 09 09 54 63 6c 5f 46  d_tcl) {...Tcl_F
ce50: 69 6e 61 6c 69 7a 65 4e 6f 74 69 66 69 65 72 28  inalizeNotifier(
ce60: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  NULL);..}.../*..
ce70: 20 2a 20 45 6e 74 65 72 20 74 68 65 20 46 55 53   * Enter the FUS
ce80: 45 20 6d 61 69 6e 20 6c 6f 6f 70 20 2d 2d 20 74  E main loop -- t
ce90: 68 69 73 20 77 69 6c 6c 20 70 72 6f 63 65 73 73  his will process
cea0: 20 61 6e 79 20 61 72 67 75 6d 65 6e 74 73 0a 09   any arguments..
ceb0: 20 2a 20 61 6e 64 20 73 74 61 72 74 20 73 65 72   * and start ser
cec0: 76 69 63 69 6e 67 20 72 65 71 75 65 73 74 73 2e  vicing requests.
ced0: 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 66 75 73  .. */..appfs_fus
cee0: 65 5f 73 74 61 72 74 65 64 20 3d 20 31 3b 0a 09  e_started = 1;..
cef0: 72 65 74 75 72 6e 28 66 75 73 65 5f 6d 61 69 6e  return(fuse_main
cf00: 28 61 72 67 73 2e 61 72 67 63 2c 20 61 72 67 73  (args.argc, args
cf10: 2e 61 72 67 76 2c 20 26 61 70 70 66 73 5f 6f 70  .argv, &appfs_op
cf20: 65 72 61 74 69 6f 6e 73 2c 20 4e 55 4c 4c 29 29  erations, NULL))
cf30: 3b 0a 7d 0a                                      ;.}.