Hex Artifact Content

Artifact 59919e0d2e3e58ceb4295fd46eda50d3dd80ffe4:


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: 72 65 74 76 61 6c 20 2b 3d 20 75 69 64 3b 0a 0a  retval += uid;..
3cc0: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
3cd0: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 61 63 68 65 20  .}../*. * Cache 
3ce0: 47 65 74 20 50 61 74 68 20 49 6e 66 6f 20 6c 6f  Get Path Info lo
3cf0: 6f 6b 75 70 73 20 66 6f 72 20 73 70 65 65 64 0a  okups for speed.
3d00: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61   */.static int a
3d10: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
3d20: 66 6f 5f 63 61 63 68 65 5f 67 65 74 28 63 6f 6e  fo_cache_get(con
3d30: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 75  st char *path, u
3d40: 69 64 5f 74 20 75 69 64 2c 20 73 74 72 75 63 74  id_t uid, struct
3d50: 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20   appfs_pathinfo 
3d60: 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 75 6e  *pathinfo) {..un
3d70: 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68 5f  signed int hash_
3d80: 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 61  idx;..int pthrea
3d90: 64 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65 74 76  d_ret;..int retv
3da0: 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 31  al;...retval = 1
3db0: 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20  ;...pthread_ret 
3dc0: 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  = pthread_mutex_
3dd0: 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68  lock(&appfs_path
3de0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65  _info_cache_mute
3df0: 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64  x);..if (pthread
3e00: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41  _ret != 0) {...A
3e10: 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62  PPFS_DEBUG("Unab
3e20: 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f  le to lock path_
3e30: 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78  info cache mutex
3e40: 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28   !");....return(
3e50: 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70  -1);..}...if (ap
3e60: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
3e70: 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  che != NULL) {..
3e80: 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61 70 70  .hash_idx = (app
3e90: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64  fs_get_path_inod
3ea0: 65 28 70 61 74 68 2c 20 75 69 64 29 29 20 25 20  e(path, uid)) % 
3eb0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
3ec0: 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 09 69  cache_size;....i
3ed0: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
3ee0: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
3ef0: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21  x]._cache_path !
3f00: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 69 66 20  = NULL) {....if 
3f10: 28 73 74 72 63 6d 70 28 61 70 70 66 73 5f 70 61  (strcmp(appfs_pa
3f20: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61  th_info_cache[ha
3f30: 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70  sh_idx]._cache_p
3f40: 61 74 68 2c 20 70 61 74 68 29 20 3d 3d 20 30 20  ath, path) == 0 
3f50: 26 26 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  && appfs_path_in
3f60: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
3f70: 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64 20 3d 3d  x]._cache_uid ==
3f80: 20 75 69 64 29 20 7b 0a 09 09 09 09 72 65 74 76   uid) {.....retv
3f90: 61 6c 20 3d 20 30 3b 0a 0a 09 09 09 09 6d 65 6d  al = 0;......mem
3fa0: 63 70 79 28 70 61 74 68 69 6e 66 6f 2c 20 26 61  cpy(pathinfo, &a
3fb0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
3fc0: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2c 20  ache[hash_idx], 
3fd0: 73 69 7a 65 6f 66 28 2a 70 61 74 68 69 6e 66 6f  sizeof(*pathinfo
3fe0: 29 29 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f  ));.....pathinfo
3ff0: 2d 3e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20  ->_cache_path = 
4000: 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09  NULL;....}...}..
4010: 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20  }...pthread_ret 
4020: 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  = pthread_mutex_
4030: 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61  unlock(&appfs_pa
4040: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75  th_info_cache_mu
4050: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65  tex);..if (pthre
4060: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
4070: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
4080: 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70  able to unlock p
4090: 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d  ath_info cache m
40a0: 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74  utex !");....ret
40b0: 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66  urn(-1);..}...if
40c0: 20 28 72 65 74 76 61 6c 20 3d 3d 20 30 29 20 7b   (retval == 0) {
40d0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
40e0: 43 61 63 68 65 20 68 69 74 20 6f 6e 20 25 73 22  Cache hit on %s"
40f0: 2c 20 70 61 74 68 29 3b 0a 09 7d 20 65 6c 73 65  , path);..} else
4100: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
4110: 28 22 43 61 63 68 65 20 6d 69 73 73 20 6f 6e 20  ("Cache miss on 
4120: 25 73 22 2c 20 70 61 74 68 29 3b 0a 09 7d 0a 0a  %s", path);..}..
4130: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
4140: 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
4150: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
4160: 6e 66 6f 5f 63 61 63 68 65 5f 61 64 64 28 63 6f  nfo_cache_add(co
4170: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
4180: 75 69 64 5f 74 20 75 69 64 2c 20 73 74 72 75 63  uid_t uid, struc
4190: 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f  t appfs_pathinfo
41a0: 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 75   *pathinfo) {..u
41b0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68  nsigned int hash
41c0: 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65  _idx;..int pthre
41d0: 61 64 5f 72 65 74 3b 0a 0a 09 70 74 68 72 65 61  ad_ret;...pthrea
41e0: 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f  d_ret = pthread_
41f0: 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66  mutex_lock(&appf
4200: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4210: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70  e_mutex);..if (p
4220: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
4230: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
4240: 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b  ("Unable to lock
4250: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65   path_info cache
4260: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72   mutex !");....r
4270: 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28  eturn;..}...if (
4280: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4290: 63 61 63 68 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b  cache == NULL) {
42a0: 0a 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  ...appfs_path_in
42b0: 66 6f 5f 63 61 63 68 65 20 3d 20 63 61 6c 6c 6f  fo_cache = callo
42c0: 63 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  c(appfs_path_inf
42d0: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 2c 20 73 69  o_cache_size, si
42e0: 7a 65 6f 66 28 2a 61 70 70 66 73 5f 70 61 74 68  zeof(*appfs_path
42f0: 5f 69 6e 66 6f 5f 63 61 63 68 65 29 29 3b 0a 09  _info_cache));..
4300: 7d 0a 0a 09 68 61 73 68 5f 69 64 78 20 3d 20 28  }...hash_idx = (
4310: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
4320: 6e 6f 64 65 28 70 61 74 68 2c 20 75 69 64 29 29  node(path, uid))
4330: 20 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e   % appfs_path_in
4340: 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a  fo_cache_size;..
4350: 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f  .if (appfs_path_
4360: 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f  info_cache[hash_
4370: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68  idx]._cache_path
4380: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 72   != NULL) {...fr
4390: 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  ee(appfs_path_in
43a0: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
43b0: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 29 3b  x]._cache_path);
43c0: 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79 28 26 61 70  ..}...memcpy(&ap
43d0: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
43e0: 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2c 20 70  che[hash_idx], p
43f0: 61 74 68 69 6e 66 6f 2c 20 73 69 7a 65 6f 66 28  athinfo, sizeof(
4400: 2a 70 61 74 68 69 6e 66 6f 29 29 3b 0a 0a 09 61  *pathinfo));...a
4410: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4420: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f  ache[hash_idx]._
4430: 63 61 63 68 65 5f 70 61 74 68 20 3d 20 73 74 72  cache_path = str
4440: 64 75 70 28 70 61 74 68 29 3b 0a 09 61 70 70 66  dup(path);..appf
4450: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4460: 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63  e[hash_idx]._cac
4470: 68 65 5f 75 69 64 20 20 3d 20 75 69 64 3b 0a 0a  he_uid  = uid;..
4480: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
4490: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c  thread_mutex_unl
44a0: 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f  ock(&appfs_path_
44b0: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
44c0: 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f  );..if (pthread_
44d0: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ret != 0) {...AP
44e0: 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c  PFS_DEBUG("Unabl
44f0: 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68  e to unlock path
4500: 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65  _info cache mute
4510: 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  x !");....return
4520: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d  ;..}...return;.}
4530: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  ..static void ap
4540: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
4550: 6f 5f 63 61 63 68 65 5f 72 6d 28 63 6f 6e 73 74  o_cache_rm(const
4560: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 75 69 64   char *path, uid
4570: 5f 74 20 75 69 64 29 20 7b 0a 09 75 6e 73 69 67  _t uid) {..unsig
4580: 6e 65 64 20 69 6e 74 20 68 61 73 68 5f 69 64 78  ned int hash_idx
4590: 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72  ;..int pthread_r
45a0: 65 74 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65  et;...pthread_re
45b0: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65  t = pthread_mute
45c0: 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61  x_lock(&appfs_pa
45d0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75  th_info_cache_mu
45e0: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65  tex);..if (pthre
45f0: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
4600: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
4610: 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74  able to lock pat
4620: 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74  h_info cache mut
4630: 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72  ex !");....retur
4640: 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66  n;..}...if (appf
4650: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4660: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68  e != NULL) {...h
4670: 61 73 68 5f 69 64 78 20 3d 20 28 61 70 70 66 73  ash_idx = (appfs
4680: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28  _get_path_inode(
4690: 70 61 74 68 2c 20 75 69 64 29 29 20 25 20 61 70  path, uid)) % ap
46a0: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
46b0: 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 09 69 66 20  che_size;....if 
46c0: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  (appfs_path_info
46d0: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d  _cache[hash_idx]
46e0: 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20  ._cache_path != 
46f0: 4e 55 4c 4c 29 20 7b 0a 09 09 09 66 72 65 65 28  NULL) {....free(
4700: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4710: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
4720: 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a 0a 09  _cache_path);...
4730: 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  ..appfs_path_inf
4740: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78  o_cache[hash_idx
4750: 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20  ]._cache_path = 
4760: 4e 55 4c 4c 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 70  NULL;...}..}...p
4770: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68  thread_ret = pth
4780: 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63  read_mutex_unloc
4790: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  k(&appfs_path_in
47a0: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b  fo_cache_mutex);
47b0: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
47c0: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  t != 0) {...APPF
47d0: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20  S_DEBUG("Unable 
47e0: 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69  to unlock path_i
47f0: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20  nfo cache mutex 
4800: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a  !");....return;.
4810: 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a  .}...return;.}..
4820: 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66  static void appf
4830: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
4840: 63 61 63 68 65 5f 66 6c 75 73 68 28 75 69 64 5f  cache_flush(uid_
4850: 74 20 75 69 64 2c 20 69 6e 74 20 6e 65 77 5f 73  t uid, int new_s
4860: 69 7a 65 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64  ize) {..unsigned
4870: 20 69 6e 74 20 69 64 78 3b 0a 09 69 6e 74 20 70   int idx;..int p
4880: 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 41 50  thread_ret;...AP
4890: 50 46 53 5f 44 45 42 55 47 28 22 46 6c 75 73 68  PFS_DEBUG("Flush
48a0: 69 6e 67 20 41 70 70 46 53 20 63 61 63 68 65 20  ing AppFS cache 
48b0: 28 75 69 64 20 3d 20 25 6c 6c 69 2c 20 6e 65 77  (uid = %lli, new
48c0: 5f 73 69 7a 65 20 3d 20 25 69 29 22 2c 20 28 6c  _size = %i)", (l
48d0: 6f 6e 67 20 6c 6f 6e 67 29 20 75 69 64 2c 20 6e  ong long) uid, n
48e0: 65 77 5f 73 69 7a 65 29 3b 0a 0a 09 70 74 68 72  ew_size);...pthr
48f0: 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61  ead_ret = pthrea
4900: 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70  d_mutex_lock(&ap
4910: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4920: 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20  che_mutex);..if 
4930: 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20  (pthread_ret != 
4940: 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  0) {...APPFS_DEB
4950: 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f  UG("Unable to lo
4960: 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63  ck path_info cac
4970: 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09  he mutex !");...
4980: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66  .return;..}...if
4990: 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66   (appfs_path_inf
49a0: 6f 5f 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29  o_cache != NULL)
49b0: 20 7b 0a 09 09 66 6f 72 20 28 69 64 78 20 3d 20   {...for (idx = 
49c0: 30 3b 20 69 64 78 20 3c 20 61 70 70 66 73 5f 70  0; idx < appfs_p
49d0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73  ath_info_cache_s
49e0: 69 7a 65 3b 20 69 64 78 2b 2b 29 20 7b 0a 09 09  ize; idx++) {...
49f0: 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f  .if (appfs_path_
4a00: 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e  info_cache[idx].
4a10: 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e  _cache_path != N
4a20: 55 4c 4c 29 20 7b 0a 09 09 09 09 69 66 20 28 75  ULL) {.....if (u
4a30: 69 64 20 21 3d 20 28 28 75 69 64 5f 74 29 20 2d  id != ((uid_t) -
4a40: 31 29 29 20 7b 0a 09 09 09 09 09 69 66 20 28 61  1)) {......if (a
4a50: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4a60: 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65  ache[idx]._cache
4a70: 5f 75 69 64 20 21 3d 20 75 69 64 29 20 7b 0a 09  _uid != uid) {..
4a80: 09 09 09 09 09 63 6f 6e 74 69 6e 75 65 3b 0a 09  .....continue;..
4a90: 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09  ....}.....}.....
4aa0: 09 66 72 65 65 28 61 70 70 66 73 5f 70 61 74 68  .free(appfs_path
4ab0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d  _info_cache[idx]
4ac0: 2e 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a 0a  ._cache_path);..
4ad0: 09 09 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69  ....appfs_path_i
4ae0: 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f  nfo_cache[idx]._
4af0: 63 61 63 68 65 5f 70 61 74 68 20 3d 20 4e 55 4c  cache_path = NUL
4b00: 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a 0a  L;....}...}..}..
4b10: 09 69 66 20 28 75 69 64 20 3d 3d 20 28 28 75 69  .if (uid == ((ui
4b20: 64 5f 74 29 20 2d 31 29 29 20 7b 0a 09 09 66 72  d_t) -1)) {...fr
4b30: 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  ee(appfs_path_in
4b40: 66 6f 5f 63 61 63 68 65 29 3b 0a 0a 09 09 61 70  fo_cache);....ap
4b50: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4b60: 63 68 65 20 3d 20 4e 55 4c 4c 3b 0a 0a 09 09 69  che = NULL;....i
4b70: 66 20 28 6e 65 77 5f 73 69 7a 65 20 21 3d 20 2d  f (new_size != -
4b80: 31 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 70 61  1) {....appfs_pa
4b90: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69  th_info_cache_si
4ba0: 7a 65 20 3d 20 6e 65 77 5f 73 69 7a 65 3b 0a 09  ze = new_size;..
4bb0: 09 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f  .}..}...pthread_
4bc0: 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75  ret = pthread_mu
4bd0: 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66  tex_unlock(&appf
4be0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4bf0: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70  e_mutex);..if (p
4c00: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
4c10: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
4c20: 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f  ("Unable to unlo
4c30: 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63  ck path_info cac
4c40: 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09  he mutex !");...
4c50: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65  .return;..}...re
4c60: 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20 47 65 74 20  turn;.}../* Get 
4c70: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75  information abou
4c80: 74 20 61 20 70 61 74 68 2c 20 61 6e 64 20 6f 70  t a path, and op
4c90: 74 69 6f 6e 61 6c 6c 79 20 6c 69 73 74 20 63 68  tionally list ch
4ca0: 69 6c 64 72 65 6e 20 2a 2f 0a 73 74 61 74 69 63  ildren */.static
4cb0: 20 69 6e 74 20 61 70 70 66 73 5f 67 65 74 5f 70   int appfs_get_p
4cc0: 61 74 68 5f 69 6e 66 6f 28 63 6f 6e 73 74 20 63  ath_info(const c
4cd0: 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63  har *path, struc
4ce0: 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f  t appfs_pathinfo
4cf0: 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 54   *pathinfo) {..T
4d00: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
4d10: 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 61 74 74  p;..Tcl_Obj *att
4d20: 72 73 5f 64 69 63 74 2c 20 2a 61 74 74 72 5f 76  rs_dict, *attr_v
4d30: 61 6c 75 65 3b 0a 09 63 6f 6e 73 74 20 63 68 61  alue;..const cha
4d40: 72 20 2a 61 74 74 72 5f 76 61 6c 75 65 5f 73 74  r *attr_value_st
4d50: 72 2c 20 2a 61 74 74 72 5f 76 61 6c 75 65 5f 73  r, *attr_value_s
4d60: 74 72 5f 69 3b 0a 09 54 63 6c 5f 57 69 64 65 49  tr_i;..Tcl_WideI
4d70: 6e 74 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69  nt attr_value_wi
4d80: 64 65 3b 0a 09 69 6e 74 20 61 74 74 72 5f 76 61  de;..int attr_va
4d90: 6c 75 65 5f 69 6e 74 3b 0a 09 73 74 61 74 69 63  lue_int;..static
4da0: 20 5f 5f 74 68 72 65 61 64 20 54 63 6c 5f 4f 62   __thread Tcl_Ob
4db0: 6a 20 2a 61 74 74 72 5f 6b 65 79 5f 74 79 70 65  j *attr_key_type
4dc0: 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b   = NULL, *attr_k
4dd0: 65 79 5f 70 65 72 6d 73 20 3d 20 4e 55 4c 4c 2c  ey_perms = NULL,
4de0: 20 2a 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 20   *attr_key_size 
4df0: 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65  = NULL, *attr_ke
4e00: 79 5f 74 69 6d 65 20 3d 20 4e 55 4c 4c 2c 20 2a  y_time = NULL, *
4e10: 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65 20  attr_key_source 
4e20: 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65  = NULL, *attr_ke
4e30: 79 5f 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 4e  y_childcount = N
4e40: 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 70  ULL, *attr_key_p
4e50: 61 63 6b 61 67 65 64 20 3d 20 4e 55 4c 4c 3b 0a  ackaged = NULL;.
4e60: 09 69 6e 74 20 63 61 63 68 65 5f 72 65 74 3b 0a  .int cache_ret;.
4e70: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 09 69  .int tcl_ret;..i
4e80: 6e 74 20 72 65 74 76 61 6c 3b 0a 09 75 69 64 5f  nt retval;..uid_
4e90: 74 20 66 73 75 69 64 3b 0a 0a 09 72 65 74 76 61  t fsuid;...retva
4ea0: 6c 20 3d 20 30 3b 0a 0a 09 66 73 75 69 64 20 3d  l = 0;...fsuid =
4eb0: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
4ec0: 28 29 3b 0a 0a 09 63 61 63 68 65 5f 72 65 74 20  ();...cache_ret 
4ed0: 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  = appfs_get_path
4ee0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28  _info_cache_get(
4ef0: 70 61 74 68 2c 20 66 73 75 69 64 2c 20 70 61 74  path, fsuid, pat
4f00: 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 63 61 63  hinfo);..if (cac
4f10: 68 65 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09  he_ret == 0) {..
4f20: 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2d 3e 74  .if (pathinfo->t
4f30: 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50 41 54  ype == APPFS_PAT
4f40: 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45  HTYPE_DOES_NOT_E
4f50: 58 49 53 54 29 20 7b 0a 09 09 09 41 50 50 46 53  XIST) {....APPFS
4f60: 5f 44 45 42 55 47 28 22 52 65 74 75 72 6e 69 6e  _DEBUG("Returnin
4f70: 67 20 66 72 6f 6d 20 63 61 63 68 65 3a 20 64 6f  g from cache: do
4f80: 65 73 20 6e 6f 74 20 65 78 69 73 74 20 5c 22 25  es not exist \"%
4f90: 73 5c 22 22 2c 20 70 61 74 68 29 3b 0a 0a 09 09  s\"", path);....
4fa0: 09 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29  .return(-ENOENT)
4fb0: 3b 0a 09 09 7d 0a 0a 09 09 69 66 20 28 70 61 74  ;...}....if (pat
4fc0: 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d 20 41  hinfo->type == A
4fd0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e  PPFS_PATHTYPE_IN
4fe0: 56 41 4c 49 44 29 20 7b 0a 09 09 09 41 50 50 46  VALID) {....APPF
4ff0: 53 5f 44 45 42 55 47 28 22 52 65 74 75 72 6e 69  S_DEBUG("Returni
5000: 6e 67 20 66 72 6f 6d 20 63 61 63 68 65 3a 20 69  ng from cache: i
5010: 6e 76 61 6c 69 64 20 6f 62 6a 65 63 74 20 5c 22  nvalid object \"
5020: 25 73 5c 22 22 2c 20 70 61 74 68 29 3b 0a 0a 09  %s\"", path);...
5030: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
5040: 09 09 7d 0a 0a 09 09 72 65 74 75 72 6e 28 30 29  ..}....return(0)
5050: 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72 70 20 3d 20  ;..}...interp = 
5060: 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28  appfs_TclInterp(
5070: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  );..if (interp =
5080: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46  = NULL) {...APPF
5090: 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20  S_DEBUG("error: 
50a0: 55 6e 61 62 6c 65 20 74 6f 20 67 65 74 20 61 6e  Unable to get an
50b0: 20 69 6e 74 65 72 70 72 65 74 65 72 22 29 3b 0a   interpreter");.
50c0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
50d0: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..}...appfs_call
50e0: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73  _libtcl(Tcl_Pres
50f0: 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  erve(interp);)..
5100: 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73  .tcl_ret = appfs
5110: 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70  _Tcl_Eval(interp
5120: 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67  , 2, "::appfs::g
5130: 65 74 61 74 74 72 22 2c 20 70 61 74 68 29 3b 0a  etattr", path);.
5140: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
5150: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
5160: 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73  S_DEBUG("::appfs
5170: 3a 3a 67 65 74 61 74 74 72 28 25 73 29 20 66 61  ::getattr(%s) fa
5180: 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09  iled.", path);..
5190: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
51a0: 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42  cl(....APPFS_DEB
51b0: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
51c0: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
51d0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
51e0: 70 29 29 3b 0a 09 09 29 0a 0a 09 09 70 61 74 68  p));...)....path
51f0: 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50  info->type = APP
5200: 46 53 5f 50 41 54 48 54 59 50 45 5f 44 4f 45 53  FS_PATHTYPE_DOES
5210: 5f 4e 4f 54 5f 45 58 49 53 54 3b 0a 0a 09 09 61  _NOT_EXIST;....a
5220: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
5230: 66 6f 5f 63 61 63 68 65 5f 61 64 64 28 70 61 74  fo_cache_add(pat
5240: 68 2c 20 66 73 75 69 64 2c 20 70 61 74 68 69 6e  h, fsuid, pathin
5250: 66 6f 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61  fo);....appfs_ca
5260: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
5270: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
5280: 0a 09 09 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e  ...return(-ENOEN
5290: 54 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74  T);..}...if (att
52a0: 72 5f 6b 65 79 5f 74 79 70 65 20 3d 3d 20 4e 55  r_key_type == NU
52b0: 4c 4c 29 20 7b 0a 09 09 61 70 70 66 73 5f 63 61  LL) {...appfs_ca
52c0: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 61 74  ll_libtcl(....at
52d0: 74 72 5f 6b 65 79 5f 74 79 70 65 20 20 20 20 20  tr_key_type     
52e0: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e    = Tcl_NewStrin
52f0: 67 4f 62 6a 28 22 74 79 70 65 22 2c 20 2d 31 29  gObj("type", -1)
5300: 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 70 65  ;....attr_key_pe
5310: 72 6d 73 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e  rms      = Tcl_N
5320: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 70 65 72  ewStringObj("per
5330: 6d 73 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74  ms", -1);....att
5340: 72 5f 6b 65 79 5f 73 69 7a 65 20 20 20 20 20 20  r_key_size      
5350: 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67   = Tcl_NewString
5360: 4f 62 6a 28 22 73 69 7a 65 22 2c 20 2d 31 29 3b  Obj("size", -1);
5370: 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 74 69 6d  ....attr_key_tim
5380: 65 20 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65  e       = Tcl_Ne
5390: 77 53 74 72 69 6e 67 4f 62 6a 28 22 74 69 6d 65  wStringObj("time
53a0: 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f  ", -1);....attr_
53b0: 6b 65 79 5f 73 6f 75 72 63 65 20 20 20 20 20 3d  key_source     =
53c0: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
53d0: 6a 28 22 73 6f 75 72 63 65 22 2c 20 2d 31 29 3b  j("source", -1);
53e0: 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 63 68 69  ....attr_key_chi
53f0: 6c 64 63 6f 75 6e 74 20 3d 20 54 63 6c 5f 4e 65  ldcount = Tcl_Ne
5400: 77 53 74 72 69 6e 67 4f 62 6a 28 22 63 68 69 6c  wStringObj("chil
5410: 64 63 6f 75 6e 74 22 2c 20 2d 31 29 3b 0a 09 09  dcount", -1);...
5420: 09 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67  .attr_key_packag
5430: 65 64 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74  ed   = Tcl_NewSt
5440: 72 69 6e 67 4f 62 6a 28 22 70 61 63 6b 61 67 65  ringObj("package
5450: 64 22 2c 20 2d 31 29 3b 0a 0a 09 09 09 54 63 6c  d", -1);.....Tcl
5460: 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74  _IncrRefCount(at
5470: 74 72 5f 6b 65 79 5f 74 79 70 65 29 3b 0a 09 09  tr_key_type);...
5480: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
5490: 74 28 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73  t(attr_key_perms
54a0: 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65  );....Tcl_IncrRe
54b0: 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f  fCount(attr_key_
54c0: 73 69 7a 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e  size);....Tcl_In
54d0: 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f  crRefCount(attr_
54e0: 6b 65 79 5f 74 69 6d 65 29 3b 0a 09 09 09 54 63  key_time);....Tc
54f0: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61  l_IncrRefCount(a
5500: 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65 29 3b  ttr_key_source);
5510: 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43  ....Tcl_IncrRefC
5520: 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 63 68  ount(attr_key_ch
5530: 69 6c 64 63 6f 75 6e 74 29 3b 0a 09 09 09 54 63  ildcount);....Tc
5540: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61  l_IncrRefCount(a
5550: 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64  ttr_key_packaged
5560: 29 3b 0a 09 09 29 0a 09 7d 0a 0a 09 61 70 70 66  );...)..}...appf
5570: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
5580: 09 61 74 74 72 73 5f 64 69 63 74 20 3d 20 54 63  .attrs_dict = Tc
5590: 6c 5f 47 65 74 4f 62 6a 52 65 73 75 6c 74 28 69  l_GetObjResult(i
55a0: 6e 74 65 72 70 29 3b 0a 09 09 74 63 6c 5f 72 65  nterp);...tcl_re
55b0: 74 20 3d 20 54 63 6c 5f 44 69 63 74 4f 62 6a 47  t = Tcl_DictObjG
55c0: 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73  et(interp, attrs
55d0: 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f  _dict, attr_key_
55e0: 74 79 70 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  type, &attr_valu
55f0: 65 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f  e);..)..if (tcl_
5600: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
5610: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
5620: 5b 64 69 63 74 20 67 65 74 20 5c 22 74 79 70 65  [dict get \"type
5630: 5c 22 5d 20 66 61 69 6c 65 64 22 29 3b 0a 09 09  \"] failed");...
5640: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
5650: 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55  l(....APPFS_DEBU
5660: 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  G("Tcl Error is:
5670: 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72   %s", Tcl_GetStr
5680: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
5690: 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73  ));...)....appfs
56a0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
56b0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
56c0: 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ;)....return(-EI
56d0: 4f 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74  O);..}...if (att
56e0: 72 5f 76 61 6c 75 65 20 3d 3d 20 4e 55 4c 4c 29  r_value == NULL)
56f0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
5700: 28 22 65 72 72 6f 72 3a 20 55 6e 61 62 6c 65 20  ("error: Unable 
5710: 74 6f 20 67 65 74 20 74 79 70 65 20 66 6f 72 20  to get type for 
5720: 5c 22 25 73 5c 22 20 66 72 6f 6d 20 54 63 6c 22  \"%s\" from Tcl"
5730: 2c 20 70 61 74 68 29 3b 0a 0a 09 09 61 70 70 66  , path);....appf
5740: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
5750: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
5760: 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45  );)....return(-E
5770: 49 4f 29 3b 0a 09 7d 0a 0a 09 70 61 74 68 69 6e  IO);..}...pathin
5780: 66 6f 2d 3e 70 61 63 6b 61 67 65 64 20 3d 20 30  fo->packaged = 0
5790: 3b 0a 09 70 61 74 68 69 6e 66 6f 2d 3e 69 6e 6f  ;..pathinfo->ino
57a0: 64 65 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 70  de = appfs_get_p
57b0: 61 74 68 5f 69 6e 6f 64 65 28 70 61 74 68 2c 20  ath_inode(path, 
57c0: 66 73 75 69 64 29 3b 0a 0a 09 61 70 70 66 73 5f  fsuid);...appfs_
57d0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 61  call_libtcl(...a
57e0: 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20  ttr_value_str = 
57f0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 61 74  Tcl_GetString(at
5800: 74 72 5f 76 61 6c 75 65 29 3b 0a 0a 09 09 73 77  tr_value);....sw
5810: 69 74 63 68 20 28 61 74 74 72 5f 76 61 6c 75 65  itch (attr_value
5820: 5f 73 74 72 5b 30 5d 29 20 7b 0a 09 09 09 63 61  _str[0]) {....ca
5830: 73 65 20 27 64 27 3a 20 2f 2a 20 64 69 72 65 63  se 'd': /* direc
5840: 74 6f 72 79 20 2a 2f 0a 09 09 09 09 70 61 74 68  tory */.....path
5850: 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50  info->type = APP
5860: 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45  FS_PATHTYPE_DIRE
5870: 43 54 4f 52 59 3b 0a 09 09 09 09 70 61 74 68 69  CTORY;.....pathi
5880: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64 69  nfo->typeinfo.di
5890: 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 30  r.childcount = 0
58a0: 3b 0a 0a 09 09 09 09 54 63 6c 5f 44 69 63 74 4f  ;......Tcl_DictO
58b0: 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74  bjGet(interp, at
58c0: 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b  trs_dict, attr_k
58d0: 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 2c 20 26  ey_childcount, &
58e0: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09  attr_value);....
58f0: 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20  .if (attr_value 
5900: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 09  != NULL) {......
5910: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65  tcl_ret = Tcl_Ge
5920: 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28  tWideIntFromObj(
5930: 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65  NULL, attr_value
5940: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69  , &attr_value_wi
5950: 64 65 29 3b 0a 09 09 09 09 09 69 66 20 28 74 63  de);......if (tc
5960: 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29  l_ret == TCL_OK)
5970: 20 7b 0a 09 09 09 09 09 09 70 61 74 68 69 6e 66   {.......pathinf
5980: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e  o->typeinfo.dir.
5990: 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 61 74 74  childcount = att
59a0: 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09  r_value_wide;...
59b0: 09 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 09  ...}.....}......
59c0: 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27  break;....case '
59d0: 66 27 3a 20 2f 2a 20 66 69 6c 65 20 2a 2f 0a 09  f': /* file */..
59e0: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
59f0: 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59  e = APPFS_PATHTY
5a00: 50 45 5f 46 49 4c 45 3b 0a 09 09 09 09 70 61 74  PE_FILE;.....pat
5a10: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
5a20: 66 69 6c 65 2e 73 69 7a 65 20 3d 20 30 3b 0a 09  file.size = 0;..
5a30: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
5a40: 65 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75  einfo.file.execu
5a50: 74 61 62 6c 65 20 3d 20 30 3b 0a 09 09 09 09 70  table = 0;.....p
5a60: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
5a70: 6f 2e 66 69 6c 65 2e 73 75 69 64 52 6f 6f 74 20  o.file.suidRoot 
5a80: 3d 20 30 3b 0a 09 09 09 09 70 61 74 68 69 6e 66  = 0;.....pathinf
5a90: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  o->typeinfo.file
5aa0: 2e 77 6f 72 6c 64 61 63 63 65 73 73 69 62 6c 65  .worldaccessible
5ab0: 20 3d 20 30 3b 0a 0a 09 09 09 09 54 63 6c 5f 44   = 0;......Tcl_D
5ac0: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
5ad0: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
5ae0: 74 72 5f 6b 65 79 5f 73 69 7a 65 2c 20 26 61 74  tr_key_size, &at
5af0: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09 69  tr_value);.....i
5b00: 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d  f (attr_value !=
5b10: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 09 74 63   NULL) {......tc
5b20: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 57  l_ret = Tcl_GetW
5b30: 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e 55  ideIntFromObj(NU
5b40: 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c 20  LL, attr_value, 
5b50: 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65  &attr_value_wide
5b60: 29 3b 0a 09 09 09 09 09 69 66 20 28 74 63 6c 5f  );......if (tcl_
5b70: 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret == TCL_OK) {
5b80: 0a 09 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  .......pathinfo-
5b90: 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73  >typeinfo.file.s
5ba0: 69 7a 65 20 3d 20 61 74 74 72 5f 76 61 6c 75 65  ize = attr_value
5bb0: 5f 77 69 64 65 3b 0a 09 09 09 09 09 7d 0a 09 09  _wide;......}...
5bc0: 09 09 7d 0a 0a 09 09 09 09 54 63 6c 5f 44 69 63  ..}......Tcl_Dic
5bd0: 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20  tObjGet(interp, 
5be0: 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72  attrs_dict, attr
5bf0: 5f 6b 65 79 5f 70 65 72 6d 73 2c 20 26 61 74 74  _key_perms, &att
5c00: 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09 69 66  r_value);.....if
5c10: 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20   (attr_value != 
5c20: 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 09 61 74 74  NULL) {......att
5c30: 72 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63  r_value_str = Tc
5c40: 6c 5f 47 65 74 53 74 72 69 6e 67 28 61 74 74 72  l_GetString(attr
5c50: 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09 09 66 6f  _value);......fo
5c60: 72 20 28 61 74 74 72 5f 76 61 6c 75 65 5f 73 74  r (attr_value_st
5c70: 72 5f 69 20 3d 20 26 61 74 74 72 5f 76 61 6c 75  r_i = &attr_valu
5c80: 65 5f 73 74 72 5b 30 5d 3b 20 2a 61 74 74 72 5f  e_str[0]; *attr_
5c90: 76 61 6c 75 65 5f 73 74 72 5f 69 20 21 3d 20 27  value_str_i != '
5ca0: 5c 30 27 3b 20 61 74 74 72 5f 76 61 6c 75 65 5f  \0'; attr_value_
5cb0: 73 74 72 5f 69 2b 2b 29 20 7b 0a 09 09 09 09 09  str_i++) {......
5cc0: 09 73 77 69 74 63 68 20 28 2a 61 74 74 72 5f 76  .switch (*attr_v
5cd0: 61 6c 75 65 5f 73 74 72 5f 69 29 20 7b 0a 09 09  alue_str_i) {...
5ce0: 09 09 09 09 09 63 61 73 65 20 27 78 27 3a 0a 09  .....case 'x':..
5cf0: 09 09 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  .......pathinfo-
5d00: 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 65  >typeinfo.file.e
5d10: 78 65 63 75 74 61 62 6c 65 20 3d 20 31 3b 0a 0a  xecutable = 1;..
5d20: 09 09 09 09 09 09 09 09 62 72 65 61 6b 3b 0a 09  ........break;..
5d30: 09 09 09 09 09 09 63 61 73 65 20 27 55 27 3a 0a  ......case 'U':.
5d40: 09 09 09 09 09 09 09 09 70 61 74 68 69 6e 66 6f  ........pathinfo
5d50: 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e  ->typeinfo.file.
5d60: 73 75 69 64 52 6f 6f 74 20 3d 20 31 3b 0a 0a 09  suidRoot = 1;...
5d70: 09 09 09 09 09 09 09 62 72 65 61 6b 3b 0a 09 09  .......break;...
5d80: 09 09 09 09 09 63 61 73 65 20 27 2d 27 3a 0a 09  .....case '-':..
5d90: 09 09 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  .......pathinfo-
5da0: 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 77  >typeinfo.file.w
5db0: 6f 72 6c 64 61 63 63 65 73 73 69 62 6c 65 20 3d  orldaccessible =
5dc0: 20 31 3b 0a 0a 09 09 09 09 09 09 09 09 62 72 65   1;..........bre
5dd0: 61 6b 3b 0a 09 09 09 09 09 09 7d 0a 09 09 09 09  ak;.......}.....
5de0: 09 7d 0a 09 09 09 09 7d 0a 09 09 09 09 62 72 65  .}.....}.....bre
5df0: 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 73 27 3a  ak;....case 's':
5e00: 20 2f 2a 20 73 79 6d 6c 69 6e 6b 20 2a 2f 0a 09   /* symlink */..
5e10: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
5e20: 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59  e = APPFS_PATHTY
5e30: 50 45 5f 53 59 4d 4c 49 4e 4b 3b 0a 09 09 09 09  PE_SYMLINK;.....
5e40: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
5e50: 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20  fo.symlink.size 
5e60: 3d 20 30 3b 0a 09 09 09 09 70 61 74 68 69 6e 66  = 0;.....pathinf
5e70: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c  o->typeinfo.syml
5e80: 69 6e 6b 2e 73 6f 75 72 63 65 5b 30 5d 20 3d 20  ink.source[0] = 
5e90: 27 5c 30 27 3b 0a 0a 09 09 09 09 54 63 6c 5f 44  '\0';......Tcl_D
5ea0: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
5eb0: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
5ec0: 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65 2c 20 26  tr_key_source, &
5ed0: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09  attr_value);....
5ee0: 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20  .if (attr_value 
5ef0: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 09  != NULL) {......
5f00: 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 20 3d  attr_value_str =
5f10: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 46 72   Tcl_GetStringFr
5f20: 6f 6d 4f 62 6a 28 61 74 74 72 5f 76 61 6c 75 65  omObj(attr_value
5f30: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e  , &attr_value_in
5f40: 74 29 3b 20 0a 0a 09 09 09 09 09 69 66 20 28 28  t); .......if ((
5f50: 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 20 2b  attr_value_int +
5f60: 20 31 29 20 3c 3d 20 73 69 7a 65 6f 66 28 70 61   1) <= sizeof(pa
5f70: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
5f80: 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29  .symlink.source)
5f90: 29 20 7b 0a 09 09 09 09 09 09 70 61 74 68 69 6e  ) {.......pathin
5fa0: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  fo->typeinfo.sym
5fb0: 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20 61 74 74 72  link.size = attr
5fc0: 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a 09 09 09 09  _value_int;.....
5fd0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
5fe0: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75  info.symlink.sou
5ff0: 72 63 65 5b 61 74 74 72 5f 76 61 6c 75 65 5f 69  rce[attr_value_i
6000: 6e 74 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09 09 09  nt] = '\0';.....
6010: 09 09 09 6d 65 6d 63 70 79 28 70 61 74 68 69 6e  ...memcpy(pathin
6020: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  fo->typeinfo.sym
6030: 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c 20 61 74 74  link.source, att
6040: 72 5f 76 61 6c 75 65 5f 73 74 72 2c 20 61 74 74  r_value_str, att
6050: 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 0a 09 09  r_value_int);...
6060: 09 09 09 7d 0a 09 09 09 09 7d 0a 09 09 09 09 62  ...}.....}.....b
6070: 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 46  reak;....case 'F
6080: 27 3a 20 2f 2a 20 70 69 70 65 2f 66 69 66 6f 20  ': /* pipe/fifo 
6090: 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  */.....pathinfo-
60a0: 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41  >type = APPFS_PA
60b0: 54 48 54 59 50 45 5f 46 49 46 4f 3b 0a 09 09 09  THTYPE_FIFO;....
60c0: 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20  .break;....case 
60d0: 27 53 27 3a 20 2f 2a 20 55 4e 49 58 20 64 6f 6d  'S': /* UNIX dom
60e0: 61 69 6e 20 73 6f 63 6b 65 74 20 2a 2f 0a 09 09  ain socket */...
60f0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
6100: 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50   = APPFS_PATHTYP
6110: 45 5f 53 4f 43 4b 45 54 3b 0a 09 09 09 09 62 72  E_SOCKET;.....br
6120: 65 61 6b 3b 0a 09 09 09 64 65 66 61 75 6c 74 3a  eak;....default:
6130: 0a 09 09 09 09 72 65 74 76 61 6c 20 3d 20 2d 45  .....retval = -E
6140: 49 4f 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44  IO;...}....Tcl_D
6150: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
6160: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
6170: 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 2c  tr_key_packaged,
6180: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
6190: 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20  .if (attr_value 
61a0: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 70 61  != NULL) {....pa
61b0: 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67 65 64  thinfo->packaged
61c0: 20 3d 20 31 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c   = 1;...}....Tcl
61d0: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
61e0: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
61f0: 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 2c 20 26  attr_key_time, &
6200: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 69  attr_value);...i
6210: 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d  f (attr_value !=
6220: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 74 63 6c 5f   NULL) {....tcl_
6230: 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 57 69 64  ret = Tcl_GetWid
6240: 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c  eIntFromObj(NULL
6250: 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c 20 26 61  , attr_value, &a
6260: 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 29 3b  ttr_value_wide);
6270: 0a 09 09 09 69 66 20 28 74 63 6c 5f 72 65 74 20  ....if (tcl_ret 
6280: 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09  == TCL_OK) {....
6290: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 69 6d 65 20  .pathinfo->time 
62a0: 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64  = attr_value_wid
62b0: 65 3b 0a 09 09 09 7d 0a 09 09 7d 20 65 6c 73 65  e;....}...} else
62c0: 20 7b 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e   {....pathinfo->
62d0: 74 69 6d 65 20 3d 20 61 70 70 66 73 5f 62 6f 6f  time = appfs_boo
62e0: 74 74 69 6d 65 3b 0a 09 09 7d 0a 0a 09 09 54 63  ttime;...}....Tc
62f0: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
6300: 29 3b 0a 09 29 0a 0a 09 69 66 20 28 72 65 74 76  );..)...if (retv
6310: 61 6c 20 3d 3d 20 30 29 20 7b 0a 09 09 61 70 70  al == 0) {...app
6320: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
6330: 5f 63 61 63 68 65 5f 61 64 64 28 70 61 74 68 2c  _cache_add(path,
6340: 20 66 73 75 69 64 2c 20 70 61 74 68 69 6e 66 6f   fsuid, pathinfo
6350: 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 41  );..} else {...A
6360: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
6370: 72 3a 20 49 6e 76 61 6c 69 64 20 74 79 70 65 20  r: Invalid type 
6380: 66 6f 72 20 5c 22 25 73 5c 22 20 66 72 6f 6d 20  for \"%s\" from 
6390: 54 63 6c 22 2c 20 70 61 74 68 29 3b 0a 09 7d 0a  Tcl", path);..}.
63a0: 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
63b0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61 72  ;.}..static char
63c0: 20 2a 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f   *appfs_prepare_
63d0: 74 6f 5f 63 72 65 61 74 65 28 63 6f 6e 73 74 20  to_create(const 
63e0: 63 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54  char *path) {..T
63f0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
6400: 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a  p;..const char *
6410: 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20  real_path;..int 
6420: 74 63 6c 5f 72 65 74 3b 0a 0a 09 61 70 70 66 73  tcl_ret;...appfs
6430: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
6440: 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73  ache_flush(appfs
6450: 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31  _get_fsuid(), -1
6460: 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  );...interp = ap
6470: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  pfs_TclInterp();
6480: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
6490: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
64a0: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70  (NULL);..}...app
64b0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
64c0: 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65  cl_Preserve(inte
64d0: 72 70 29 3b 29 0a 0a 09 61 70 70 66 73 5f 63 61  rp);)...appfs_ca
64e0: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c  ll_libtcl(...tcl
64f0: 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c  _ret = appfs_Tcl
6500: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c  _Eval(interp, 2,
6510: 20 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65 70 61   "::appfs::prepa
6520: 72 65 5f 74 6f 5f 63 72 65 61 74 65 22 2c 20 70  re_to_create", p
6530: 61 74 68 29 3b 0a 09 29 0a 09 69 66 20 28 74 63  ath);..)..if (tc
6540: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
6550: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
6560: 28 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65 70 61  ("::appfs::prepa
6570: 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 25 73 29  re_to_create(%s)
6580: 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29   failed.", path)
6590: 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ;...appfs_call_l
65a0: 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f  ibtcl(....APPFS_
65b0: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72  DEBUG("Tcl Error
65c0: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
65d0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
65e0: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61  terp));...)....a
65f0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
6600: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
6610: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e  erp);)....return
6620: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70  (NULL);..}...app
6630: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
6640: 09 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63  ..real_path = Tc
6650: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
6660: 74 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09  t(interp);..)...
6670: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
6680: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
6690: 74 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72 65  terp);)...if (re
66a0: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
66b0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c   {...return(NULL
66c0: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 73  );..}...return(s
66d0: 74 72 64 75 70 28 72 65 61 6c 5f 70 61 74 68 29  trdup(real_path)
66e0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61  );.}..static cha
66f0: 72 20 2a 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61  r *appfs_localpa
6700: 74 68 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  th(const char *p
6710: 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  ath) {..Tcl_Inte
6720: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e  rp *interp;..con
6730: 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 61  st char *real_pa
6740: 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  th;..int tcl_ret
6750: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  ;...interp = app
6760: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a  fs_TclInterp();.
6770: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
6780: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
6790: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  NULL);..}...appf
67a0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
67b0: 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72  l_Preserve(inter
67c0: 70 29 3b 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c  p);)...appfs_cal
67d0: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f  l_libtcl(...tcl_
67e0: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
67f0: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20  Eval(interp, 2, 
6800: 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63 61 6c 70  "::appfs::localp
6810: 61 74 68 22 2c 20 70 61 74 68 29 3b 0a 09 29 0a  ath", path);..).
6820: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
6830: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
6840: 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73  S_DEBUG("::appfs
6850: 3a 3a 6c 6f 63 61 6c 70 61 74 68 28 25 73 29 20  ::localpath(%s) 
6860: 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b  failed.", path);
6870: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
6880: 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44  btcl(....APPFS_D
6890: 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20  EBUG("Tcl Error 
68a0: 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74  is: %s", Tcl_Get
68b0: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
68c0: 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 72 65  erp));...)....re
68d0: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
68e0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
68f0: 63 6c 28 0a 09 09 72 65 61 6c 5f 70 61 74 68 20  cl(...real_path 
6900: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  = Tcl_GetStringR
6910: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09  esult(interp);..
6920: 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  )...appfs_call_l
6930: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
6940: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 69 66  e(interp);)...if
6950: 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e   (real_path == N
6960: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
6970: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  NULL);..}...retu
6980: 72 6e 28 73 74 72 64 75 70 28 72 65 61 6c 5f 70  rn(strdup(real_p
6990: 61 74 68 29 29 3b 0a 7d 0a 0a 23 69 66 20 28 64  ath));.}..#if (d
69a0: 65 66 69 6e 65 64 28 44 45 42 55 47 29 20 26 26  efined(DEBUG) &&
69b0: 20 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45   defined(APPFS_E
69c0: 58 49 54 5f 50 41 54 48 29 29 20 7c 7c 20 64 65  XIT_PATH)) || de
69d0: 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58 49 54  fined(APPFS_EXIT
69e0: 5f 50 41 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a  _PATH_ENABLE_MAJ
69f0: 4f 52 5f 53 45 43 55 52 49 54 59 5f 48 4f 4c 45  OR_SECURITY_HOLE
6a00: 29 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  ).static void ap
6a10: 70 66 73 5f 65 78 69 74 28 76 6f 69 64 29 20 7b  pfs_exit(void) {
6a20: 0a 09 69 6e 74 20 67 6c 6f 62 61 6c 5f 69 6e 74  ..int global_int
6a30: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 3b 0a 0a  erp_reset_key;..
6a40: 09 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72  .global_interp_r
6a50: 65 73 65 74 5f 6b 65 79 20 3d 20 5f 5f 73 79 6e  eset_key = __syn
6a60: 63 5f 66 65 74 63 68 5f 61 6e 64 5f 61 64 64 28  c_fetch_and_add(
6a70: 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65  &interp_reset_ke
6a80: 79 2c 20 30 29 3b 0a 09 5f 5f 73 79 6e 63 5f 66  y, 0);..__sync_f
6a90: 65 74 63 68 5f 61 6e 64 5f 73 75 62 28 26 69 6e  etch_and_sub(&in
6aa0: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20  terp_reset_key, 
6ab0: 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65  global_interp_re
6ac0: 73 65 74 5f 6b 65 79 29 3b 0a 0a 09 77 68 69 6c  set_key);...whil
6ad0: 65 20 28 5f 5f 73 79 6e 63 5f 73 75 62 5f 61 6e  e (__sync_sub_an
6ae0: 64 5f 66 65 74 63 68 28 26 69 6e 74 65 72 70 5f  d_fetch(&interp_
6af0: 72 65 73 65 74 5f 6b 65 79 2c 20 31 29 20 3e 3d  reset_key, 1) >=
6b00: 20 30 29 20 7b 0a 09 09 2f 2a 20 42 75 73 79 20   0) {.../* Busy 
6b10: 4c 6f 6f 70 20 2a 2f 0a 09 7d 0a 0a 09 67 6c 6f  Loop */..}...glo
6b20: 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74  bal_interp_reset
6b30: 5f 6b 65 79 20 3d 20 5f 5f 73 79 6e 63 5f 66 65  _key = __sync_fe
6b40: 74 63 68 5f 61 6e 64 5f 61 64 64 28 26 69 6e 74  tch_and_add(&int
6b50: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 30  erp_reset_key, 0
6b60: 29 3b 0a 09 69 66 20 28 67 6c 6f 62 61 6c 5f 69  );..if (global_i
6b70: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20  nterp_reset_key 
6b80: 21 3d 20 2d 31 29 20 7b 0a 09 09 41 50 50 46 53  != -1) {...APPFS
6b90: 5f 44 45 42 55 47 28 22 45 72 72 6f 72 20 73 65  _DEBUG("Error se
6ba0: 6e 64 69 6e 67 20 6b 69 6c 6c 20 73 69 67 6e 61  nding kill signa
6bb0: 6c 20 74 6f 20 61 6c 6c 20 74 68 72 65 61 64 73  l to all threads
6bc0: 2c 20 61 62 6f 72 74 69 6e 67 20 61 6e 79 77 61  , aborting anywa
6bd0: 79 2e 22 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  y.");..}...appfs
6be0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
6bf0: 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c 20 2d  ache_flush(-1, -
6c00: 31 29 3b 0a 0a 09 66 75 73 65 5f 65 78 69 74 28  1);...fuse_exit(
6c10: 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65 78 74  fuse_get_context
6c20: 28 29 2d 3e 66 75 73 65 29 3b 0a 0a 09 72 65 74  ()->fuse);...ret
6c30: 75 72 6e 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 73  urn;.}.#endif..s
6c40: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
6c50: 66 75 73 65 5f 72 65 61 64 6c 69 6e 6b 28 63 6f  fuse_readlink(co
6c60: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
6c70: 63 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f  char *buf, size_
6c80: 74 20 73 69 7a 65 29 20 7b 0a 09 73 74 72 75 63  t size) {..struc
6c90: 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f  t appfs_pathinfo
6ca0: 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69 6e 74 20   pathinfo;..int 
6cb0: 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 41 50  retval = 0;...AP
6cc0: 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72  PFS_DEBUG("Enter
6cd0: 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e   (path = %s, ...
6ce0: 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 70 61 74  )", path);...pat
6cf0: 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41 50 50  hinfo.type = APP
6d00: 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41  FS_PATHTYPE_INVA
6d10: 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  LID;...retval = 
6d20: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
6d30: 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69  nfo(path, &pathi
6d40: 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65 74 76 61  nfo);..if (retva
6d50: 6c 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  l != 0) {...retu
6d60: 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a  rn(retval);..}..
6d70: 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 74 79  .if (pathinfo.ty
6d80: 70 65 20 21 3d 20 41 50 50 46 53 5f 50 41 54 48  pe != APPFS_PATH
6d90: 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 29 20 7b 0a  TYPE_SYMLINK) {.
6da0: 09 09 72 65 74 75 72 6e 28 2d 45 49 4e 56 41 4c  ..return(-EINVAL
6db0: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 73 74 72  );..}...if ((str
6dc0: 6c 65 6e 28 70 61 74 68 69 6e 66 6f 2e 74 79 70  len(pathinfo.typ
6dd0: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f  einfo.symlink.so
6de0: 75 72 63 65 29 20 2b 20 31 29 20 3e 20 73 69 7a  urce) + 1) > siz
6df0: 65 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  e) {...return(-E
6e00: 4e 41 4d 45 54 4f 4f 4c 4f 4e 47 29 3b 0a 09 7d  NAMETOOLONG);..}
6e10: 0a 0a 09 6d 65 6d 63 70 79 28 62 75 66 2c 20 70  ...memcpy(buf, p
6e20: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
6e30: 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c  .symlink.source,
6e40: 20 73 74 72 6c 65 6e 28 70 61 74 68 69 6e 66 6f   strlen(pathinfo
6e50: 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e  .typeinfo.symlin
6e60: 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31 29 3b 0a  k.source) + 1);.
6e70: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
6e80: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
6e90: 5f 66 75 73 65 5f 67 65 74 61 74 74 72 28 63 6f  _fuse_getattr(co
6ea0: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
6eb0: 73 74 72 75 63 74 20 73 74 61 74 20 2a 73 74 62  struct stat *stb
6ec0: 75 66 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70  uf) {..struct ap
6ed0: 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74  pfs_pathinfo pat
6ee0: 68 69 6e 66 6f 3b 0a 09 69 6e 74 20 63 68 61 6e  hinfo;..int chan
6ef0: 67 65 4f 77 6e 65 72 54 6f 55 73 65 72 49 66 50  geOwnerToUserIfP
6f00: 61 63 6b 61 67 65 64 3b 0a 09 69 6e 74 20 72 65  ackaged;..int re
6f10: 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 3d  tval;...retval =
6f20: 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55   0;...APPFS_DEBU
6f30: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
6f40: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
6f50: 29 3b 0a 0a 23 69 66 20 28 64 65 66 69 6e 65 64  );..#if (defined
6f60: 28 44 45 42 55 47 29 20 26 26 20 64 65 66 69 6e  (DEBUG) && defin
6f70: 65 64 28 41 50 50 46 53 5f 45 58 49 54 5f 50 41  ed(APPFS_EXIT_PA
6f80: 54 48 29 29 20 7c 7c 20 64 65 66 69 6e 65 64 28  TH)) || defined(
6f90: 41 50 50 46 53 5f 45 58 49 54 5f 50 41 54 48 5f  APPFS_EXIT_PATH_
6fa0: 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f 53 45 43  ENABLE_MAJOR_SEC
6fb0: 55 52 49 54 59 5f 48 4f 4c 45 29 0a 09 2f 2a 0a  URITY_HOLE)../*.
6fc0: 09 20 2a 20 54 68 69 73 20 69 73 20 61 20 6d 61  . * This is a ma
6fd0: 6a 6f 72 20 73 65 63 75 72 69 74 79 20 69 73 73  jor security iss
6fe0: 75 65 20 73 6f 20 77 65 20 63 61 6e 6e 6f 74 20  ue so we cannot 
6ff0: 6c 65 74 20 69 74 20 62 65 20 63 6f 6d 70 69 6c  let it be compil
7000: 65 64 20 69 6e 74 6f 0a 09 20 2a 20 61 6e 79 20  ed into.. * any 
7010: 72 65 6c 65 61 73 65 0a 09 20 2a 2f 0a 0a 09 69  release.. */...i
7020: 66 20 28 73 74 72 63 6d 70 28 70 61 74 68 2c 20  f (strcmp(path, 
7030: 22 2f 65 78 69 74 22 29 20 3d 3d 20 30 29 20 7b  "/exit") == 0) {
7040: 0a 09 09 61 70 70 66 73 5f 65 78 69 74 28 29 3b  ...appfs_exit();
7050: 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 70 61 74  ..}.#endif...pat
7060: 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41 50 50  hinfo.type = APP
7070: 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41  FS_PATHTYPE_INVA
7080: 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  LID;...retval = 
7090: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
70a0: 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69  nfo(path, &pathi
70b0: 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65 74 76 61  nfo);..if (retva
70c0: 6c 20 21 3d 20 30 29 20 7b 0a 09 09 69 66 20 28  l != 0) {...if (
70d0: 72 65 74 76 61 6c 20 3d 3d 20 2d 45 4e 4f 45 4e  retval == -ENOEN
70e0: 54 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45  T) {....APPFS_DE
70f0: 42 55 47 28 22 67 65 74 5f 70 61 74 68 5f 69 6e  BUG("get_path_in
7100: 66 6f 20 72 65 74 75 72 6e 65 64 20 45 4e 4f 45  fo returned ENOE
7110: 4e 54 2c 20 72 65 74 75 72 6e 69 6e 67 20 69 74  NT, returning it
7120: 20 61 73 20 77 65 6c 6c 2e 22 29 3b 0a 09 09 7d   as well.");...}
7130: 20 65 6c 73 65 20 7b 0a 09 09 09 41 50 50 46 53   else {....APPFS
7140: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 67  _DEBUG("error: g
7150: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20 66 61 69  et_path_info fai
7160: 6c 65 64 22 29 3b 0a 09 09 7d 0a 0a 09 09 72 65  led");...}....re
7170: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d  turn(retval);..}
7180: 0a 0a 09 6d 65 6d 73 65 74 28 73 74 62 75 66 2c  ...memset(stbuf,
7190: 20 30 2c 20 73 69 7a 65 6f 66 28 73 74 72 75 63   0, sizeof(struc
71a0: 74 20 73 74 61 74 29 29 3b 0a 0a 09 73 74 62 75  t stat));...stbu
71b0: 66 2d 3e 73 74 5f 6d 74 69 6d 65 20 3d 20 70 61  f->st_mtime = pa
71c0: 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74  thinfo.time;..st
71d0: 62 75 66 2d 3e 73 74 5f 63 74 69 6d 65 20 3d 20  buf->st_ctime = 
71e0: 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09  pathinfo.time;..
71f0: 73 74 62 75 66 2d 3e 73 74 5f 61 74 69 6d 65 20  stbuf->st_atime 
7200: 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b  = pathinfo.time;
7210: 0a 09 73 74 62 75 66 2d 3e 73 74 5f 69 6e 6f 20  ..stbuf->st_ino 
7220: 20 20 3d 20 70 61 74 68 69 6e 66 6f 2e 69 6e 6f    = pathinfo.ino
7230: 64 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 6d  de;..stbuf->st_m
7240: 6f 64 65 20 20 3d 20 30 3b 0a 0a 09 63 68 61 6e  ode  = 0;...chan
7250: 67 65 4f 77 6e 65 72 54 6f 55 73 65 72 49 66 50  geOwnerToUserIfP
7260: 61 63 6b 61 67 65 64 20 3d 20 31 3b 0a 0a 09 73  ackaged = 1;...s
7270: 77 69 74 63 68 20 28 70 61 74 68 69 6e 66 6f 2e  witch (pathinfo.
7280: 74 79 70 65 29 20 7b 0a 09 09 63 61 73 65 20 41  type) {...case A
7290: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49  PPFS_PATHTYPE_DI
72a0: 52 45 43 54 4f 52 59 3a 0a 09 09 09 73 74 62 75  RECTORY:....stbu
72b0: 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49  f->st_mode = S_I
72c0: 46 44 49 52 20 7c 20 30 35 35 35 3b 0a 09 09 09  FDIR | 0555;....
72d0: 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20  stbuf->st_nlink 
72e0: 3d 20 32 20 2b 20 70 61 74 68 69 6e 66 6f 2e 74  = 2 + pathinfo.t
72f0: 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c  ypeinfo.dir.chil
7300: 64 63 6f 75 6e 74 3b 0a 09 09 09 62 72 65 61 6b  dcount;....break
7310: 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50  ;...case APPFS_P
7320: 41 54 48 54 59 50 45 5f 46 49 4c 45 3a 0a 09 09  ATHTYPE_FILE:...
7330: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
7340: 3d 20 53 5f 49 46 52 45 47 20 7c 20 30 34 34 34  = S_IFREG | 0444
7350: 3b 0a 0a 09 09 09 69 66 20 28 70 61 74 68 69 6e  ;.....if (pathin
7360: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  fo.typeinfo.file
7370: 2e 65 78 65 63 75 74 61 62 6c 65 29 20 7b 0a 09  .executable) {..
7380: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ...stbuf->st_mod
7390: 65 20 7c 3d 20 30 31 31 31 3b 0a 09 09 09 7d 0a  e |= 0111;....}.
73a0: 0a 09 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f  ....if (pathinfo
73b0: 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73  .typeinfo.file.s
73c0: 75 69 64 52 6f 6f 74 29 20 7b 0a 09 09 09 09 63  uidRoot) {.....c
73d0: 68 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65 72  hangeOwnerToUser
73e0: 49 66 50 61 63 6b 61 67 65 64 20 3d 20 30 3b 0a  IfPackaged = 0;.
73f0: 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d  .....stbuf->st_m
7400: 6f 64 65 20 7c 3d 20 30 34 30 30 30 3b 0a 09 09  ode |= 04000;...
7410: 09 7d 0a 0a 09 09 09 69 66 20 28 70 61 74 68 69  .}.....if (pathi
7420: 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  nfo.typeinfo.fil
7430: 65 2e 77 6f 72 6c 64 61 63 63 65 73 73 69 62 6c  e.worldaccessibl
7440: 65 29 20 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e  e) {.....stbuf->
7450: 73 74 5f 6d 6f 64 65 20 26 3d 20 7e 30 37 37 3b  st_mode &= ~077;
7460: 0a 09 09 09 7d 0a 0a 09 09 09 73 74 62 75 66 2d  ....}.....stbuf-
7470: 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09  >st_nlink = 1;..
7480: 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65  ..stbuf->st_size
7490: 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65   = pathinfo.type
74a0: 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 3b 0a  info.file.size;.
74b0: 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73  ....break;...cas
74c0: 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  e APPFS_PATHTYPE
74d0: 5f 53 59 4d 4c 49 4e 4b 3a 0a 09 09 09 73 74 62  _SYMLINK:....stb
74e0: 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f  uf->st_mode = S_
74f0: 49 46 4c 4e 4b 20 7c 20 30 35 35 35 3b 0a 09 09  IFLNK | 0555;...
7500: 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b  .stbuf->st_nlink
7510: 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e   = 1;....stbuf->
7520: 73 74 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e  st_size = pathin
7530: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c  fo.typeinfo.syml
7540: 69 6e 6b 2e 73 69 7a 65 3b 0a 09 09 09 62 72 65  ink.size;....bre
7550: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53  ak;...case APPFS
7560: 5f 50 41 54 48 54 59 50 45 5f 53 4f 43 4b 45 54  _PATHTYPE_SOCKET
7570: 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d  :....stbuf->st_m
7580: 6f 64 65 20 3d 20 53 5f 49 46 53 4f 43 4b 20 7c  ode = S_IFSOCK |
7590: 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d   0555;....stbuf-
75a0: 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09  >st_nlink = 1;..
75b0: 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65  ..stbuf->st_size
75c0: 20 3d 20 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a   = 0;....break;.
75d0: 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54  ..case APPFS_PAT
75e0: 48 54 59 50 45 5f 46 49 46 4f 3a 0a 09 09 09 73  HTYPE_FIFO:....s
75f0: 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20  tbuf->st_mode = 
7600: 53 5f 49 46 49 46 4f 20 7c 20 30 35 35 35 3b 0a  S_IFIFO | 0555;.
7610: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69  ...stbuf->st_nli
7620: 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66  nk = 1;....stbuf
7630: 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 30 3b 0a 09  ->st_size = 0;..
7640: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20  ..break;...case 
7650: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44  APPFS_PATHTYPE_D
7660: 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 3a 0a 09  OES_NOT_EXIST:..
7670: 09 09 72 65 74 76 61 6c 20 3d 20 2d 45 4e 4f 45  ..retval = -ENOE
7680: 4e 54 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a 09  NT;.....break;..
7690: 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48  .case APPFS_PATH
76a0: 54 59 50 45 5f 49 4e 56 41 4c 49 44 3a 0a 09 09  TYPE_INVALID:...
76b0: 09 72 65 74 76 61 6c 20 3d 20 2d 45 49 4f 3b 0a  .retval = -EIO;.
76c0: 0a 09 09 09 62 72 65 61 6b 3b 0a 09 7d 0a 0a 09  ....break;..}...
76d0: 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 70 61 63  if (pathinfo.pac
76e0: 6b 61 67 65 64 20 26 26 20 63 68 61 6e 67 65 4f  kaged && changeO
76f0: 77 6e 65 72 54 6f 55 73 65 72 49 66 50 61 63 6b  wnerToUserIfPack
7700: 61 67 65 64 29 20 7b 0a 09 09 73 74 62 75 66 2d  aged) {...stbuf-
7710: 3e 73 74 5f 75 69 64 20 20 20 3d 20 61 70 70 66  >st_uid   = appf
7720: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 09  s_get_fsuid();..
7730: 09 73 74 62 75 66 2d 3e 73 74 5f 67 69 64 20 20  .stbuf->st_gid  
7740: 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67   = appfs_get_fsg
7750: 69 64 28 29 3b 0a 09 09 73 74 62 75 66 2d 3e 73  id();...stbuf->s
7760: 74 5f 6d 6f 64 65 20 7c 3d 20 30 32 30 30 3b 0a  t_mode |= 0200;.
7770: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76  .}...return(retv
7780: 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  al);.}..static i
7790: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65  nt appfs_fuse_re
77a0: 61 64 64 69 72 28 63 6f 6e 73 74 20 63 68 61 72  addir(const char
77b0: 20 2a 70 61 74 68 2c 20 76 6f 69 64 20 2a 62 75   *path, void *bu
77c0: 66 2c 20 66 75 73 65 5f 66 69 6c 6c 5f 64 69 72  f, fuse_fill_dir
77d0: 5f 74 20 66 69 6c 6c 65 72 2c 20 6f 66 66 5f 74  _t filler, off_t
77e0: 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63 74 20   offset, struct 
77f0: 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a  fuse_file_info *
7800: 66 69 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  fi) {..Tcl_Inter
7810: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c 5f  p *interp;..Tcl_
7820: 4f 62 6a 20 2a 2a 63 68 69 6c 64 72 65 6e 3b 0a  Obj **children;.
7830: 09 69 6e 74 20 63 68 69 6c 64 72 65 6e 5f 63 6f  .int children_co
7840: 75 6e 74 2c 20 69 64 78 3b 0a 09 69 6e 74 20 74  unt, idx;..int t
7850: 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f  cl_ret;...APPFS_
7860: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
7870: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
7880: 70 61 74 68 29 3b 0a 0a 09 69 6e 74 65 72 70 20  path);...interp 
7890: 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72  = appfs_TclInter
78a0: 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  p();..if (interp
78b0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50   == NULL) {...AP
78c0: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
78d0: 3a 20 55 6e 61 62 6c 65 20 74 6f 20 67 65 74 20  : Unable to get 
78e0: 61 6e 20 69 6e 74 65 72 70 72 65 74 65 72 22 29  an interpreter")
78f0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a  ;....return(0);.
7900: 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .}...appfs_call_
7910: 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65  libtcl(Tcl_Prese
7920: 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  rve(interp);)...
7930: 66 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e 22 2c  filler(buf, ".",
7940: 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 66 69 6c 6c   NULL, 0);..fill
7950: 65 72 28 62 75 66 2c 20 22 2e 2e 22 2c 20 4e 55  er(buf, "..", NU
7960: 4c 4c 2c 20 30 29 3b 0a 0a 09 74 63 6c 5f 72 65  LL, 0);...tcl_re
7970: 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76  t = appfs_Tcl_Ev
7980: 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a  al(interp, 2, ":
7990: 3a 61 70 70 66 73 3a 3a 67 65 74 63 68 69 6c 64  :appfs::getchild
79a0: 72 65 6e 22 2c 20 70 61 74 68 29 3b 0a 09 69 66  ren", path);..if
79b0: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
79c0: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
79d0: 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67  EBUG("::appfs::g
79e0: 65 74 63 68 69 6c 64 72 65 6e 28 25 73 29 20 66  etchildren(%s) f
79f0: 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a  ailed.", path);.
7a00: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
7a10: 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45  tcl(....APPFS_DE
7a20: 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69  BUG("Tcl Error i
7a30: 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53  s: %s", Tcl_GetS
7a40: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
7a50: 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70  rp));...)....app
7a60: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
7a70: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
7a80: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 30  p);)....return(0
7a90: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61  );..}...appfs_ca
7aa0: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c  ll_libtcl(...tcl
7ab0: 5f 72 65 74 20 3d 20 54 63 6c 5f 4c 69 73 74 4f  _ret = Tcl_ListO
7ac0: 62 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e  bjGetElements(in
7ad0: 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 4f 62 6a  terp, Tcl_GetObj
7ae0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 20  Result(interp), 
7af0: 26 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c  &children_count,
7b00: 20 26 63 68 69 6c 64 72 65 6e 29 3b 0a 09 29 0a   &children);..).
7b10: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
7b20: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
7b30: 53 5f 44 45 42 55 47 28 22 50 61 72 73 69 6e 67  S_DEBUG("Parsing
7b40: 20 6c 69 73 74 20 6f 66 20 63 68 69 6c 64 72 65   list of childre
7b50: 6e 20 6f 6e 20 70 61 74 68 20 25 73 20 66 61 69  n on path %s fai
7b60: 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09  led.", path);...
7b70: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
7b80: 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55  l(....APPFS_DEBU
7b90: 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  G("Tcl Error is:
7ba0: 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72   %s", Tcl_GetStr
7bb0: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
7bc0: 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73  ));...)....appfs
7bd0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
7be0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
7bf0: 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b  ;)....return(0);
7c00: 0a 09 7d 0a 0a 09 66 6f 72 20 28 69 64 78 20 3d  ..}...for (idx =
7c10: 20 30 3b 20 69 64 78 20 3c 20 63 68 69 6c 64 72   0; idx < childr
7c20: 65 6e 5f 63 6f 75 6e 74 3b 20 69 64 78 2b 2b 29  en_count; idx++)
7c30: 20 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f   {...appfs_call_
7c40: 6c 69 62 74 63 6c 28 0a 09 09 09 66 69 6c 6c 65  libtcl(....fille
7c50: 72 28 62 75 66 2c 20 54 63 6c 5f 47 65 74 53 74  r(buf, Tcl_GetSt
7c60: 72 69 6e 67 28 63 68 69 6c 64 72 65 6e 5b 69 64  ring(children[id
7c70: 78 5d 29 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09  x]), NULL, 0);..
7c80: 09 29 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61  .)..}...appfs_ca
7c90: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
7ca0: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
7cb0: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
7cc0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
7cd0: 5f 66 75 73 65 5f 6f 70 65 6e 28 63 6f 6e 73 74  _fuse_open(const
7ce0: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72   char *path, str
7cf0: 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e  uct fuse_file_in
7d00: 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c 5f 49  fo *fi) {..Tcl_I
7d10: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09  nterp *interp;..
7d20: 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74  struct appfs_pat
7d30: 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a  hinfo pathinfo;.
7d40: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61  .const char *rea
7d50: 6c 5f 70 61 74 68 2c 20 2a 6d 6f 64 65 3b 0a 09  l_path, *mode;..
7d60: 69 6e 74 20 67 70 69 5f 72 65 74 2c 20 74 63 6c  int gpi_ret, tcl
7d70: 5f 72 65 74 3b 0a 09 69 6e 74 20 66 68 3b 0a 0a  _ret;..int fh;..
7d80: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
7d90: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
7da0: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09  ...)", path);...
7db0: 67 70 69 5f 72 65 74 20 3d 20 61 70 70 66 73 5f  gpi_ret = appfs_
7dc0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61  get_path_info(pa
7dd0: 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a  th, &pathinfo);.
7de0: 0a 09 69 66 20 28 28 66 69 2d 3e 66 6c 61 67 73  ..if ((fi->flags
7df0: 20 26 20 28 4f 5f 57 52 4f 4e 4c 59 7c 4f 5f 43   & (O_WRONLY|O_C
7e00: 52 45 41 54 29 29 20 3d 3d 20 28 4f 5f 43 52 45  REAT)) == (O_CRE
7e10: 41 54 7c 4f 5f 57 52 4f 4e 4c 59 29 29 20 7b 0a  AT|O_WRONLY)) {.
7e20: 09 09 2f 2a 20 54 68 65 20 66 69 6c 65 20 77 69  ../* The file wi
7e30: 6c 6c 20 62 65 20 63 72 65 61 74 65 64 20 69 66  ll be created if
7e40: 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 65 78 69   it does not exi
7e50: 73 74 20 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f  st */...if (gpi_
7e60: 72 65 74 20 21 3d 20 30 20 26 26 20 67 70 69 5f  ret != 0 && gpi_
7e70: 72 65 74 20 21 3d 20 2d 45 4e 4f 45 4e 54 29 20  ret != -ENOENT) 
7e80: 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  {....APPFS_DEBUG
7e90: 28 22 65 72 72 6f 72 3a 20 67 65 74 5f 70 61 74  ("error: get_pat
7ea0: 68 5f 69 6e 66 6f 20 66 61 69 6c 65 64 22 29 3b  h_info failed");
7eb0: 0a 0a 09 09 09 72 65 74 75 72 6e 28 67 70 69 5f  .....return(gpi_
7ec0: 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d 6f 64  ret);...}....mod
7ed0: 65 20 3d 20 22 63 72 65 61 74 65 22 3b 0a 0a 09  e = "create";...
7ee0: 09 2f 2a 0a 09 09 20 2a 20 57 65 20 68 61 76 65  ./*... * We have
7ef0: 20 74 6f 20 63 6c 65 61 72 20 74 68 65 20 63 61   to clear the ca
7f00: 63 68 65 20 68 65 72 65 20 73 6f 20 74 68 61 74  che here so that
7f10: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a 09   the number of..
7f20: 09 20 2a 20 6c 69 6e 6b 73 20 67 65 74 73 20 6d  . * links gets m
7f30: 61 69 6e 74 61 69 6e 65 64 20 6f 6e 20 74 68 65  aintained on the
7f40: 20 70 61 72 65 6e 74 20 64 69 72 65 63 74 6f 72   parent director
7f50: 79 0a 09 09 20 2a 2f 0a 09 09 61 70 70 66 73 5f  y... */...appfs_
7f60: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
7f70: 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73 5f  che_flush(appfs_
7f80: 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31 29  get_fsuid(), -1)
7f90: 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 2f 2a  ;..} else {.../*
7fa0: 20 54 68 65 20 66 69 6c 65 20 6d 75 73 74 20 61   The file must a
7fb0: 6c 72 65 61 64 79 20 65 78 69 73 74 20 2a 2f 0a  lready exist */.
7fc0: 09 09 69 66 20 28 67 70 69 5f 72 65 74 20 21 3d  ..if (gpi_ret !=
7fd0: 20 30 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44   0) {....APPFS_D
7fe0: 45 42 55 47 28 22 65 72 72 6f 72 3a 20 67 65 74  EBUG("error: get
7ff0: 5f 70 61 74 68 5f 69 6e 66 6f 20 66 61 69 6c 65  _path_info faile
8000: 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28  d");.....return(
8010: 67 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09  gpi_ret);...}...
8020: 09 6d 6f 64 65 20 3d 20 22 22 3b 0a 0a 09 09 69  .mode = "";....i
8030: 66 20 28 28 66 69 2d 3e 66 6c 61 67 73 20 26 20  f ((fi->flags & 
8040: 4f 5f 57 52 4f 4e 4c 59 29 20 3d 3d 20 4f 5f 57  O_WRONLY) == O_W
8050: 52 4f 4e 4c 59 29 20 7b 0a 09 09 09 6d 6f 64 65  RONLY) {....mode
8060: 20 3d 20 22 77 72 69 74 65 22 3b 0a 09 09 7d 0a   = "write";...}.
8070: 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66  .}...if (pathinf
8080: 6f 2e 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f  o.type == APPFS_
8090: 50 41 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f  PATHTYPE_DIRECTO
80a0: 52 59 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  RY) {...APPFS_DE
80b0: 42 55 47 28 22 65 72 72 6f 72 3a 20 41 73 6b 65  BUG("error: Aske
80c0: 64 20 74 6f 20 6f 70 65 6e 20 61 20 64 69 72 65  d to open a dire
80d0: 63 74 6f 72 79 2e 22 29 3b 0a 0a 09 09 72 65 74  ctory.");....ret
80e0: 75 72 6e 28 2d 45 49 53 44 49 52 29 3b 0a 09 7d  urn(-EISDIR);..}
80f0: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66  ...interp = appf
8100: 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09  s_TclInterp();..
8110: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
8120: 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  LL) {...APPFS_DE
8130: 42 55 47 28 22 65 72 72 6f 72 3a 20 55 6e 61 62  BUG("error: Unab
8140: 6c 65 20 74 6f 20 67 65 74 20 61 6e 20 69 6e 74  le to get an int
8150: 65 72 70 72 65 74 65 72 22 29 3b 0a 0a 09 09 72  erpreter");....r
8160: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
8170: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
8180: 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65  tcl(Tcl_Preserve
8190: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c  (interp);)...tcl
81a0: 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c  _ret = appfs_Tcl
81b0: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 33 2c  _Eval(interp, 3,
81c0: 20 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70   "::appfs::openp
81d0: 61 74 68 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65  ath", path, mode
81e0: 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  );..if (tcl_ret 
81f0: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41  != TCL_OK) {...A
8200: 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70  PPFS_DEBUG("::ap
8210: 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28 25 73  pfs::openpath(%s
8220: 2c 20 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20  , %s) failed.", 
8230: 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 09 09 61  path, mode);...a
8240: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
8250: 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  (....APPFS_DEBUG
8260: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20  ("Tcl Error is: 
8270: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  %s", Tcl_GetStri
8280: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
8290: 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f  );...)....appfs_
82a0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
82b0: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
82c0: 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f  )....return(-EIO
82d0: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61  );..}...appfs_ca
82e0: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 61  ll_libtcl(...rea
82f0: 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74  l_path = Tcl_Get
8300: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
8310: 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73  erp);..)...appfs
8320: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
8330: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
8340: 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61  ;)...if (real_pa
8350: 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th == NULL) {...
8360: 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72  APPFS_DEBUG("err
8370: 6f 72 3a 20 72 65 61 6c 5f 70 61 74 68 20 77 61  or: real_path wa
8380: 73 20 4e 55 4c 4c 2e 22 29 0a 0a 09 09 72 65 74  s NULL.")....ret
8390: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
83a0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 72 61  APPFS_DEBUG("Tra
83b0: 6e 73 6c 61 74 65 64 20 72 65 71 75 65 73 74 20  nslated request 
83c0: 74 6f 20 6f 70 65 6e 20 25 73 20 74 6f 20 6f 70  to open %s to op
83d0: 65 6e 69 6e 67 20 25 73 20 28 6d 6f 64 65 20 3d  ening %s (mode =
83e0: 20 5c 22 25 73 5c 22 29 22 2c 20 70 61 74 68 2c   \"%s\")", path,
83f0: 20 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65   real_path, mode
8400: 29 3b 0a 0a 09 66 68 20 3d 20 6f 70 65 6e 28 72  );...fh = open(r
8410: 65 61 6c 5f 70 61 74 68 2c 20 66 69 2d 3e 66 6c  eal_path, fi->fl
8420: 61 67 73 2c 20 30 36 30 30 29 3b 0a 0a 09 69 66  ags, 0600);...if
8430: 20 28 66 68 20 3c 20 30 29 20 7b 0a 09 09 41 50   (fh < 0) {...AP
8440: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
8450: 3a 20 6f 70 65 6e 20 66 61 69 6c 65 64 22 29 3b  : open failed");
8460: 0a 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f  ....return(errno
8470: 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66 69 2d   * -1);..}...fi-
8480: 3e 66 68 20 3d 20 66 68 3b 0a 0a 09 72 65 74 75  >fh = fh;...retu
8490: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn(0);.}..static
84a0: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
84b0: 63 6c 6f 73 65 28 63 6f 6e 73 74 20 63 68 61 72  close(const char
84c0: 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20 66   *path, struct f
84d0: 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66  use_file_info *f
84e0: 69 29 20 7b 0a 09 69 6e 74 20 63 6c 6f 73 65 5f  i) {..int close_
84f0: 72 65 74 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74  ret;...appfs_get
8500: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
8510: 5f 72 6d 28 70 61 74 68 2c 20 61 70 70 66 73 5f  _rm(path, appfs_
8520: 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09  get_fsuid());...
8530: 63 6c 6f 73 65 5f 72 65 74 20 3d 20 63 6c 6f 73  close_ret = clos
8540: 65 28 66 69 2d 3e 66 68 29 3b 0a 09 69 66 20 28  e(fi->fh);..if (
8550: 63 6c 6f 73 65 5f 72 65 74 20 21 3d 20 30 29 20  close_ret != 0) 
8560: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
8570: 22 65 72 72 6f 72 3a 20 63 6c 6f 73 65 20 66 61  "error: close fa
8580: 69 6c 65 64 22 29 3b 0a 0a 09 09 72 65 74 75 72  iled");....retur
8590: 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09  n(errno * -1);..
85a0: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  }...return(0);.}
85b0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
85c0: 66 73 5f 66 75 73 65 5f 72 65 61 64 28 63 6f 6e  fs_fuse_read(con
85d0: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 63  st char *path, c
85e0: 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74  har *buf, size_t
85f0: 20 73 69 7a 65 2c 20 6f 66 66 5f 74 20 6f 66 66   size, off_t off
8600: 73 65 74 2c 20 73 74 72 75 63 74 20 66 75 73 65  set, struct fuse
8610: 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20  _file_info *fi) 
8620: 7b 0a 09 73 73 69 7a 65 5f 74 20 72 65 61 64 5f  {..ssize_t read_
8630: 72 65 74 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c  ret;..int retval
8640: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
8650: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
8660: 73 2c 20 62 75 66 2c 20 25 6c 6c 69 2c 20 25 6c  s, buf, %lli, %l
8670: 6c 69 2c 20 66 64 3d 25 6c 6c 69 29 22 2c 20 70  li, fd=%lli)", p
8680: 61 74 68 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29  ath, (long long)
8690: 20 73 69 7a 65 2c 20 28 6c 6f 6e 67 20 6c 6f 6e   size, (long lon
86a0: 67 29 20 6f 66 66 73 65 74 2c 20 28 6c 6f 6e 67  g) offset, (long
86b0: 20 6c 6f 6e 67 29 20 66 69 2d 3e 66 68 29 3b 0a   long) fi->fh);.
86c0: 0a 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09  ..retval = 0;...
86d0: 77 68 69 6c 65 20 28 73 69 7a 65 20 21 3d 20 30  while (size != 0
86e0: 29 20 7b 0a 09 09 72 65 61 64 5f 72 65 74 20 3d  ) {...read_ret =
86f0: 20 70 72 65 61 64 28 66 69 2d 3e 66 68 2c 20 62   pread(fi->fh, b
8700: 75 66 2c 20 73 69 7a 65 2c 20 6f 66 66 73 65 74  uf, size, offset
8710: 29 3b 0a 0a 09 09 69 66 20 28 72 65 61 64 5f 72  );....if (read_r
8720: 65 74 20 3c 20 30 29 20 7b 0a 09 09 09 41 50 50  et < 0) {....APP
8730: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
8740: 20 72 65 61 64 20 66 61 69 6c 65 64 22 29 3b 0a   read failed");.
8750: 0a 09 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f  ....return(errno
8760: 20 2a 20 2d 31 29 3b 0a 09 09 7d 0a 0a 09 09 69   * -1);...}....i
8770: 66 20 28 72 65 61 64 5f 72 65 74 20 3d 3d 20 30  f (read_ret == 0
8780: 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09  ) {....break;...
8790: 7d 0a 0a 09 09 73 69 7a 65 20 2d 3d 20 72 65 61  }....size -= rea
87a0: 64 5f 72 65 74 3b 0a 09 09 62 75 66 20 20 2b 3d  d_ret;...buf  +=
87b0: 20 72 65 61 64 5f 72 65 74 3b 0a 09 09 6f 66 66   read_ret;...off
87c0: 73 65 74 20 2b 3d 20 72 65 61 64 5f 72 65 74 3b  set += read_ret;
87d0: 0a 09 09 72 65 74 76 61 6c 20 2b 3d 20 72 65 61  ...retval += rea
87e0: 64 5f 72 65 74 3b 0a 09 7d 0a 0a 09 69 66 20 28  d_ret;..}...if (
87f0: 73 69 7a 65 20 21 3d 20 30 29 20 7b 0a 09 09 41  size != 0) {...A
8800: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
8810: 72 3a 20 69 6e 63 6f 6d 70 6c 65 74 65 20 72 65  r: incomplete re
8820: 61 64 20 28 74 68 69 73 20 6d 69 67 68 74 20 62  ad (this might b
8830: 65 20 61 6e 20 65 72 72 6f 72 20 62 65 63 61 75  e an error becau
8840: 73 65 20 46 55 53 45 20 77 69 6c 6c 20 72 65 71  se FUSE will req
8850: 75 65 73 74 20 74 68 65 20 65 78 61 63 74 20 6c  uest the exact l
8860: 65 6e 67 74 68 20 6f 66 20 74 68 65 20 66 69 6c  ength of the fil
8870: 65 29 22 29 3b 0a 09 7d 0a 0a 09 41 50 50 46 53  e)");..}...APPFS
8880: 5f 44 45 42 55 47 28 22 52 65 74 75 72 6e 69 6e  _DEBUG("Returnin
8890: 67 3a 20 25 69 22 2c 20 72 65 74 76 61 6c 29 3b  g: %i", retval);
88a0: 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
88b0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
88c0: 20 61 70 70 66 73 5f 66 75 73 65 5f 77 72 69 74   appfs_fuse_writ
88d0: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  e(const char *pa
88e0: 74 68 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  th, const char *
88f0: 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65  buf, size_t size
8900: 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20  , off_t offset, 
8910: 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65  struct fuse_file
8920: 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 73 73  _info *fi) {..ss
8930: 69 7a 65 5f 74 20 77 72 69 74 65 5f 72 65 74 3b  ize_t write_ret;
8940: 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09  ..int retval;...
8950: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
8960: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
8970: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61  ..)", path);...a
8980: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
8990: 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68  fo_cache_rm(path
89a0: 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  , appfs_get_fsui
89b0: 64 28 29 29 3b 0a 0a 09 72 65 74 76 61 6c 20 3d  d());...retval =
89c0: 20 30 3b 0a 0a 09 77 68 69 6c 65 20 28 73 69 7a   0;...while (siz
89d0: 65 20 21 3d 20 30 29 20 7b 0a 09 09 77 72 69 74  e != 0) {...writ
89e0: 65 5f 72 65 74 20 3d 20 70 77 72 69 74 65 28 66  e_ret = pwrite(f
89f0: 69 2d 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a 65  i->fh, buf, size
8a00: 2c 20 6f 66 66 73 65 74 29 3b 0a 0a 09 09 69 66  , offset);....if
8a10: 20 28 77 72 69 74 65 5f 72 65 74 20 3c 20 30 29   (write_ret < 0)
8a20: 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55   {....APPFS_DEBU
8a30: 47 28 22 65 72 72 6f 72 3a 20 77 72 69 74 65 20  G("error: write 
8a40: 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09 09 72 65  failed");.....re
8a50: 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29  turn(errno * -1)
8a60: 3b 0a 09 09 7d 0a 0a 09 09 69 66 20 28 77 72 69  ;...}....if (wri
8a70: 74 65 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09  te_ret == 0) {..
8a80: 09 09 62 72 65 61 6b 3b 0a 09 09 7d 0a 0a 09 09  ..break;...}....
8a90: 73 69 7a 65 20 2d 3d 20 77 72 69 74 65 5f 72 65  size -= write_re
8aa0: 74 3b 0a 09 09 62 75 66 20 20 2b 3d 20 77 72 69  t;...buf  += wri
8ab0: 74 65 5f 72 65 74 3b 0a 09 09 6f 66 66 73 65 74  te_ret;...offset
8ac0: 20 2b 3d 20 77 72 69 74 65 5f 72 65 74 3b 0a 09   += write_ret;..
8ad0: 09 72 65 74 76 61 6c 20 2b 3d 20 77 72 69 74 65  .retval += write
8ae0: 5f 72 65 74 3b 0a 09 7d 0a 0a 09 69 66 20 28 73  _ret;..}...if (s
8af0: 69 7a 65 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ize != 0) {...AP
8b00: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
8b10: 3a 20 69 6e 63 6f 6d 70 6c 65 74 65 20 77 72 69  : incomplete wri
8b20: 74 65 22 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  te");..}...retur
8b30: 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74  n(retval);.}..st
8b40: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
8b50: 75 73 65 5f 6d 6b 6e 6f 64 28 63 6f 6e 73 74 20  use_mknod(const 
8b60: 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65  char *path, mode
8b70: 5f 74 20 6d 6f 64 65 2c 20 64 65 76 5f 74 20 64  _t mode, dev_t d
8b80: 65 76 69 63 65 29 20 7b 0a 09 63 68 61 72 20 2a  evice) {..char *
8b90: 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20  real_path;..int 
8ba0: 6d 6b 6e 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50  mknod_ret;...APP
8bb0: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
8bc0: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
8bd0: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69 66 20 28  ", path);...if (
8be0: 28 6d 6f 64 65 20 26 20 53 5f 49 46 43 48 52 29  (mode & S_IFCHR)
8bf0: 20 3d 3d 20 53 5f 49 46 43 48 52 29 20 7b 0a 09   == S_IFCHR) {..
8c00: 09 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b  .return(-EPERM);
8c10: 0a 09 7d 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20  ..}...if ((mode 
8c20: 26 20 53 5f 49 46 42 4c 4b 29 20 3d 3d 20 53 5f  & S_IFBLK) == S_
8c30: 49 46 42 4c 4b 29 20 7b 0a 09 09 72 65 74 75 72  IFBLK) {...retur
8c40: 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09  n(-EPERM);..}...
8c50: 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66  real_path = appf
8c60: 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65  s_prepare_to_cre
8c70: 61 74 65 28 70 61 74 68 29 3b 0a 09 69 66 20 28  ate(path);..if (
8c80: 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c  real_path == NUL
8c90: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  L) {...return(-E
8ca0: 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  IO);..}...appfs_
8cb0: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
8cc0: 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b 6e 6f  _enter();...mkno
8cd0: 64 5f 72 65 74 20 3d 20 6d 6b 6e 6f 64 28 72 65  d_ret = mknod(re
8ce0: 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 2c 20 64  al_path, mode, d
8cf0: 65 76 69 63 65 29 3b 0a 0a 09 61 70 70 66 73 5f  evice);...appfs_
8d00: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
8d10: 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65  _leave();...free
8d20: 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69  (real_path);...i
8d30: 66 20 28 6d 6b 6e 6f 64 5f 72 65 74 20 21 3d 20  f (mknod_ret != 
8d40: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72  0) {...return(er
8d50: 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09  rno * -1);..}...
8d60: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74  return(0);.}..st
8d70: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
8d80: 75 73 65 5f 63 72 65 61 74 65 28 63 6f 6e 73 74  use_create(const
8d90: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64   char *path, mod
8da0: 65 5f 74 20 6d 6f 64 65 2c 20 73 74 72 75 63 74  e_t mode, struct
8db0: 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20   fuse_file_info 
8dc0: 2a 66 69 29 20 7b 0a 09 63 68 61 72 20 2a 72 65  *fi) {..char *re
8dd0: 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 66 64  al_path;..int fd
8de0: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
8df0: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
8e00: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b  s, ...)", path);
8e10: 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53  ...if ((mode & S
8e20: 5f 49 46 43 48 52 29 20 3d 3d 20 53 5f 49 46 43  _IFCHR) == S_IFC
8e30: 48 52 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  HR) {...return(-
8e40: 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20  EPERM);..}...if 
8e50: 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 42 4c 4b  ((mode & S_IFBLK
8e60: 29 20 3d 3d 20 53 5f 49 46 42 4c 4b 29 20 7b 0a  ) == S_IFBLK) {.
8e70: 09 09 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29  ..return(-EPERM)
8e80: 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68  ;..}...real_path
8e90: 20 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72 65   = appfs_prepare
8ea0: 5f 74 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29  _to_create(path)
8eb0: 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68  ;..if (real_path
8ec0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
8ed0: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
8ee0: 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  .appfs_simulate_
8ef0: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b  user_fs_enter();
8f00: 0a 0a 09 66 64 20 3d 20 63 72 65 61 74 28 72 65  ...fd = creat(re
8f10: 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a  al_path, mode);.
8f20: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  ..appfs_simulate
8f30: 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29  _user_fs_leave()
8f40: 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61  ;...free(real_pa
8f50: 74 68 29 3b 0a 0a 09 69 66 20 28 66 64 20 3c 20  th);...if (fd < 
8f60: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72  0) {...return(er
8f70: 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09  rno * -1);..}...
8f80: 66 69 2d 3e 66 68 20 3d 20 66 64 3b 0a 0a 09 72  fi->fh = fd;...r
8f90: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61  eturn(0);.}..sta
8fa0: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
8fb0: 73 65 5f 74 72 75 6e 63 61 74 65 28 63 6f 6e 73  se_truncate(cons
8fc0: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6f 66  t char *path, of
8fd0: 66 5f 74 20 73 69 7a 65 29 20 7b 0a 09 63 68 61  f_t size) {..cha
8fe0: 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69  r *real_path;..i
8ff0: 6e 74 20 74 72 75 6e 63 61 74 65 5f 72 65 74 3b  nt truncate_ret;
9000: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
9010: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
9020: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
9030: 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70  ..real_path = ap
9040: 70 66 73 5f 6c 6f 63 61 6c 70 61 74 68 28 70 61  pfs_localpath(pa
9050: 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70  th);..if (real_p
9060: 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ath == NULL) {..
9070: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
9080: 7d 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61  }...appfs_get_pa
9090: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d  th_info_cache_rm
90a0: 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74  (path, appfs_get
90b0: 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 61 70 70  _fsuid());...app
90c0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
90d0: 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 74  _fs_enter();...t
90e0: 72 75 6e 63 61 74 65 5f 72 65 74 20 3d 20 74 72  runcate_ret = tr
90f0: 75 6e 63 61 74 65 28 72 65 61 6c 5f 70 61 74 68  uncate(real_path
9100: 2c 20 73 69 7a 65 29 3b 0a 0a 09 61 70 70 66 73  , size);...appfs
9110: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
9120: 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 65  s_leave();...fre
9130: 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09  e(real_path);...
9140: 69 66 20 28 74 72 75 6e 63 61 74 65 5f 72 65 74  if (truncate_ret
9150: 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72   != 0) {...retur
9160: 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09  n(errno * -1);..
9170: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  }...return(0);.}
9180: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
9190: 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72  fs_fuse_unlink_r
91a0: 6d 64 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20  mdir(const char 
91b0: 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e  *path) {..Tcl_In
91c0: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 69  terp *interp;..i
91d0: 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50  nt tcl_ret;...AP
91e0: 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72  PFS_DEBUG("Enter
91f0: 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e   (path = %s, ...
9200: 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70 70  )", path);...app
9210: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
9220: 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70  _cache_flush(app
9230: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20  fs_get_fsuid(), 
9240: 2d 31 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20  -1);...interp = 
9250: 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28  appfs_TclInterp(
9260: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  );..if (interp =
9270: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
9280: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
9290: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
92a0: 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e  (Tcl_Preserve(in
92b0: 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72 65  terp);)...tcl_re
92c0: 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76  t = appfs_Tcl_Ev
92d0: 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a  al(interp, 2, ":
92e0: 3a 61 70 70 66 73 3a 3a 75 6e 6c 69 6e 6b 70 61  :appfs::unlinkpa
92f0: 74 68 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20  th", path);..if 
9300: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
9310: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
9320: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 75 6e  BUG("::appfs::un
9330: 6c 69 6e 6b 70 61 74 68 28 25 73 29 20 66 61 69  linkpath(%s) fai
9340: 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09  led.", path);...
9350: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
9360: 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55  l(....APPFS_DEBU
9370: 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  G("Tcl Error is:
9380: 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72   %s", Tcl_GetStr
9390: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
93a0: 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73  ));...)....appfs
93b0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
93c0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
93d0: 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ;)....return(-EI
93e0: 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63  O);..}...appfs_c
93f0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
9400: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
9410: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a  ...return(0);.}.
9420: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
9430: 73 5f 66 75 73 65 5f 6d 6b 64 69 72 28 63 6f 6e  s_fuse_mkdir(con
9440: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d  st char *path, m
9450: 6f 64 65 5f 74 20 6d 6f 64 65 29 20 7b 0a 09 63  ode_t mode) {..c
9460: 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a  har *real_path;.
9470: 09 69 6e 74 20 6d 6b 64 69 72 5f 72 65 74 3b 0a  .int mkdir_ret;.
9480: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45  ..APPFS_DEBUG("E
9490: 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c  nter (path = %s,
94a0: 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a   ...)", path);..
94b0: 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70  .real_path = app
94c0: 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72  fs_prepare_to_cr
94d0: 65 61 74 65 28 70 61 74 68 29 3b 0a 09 69 66 20  eate(path);..if 
94e0: 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55  (real_path == NU
94f0: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  LL) {...return(-
9500: 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  EIO);..}...appfs
9510: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
9520: 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b 64  s_enter();...mkd
9530: 69 72 5f 72 65 74 20 3d 20 6d 6b 64 69 72 28 72  ir_ret = mkdir(r
9540: 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b  eal_path, mode);
9550: 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  ...appfs_simulat
9560: 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28  e_user_fs_leave(
9570: 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70  );...free(real_p
9580: 61 74 68 29 3b 0a 0a 09 69 66 20 28 6d 6b 64 69  ath);...if (mkdi
9590: 72 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  r_ret != 0) {...
95a0: 69 66 20 28 65 72 72 6e 6f 20 21 3d 20 45 45 58  if (errno != EEX
95b0: 49 53 54 29 20 7b 0a 09 09 09 72 65 74 75 72 6e  IST) {....return
95c0: 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 09  (errno * -1);...
95d0: 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29  }..}...return(0)
95e0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
95f0: 61 70 70 66 73 5f 66 75 73 65 5f 63 68 6d 6f 64  appfs_fuse_chmod
9600: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
9610: 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 29 20  h, mode_t mode) 
9620: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
9630: 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68  nterp;..const ch
9640: 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09  ar *real_path;..
9650: 69 6e 74 20 74 63 6c 5f 72 65 74 2c 20 63 68 6d  int tcl_ret, chm
9660: 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f  od_ret;...APPFS_
9670: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
9680: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
9690: 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f 67  path);...appfs_g
96a0: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
96b0: 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70 70 66  he_rm(path, appf
96c0: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a  s_get_fsuid());.
96d0: 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
96e0: 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69  _TclInterp();..i
96f0: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
9700: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  L) {...return(-E
9710: 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  IO);..}...appfs_
9720: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
9730: 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29  Preserve(interp)
9740: 3b 29 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61  ;)...tcl_ret = a
9750: 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e  ppfs_Tcl_Eval(in
9760: 74 65 72 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66  terp, 3, "::appf
9770: 73 3a 3a 6f 70 65 6e 70 61 74 68 22 2c 20 70 61  s::openpath", pa
9780: 74 68 2c 20 22 77 72 69 74 65 22 29 3b 0a 09 69  th, "write");..i
9790: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
97a0: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
97b0: 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a  DEBUG("::appfs::
97c0: 6f 70 65 6e 70 61 74 68 28 25 73 2c 20 25 73 29  openpath(%s, %s)
97d0: 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 2c   failed.", path,
97e0: 20 22 77 72 69 74 65 22 29 3b 0a 09 09 61 70 70   "write");...app
97f0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
9800: 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
9810: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
9820: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
9830: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
9840: 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61  ...)....appfs_ca
9850: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
9860: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
9870: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
9880: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..}...appfs_call
9890: 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 61 6c 5f  _libtcl(...real_
98a0: 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74 53 74  path = Tcl_GetSt
98b0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
98c0: 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63  p);..)...appfs_c
98d0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
98e0: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
98f0: 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68  ...if (real_path
9900: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
9910: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
9920: 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  .appfs_simulate_
9930: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b  user_fs_enter();
9940: 0a 0a 09 63 68 6d 6f 64 5f 72 65 74 20 3d 20 63  ...chmod_ret = c
9950: 68 6d 6f 64 28 72 65 61 6c 5f 70 61 74 68 2c 20  hmod(real_path, 
9960: 6d 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73  mode);...appfs_s
9970: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
9980: 6c 65 61 76 65 28 29 3b 0a 0a 09 72 65 74 75 72  leave();...retur
9990: 6e 28 63 68 6d 6f 64 5f 72 65 74 29 3b 0a 7d 0a  n(chmod_ret);.}.
99a0: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
99b0: 73 5f 66 75 73 65 5f 73 79 6d 6c 69 6e 6b 28 63  s_fuse_symlink(c
99c0: 6f 6e 73 74 20 63 68 61 72 20 2a 6f 6c 64 70 61  onst char *oldpa
99d0: 74 68 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  th, const char *
99e0: 6e 65 77 70 61 74 68 29 20 7b 0a 09 63 68 61 72  newpath) {..char
99f0: 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e   *real_path;..in
9a00: 74 20 73 79 6d 6c 69 6e 6b 5f 72 65 74 3b 0a 0a  t symlink_ret;..
9a10: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
9a20: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
9a30: 25 73 29 22 2c 20 6f 6c 64 70 61 74 68 2c 20 6e  %s)", oldpath, n
9a40: 65 77 70 61 74 68 29 3b 0a 0a 09 72 65 61 6c 5f  ewpath);...real_
9a50: 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72 65  path = appfs_pre
9a60: 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 6e  pare_to_create(n
9a70: 65 77 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65  ewpath);..if (re
9a80: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
9a90: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f   {...return(-EIO
9aa0: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69  );..}...appfs_si
9ab0: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65  mulate_user_fs_e
9ac0: 6e 74 65 72 28 29 3b 0a 0a 09 73 79 6d 6c 69 6e  nter();...symlin
9ad0: 6b 5f 72 65 74 20 3d 20 73 79 6d 6c 69 6e 6b 28  k_ret = symlink(
9ae0: 6f 6c 64 70 61 74 68 2c 20 72 65 61 6c 5f 70 61  oldpath, real_pa
9af0: 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d  th);...appfs_sim
9b00: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65  ulate_user_fs_le
9b10: 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65  ave();...free(re
9b20: 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28  al_path);...if (
9b30: 73 79 6d 6c 69 6e 6b 5f 72 65 74 20 21 3d 20 30  symlink_ret != 0
9b40: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72  ) {...return(err
9b50: 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72  no * -1);..}...r
9b60: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a  eturn(0);.}../*.
9b70: 20 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 3a   * SQLite3 mode:
9b80: 20 45 78 65 63 75 74 65 20 72 61 77 20 53 51 4c   Execute raw SQL
9b90: 20 61 6e 64 20 72 65 74 75 72 6e 20 73 75 63 63   and return succ
9ba0: 65 73 73 20 6f 72 20 66 61 69 6c 75 72 65 0a 20  ess or failure. 
9bb0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  */.static int ap
9bc0: 70 66 73 5f 73 71 6c 69 74 65 33 28 63 6f 6e 73  pfs_sqlite3(cons
9bd0: 74 20 63 68 61 72 20 2a 73 71 6c 29 20 7b 0a 09  t char *sql) {..
9be0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
9bf0: 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20  rp;..const char 
9c00: 2a 73 71 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 74  *sql_ret;..int t
9c10: 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70  cl_ret;...interp
9c20: 20 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f   = appfs_create_
9c30: 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b  TclInterp(NULL);
9c40: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
9c50: 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74  NULL) {...fprint
9c60: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
9c70: 65 20 74 6f 20 63 72 65 61 74 65 20 61 20 54 63  e to create a Tc
9c80: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20  l interpreter.  
9c90: 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a  Aborting.\n");..
9ca0: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
9cb0: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66  ..tcl_ret = appf
9cc0: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  s_Tcl_Eval(inter
9cd0: 70 2c 20 35 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  p, 5, "::appfs::
9ce0: 64 62 22 2c 20 22 65 76 61 6c 22 2c 20 73 71 6c  db", "eval", sql
9cf0: 2c 20 22 72 6f 77 22 2c 20 22 75 6e 73 65 74 20  , "row", "unset 
9d00: 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 72 6f 77 28  -nocomplain row(
9d10: 2a 29 3b 20 70 61 72 72 61 79 20 72 6f 77 3b 20  *); parray row; 
9d20: 70 75 74 73 20 5c 22 2d 2d 2d 2d 5c 22 22 29 3b  puts \"----\"");
9d30: 0a 09 73 71 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..sql_ret = Tcl_
9d40: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
9d50: 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 74  interp);...if (t
9d60: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
9d70: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
9d80: 64 65 72 72 2c 20 22 5b 65 72 72 6f 72 5d 20 25  derr, "[error] %
9d90: 73 5c 6e 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a  s\n", sql_ret);.
9da0: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
9db0: 0a 0a 09 69 66 20 28 73 71 6c 5f 72 65 74 20 26  ...if (sql_ret &
9dc0: 26 20 73 71 6c 5f 72 65 74 5b 30 5d 20 21 3d 20  & sql_ret[0] != 
9dd0: 27 5c 30 27 29 20 7b 0a 09 09 70 72 69 6e 74 66  '\0') {...printf
9de0: 28 22 25 73 5c 6e 22 2c 20 73 71 6c 5f 72 65 74  ("%s\n", sql_ret
9df0: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30  );..}...return(0
9e00: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 63 6c 20  );.}../*. * Tcl 
9e10: 6d 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72 61  mode: Execute ra
9e20: 77 20 54 63 6c 20 61 6e 64 20 72 65 74 75 72 6e  w Tcl and return
9e30: 20 73 75 63 63 65 73 73 20 6f 72 20 66 61 69 6c   success or fail
9e40: 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69  ure. */.static i
9e50: 6e 74 20 61 70 70 66 73 5f 74 63 6c 28 63 6f 6e  nt appfs_tcl(con
9e60: 73 74 20 63 68 61 72 20 2a 74 63 6c 29 20 7b 0a  st char *tcl) {.
9e70: 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  .Tcl_Interp *int
9e80: 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72  erp;..const char
9e90: 20 2a 74 63 6c 5f 72 65 73 75 6c 74 3b 0a 09 69   *tcl_result;..i
9ea0: 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e  nt tcl_ret;...in
9eb0: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65  terp = appfs_cre
9ec0: 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55  ate_TclInterp(NU
9ed0: 4c 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  LL);..if (interp
9ee0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70   == NULL) {...fp
9ef0: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55  rintf(stderr, "U
9f00: 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20  nable to create 
9f10: 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  a Tcl interprete
9f20: 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22  r.  Aborting.\n"
9f30: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b  );....return(1);
9f40: 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20  ..}...tcl_ret = 
9f50: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
9f60: 20 74 63 6c 29 3b 0a 09 74 63 6c 5f 72 65 73 75   tcl);..tcl_resu
9f70: 6c 74 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  lt = Tcl_GetStri
9f80: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
9f90: 3b 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  ;...if (tcl_ret 
9fa0: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66  != TCL_OK) {...f
9fb0: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
9fc0: 5b 65 72 72 6f 72 5d 20 25 73 5c 6e 22 2c 20 54  [error] %s\n", T
9fd0: 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72 70  cl_GetVar(interp
9fe0: 2c 20 22 65 72 72 6f 72 49 6e 66 6f 22 2c 20 54  , "errorInfo", T
9ff0: 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 29  CL_GLOBAL_ONLY))
a000: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a  ;....return(1);.
a010: 09 7d 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 73  .}...if (tcl_res
a020: 75 6c 74 20 26 26 20 74 63 6c 5f 72 65 73 75 6c  ult && tcl_resul
a030: 74 5b 30 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a  t[0] != '\0') {.
a040: 09 09 70 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c  ..printf("%s\n",
a050: 20 74 63 6c 5f 72 65 73 75 6c 74 29 3b 0a 09 7d   tcl_result);..}
a060: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a  ...return(0);.}.
a070: 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 64 20 50 61  ./*. * AppFSd Pa
a080: 63 6b 61 67 65 20 66 6f 72 20 54 63 6c 3a 0a 20  ckage for Tcl:. 
a090: 2a 20 20 20 20 20 20 20 20 20 42 72 69 64 67 65  *         Bridge
a0a0: 20 66 6f 72 20 49 2f 4f 20 6f 70 65 72 61 74 69   for I/O operati
a0b0: 6f 6e 73 20 74 6f 20 72 65 71 75 65 73 74 20 69  ons to request i
a0c0: 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74  nformation about
a0d0: 20 74 68 65 20 63 75 72 72 65 6e 74 0a 20 2a 20   the current. * 
a0e0: 20 20 20 20 20 20 20 20 74 72 61 6e 73 61 63 74          transact
a0f0: 69 6f 6e 0a 20 2a 2f 0a 2f 2a 0a 20 2a 20 54 63  ion. */./*. * Tc
a100: 6c 20 69 6e 74 65 72 66 61 63 65 20 74 6f 20 67  l interface to g
a110: 65 74 20 74 68 65 20 68 6f 6d 65 20 64 69 72 65  et the home dire
a120: 63 74 6f 72 79 20 66 6f 72 20 74 68 65 20 75 73  ctory for the us
a130: 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 22 63  er making the "c
a140: 75 72 72 65 6e 74 22 0a 20 2a 20 46 55 53 45 20  urrent". * FUSE 
a150: 49 2f 4f 20 72 65 71 75 65 73 74 0a 20 2a 2f 0a  I/O request. */.
a160: 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61  static int tcl_a
a170: 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72  ppfs_get_homedir
a180: 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20  (ClientData cd, 
a190: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
a1a0: 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63  rp, int objc, Tc
a1b0: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
a1c0: 76 5b 5d 29 20 7b 0a 09 63 68 61 72 20 2a 68 6f  v[]) {..char *ho
a1d0: 6d 65 64 69 72 3b 0a 09 54 63 6c 5f 4f 62 6a 20  medir;..Tcl_Obj 
a1e0: 2a 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 75  *homedir_obj;..u
a1f0: 69 64 5f 74 20 66 73 75 69 64 3b 0a 09 73 74 61  id_t fsuid;..sta
a200: 74 69 63 20 5f 5f 74 68 72 65 61 64 20 54 63 6c  tic __thread Tcl
a210: 5f 4f 62 6a 20 2a 6c 61 73 74 5f 68 6f 6d 65 64  _Obj *last_homed
a220: 69 72 5f 6f 62 6a 20 3d 20 4e 55 4c 4c 3b 0a 09  ir_obj = NULL;..
a230: 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64 20  static __thread 
a240: 75 69 64 5f 74 20 6c 61 73 74 5f 66 73 75 69 64  uid_t last_fsuid
a250: 20 3d 20 2d 31 3b 0a 0a 20 20 20 20 20 20 20 20   = -1;..        
a260: 69 66 20 28 6f 62 6a 63 20 21 3d 20 31 29 20 7b  if (objc != 1) {
a270: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
a280: 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67   Tcl_WrongNumArg
a290: 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a  s(interp, 1, obj
a2a0: 76 2c 20 4e 55 4c 4c 29 3b 0a 20 20 20 20 20 20  v, NULL);.      
a2b0: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
a2c0: 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 20 20 20  (TCL_ERROR);.   
a2d0: 20 20 20 20 20 7d 0a 0a 09 66 73 75 69 64 20 3d       }...fsuid =
a2e0: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
a2f0: 28 29 3b 0a 0a 09 69 66 20 28 66 73 75 69 64 20  ();...if (fsuid 
a300: 3d 3d 20 6c 61 73 74 5f 66 73 75 69 64 20 26 26  == last_fsuid &&
a310: 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62   last_homedir_ob
a320: 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68  j != NULL) {...h
a330: 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 6c 61 73  omedir_obj = las
a340: 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 0a  t_homedir_obj;..
a350: 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75  ..Tcl_IncrRefCou
a360: 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b  nt(homedir_obj);
a370: 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 68 6f 6d  ..} else {...hom
a380: 65 64 69 72 20 3d 20 61 70 70 66 73 5f 67 65 74  edir = appfs_get
a390: 5f 68 6f 6d 65 64 69 72 28 61 70 70 66 73 5f 67  _homedir(appfs_g
a3a0: 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 09  et_fsuid());....
a3b0: 69 66 20 28 68 6f 6d 65 64 69 72 20 3d 3d 20 4e  if (homedir == N
a3c0: 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74 75 72 6e  ULL) {....return
a3d0: 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 09 7d  (TCL_ERROR);...}
a3e0: 0a 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20  ....homedir_obj 
a3f0: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
a400: 62 6a 28 68 6f 6d 65 64 69 72 2c 20 2d 31 29 3b  bj(homedir, -1);
a410: 0a 0a 09 09 66 72 65 65 28 68 6f 6d 65 64 69 72  ....free(homedir
a420: 29 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65  );....Tcl_IncrRe
a430: 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f  fCount(homedir_o
a440: 62 6a 29 3b 0a 0a 09 09 69 66 20 28 6c 61 73 74  bj);....if (last
a450: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 21 3d 20  _homedir_obj != 
a460: 4e 55 4c 4c 29 20 7b 0a 09 09 09 54 63 6c 5f 44  NULL) {....Tcl_D
a470: 65 63 72 52 65 66 43 6f 75 6e 74 28 6c 61 73 74  ecrRefCount(last
a480: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09  _homedir_obj);..
a490: 09 7d 0a 0a 09 09 6c 61 73 74 5f 68 6f 6d 65 64  .}....last_homed
a4a0: 69 72 5f 6f 62 6a 20 3d 20 68 6f 6d 65 64 69 72  ir_obj = homedir
a4b0: 5f 6f 62 6a 3b 0a 09 09 6c 61 73 74 5f 66 73 75  _obj;...last_fsu
a4c0: 69 64 20 3d 20 66 73 75 69 64 3b 0a 0a 09 09 54  id = fsuid;....T
a4d0: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
a4e0: 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 7d  homedir_obj);..}
a4f0: 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53 65  ..       .Tcl_Se
a500: 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72  tObjResult(inter
a510: 70 2c 20 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b  p, homedir_obj);
a520: 0a 0a 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f  ...Tcl_DecrRefCo
a530: 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29  unt(homedir_obj)
a540: 3b 0a 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ;..        retur
a550: 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74  n(TCL_OK);.}..st
a560: 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70  atic int tcl_app
a570: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
a580: 5f 66 73 5f 65 6e 74 65 72 28 43 6c 69 65 6e 74  _fs_enter(Client
a590: 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74  Data cd, Tcl_Int
a5a0: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74  erp *interp, int
a5b0: 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a   objc, Tcl_Obj *
a5c0: 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a  CONST objv[]) {.
a5d0: 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  .appfs_simulate_
a5e0: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b  user_fs_enter();
a5f0: 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b  ...return(TCL_OK
a600: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
a610: 20 74 63 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c   tcl_appfs_simul
a620: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76  ate_user_fs_leav
a630: 65 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c  e(ClientData cd,
a640: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
a650: 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54  erp, int objc, T
a660: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
a670: 6a 76 5b 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73  jv[]) {..appfs_s
a680: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
a690: 6c 65 61 76 65 28 29 3b 0a 0a 09 72 65 74 75 72  leave();...retur
a6a0: 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74  n(TCL_OK);.}..st
a6b0: 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70  atic int tcl_app
a6c0: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 43 6c 69  fs_get_fsuid(Cli
a6d0: 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f  entData cd, Tcl_
a6e0: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20  Interp *interp, 
a6f0: 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62  int objc, Tcl_Ob
a700: 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29  j *CONST objv[])
a710: 20 7b 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b   {..uid_t fsuid;
a720: 0a 0a 09 66 73 75 69 64 20 3d 20 61 70 70 66 73  ...fsuid = appfs
a730: 5f 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 0a 20  _get_fsuid();.. 
a740: 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74 4f 62        .Tcl_SetOb
a750: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  jResult(interp, 
a760: 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62  Tcl_NewWideIntOb
a770: 6a 28 66 73 75 69 64 29 29 3b 0a 0a 09 72 65 74  j(fsuid));...ret
a780: 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a  urn(TCL_OK);.}..
a790: 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61  static int tcl_a
a7a0: 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28 43  ppfs_get_fsgid(C
a7b0: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63  lientData cd, Tc
a7c0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
a7d0: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f  , int objc, Tcl_
a7e0: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
a7f0: 5d 29 20 7b 0a 09 67 69 64 5f 74 20 66 73 67 69  ]) {..gid_t fsgi
a800: 64 3b 0a 0a 09 66 73 67 69 64 20 3d 20 61 70 70  d;...fsgid = app
a810: 66 73 5f 67 65 74 5f 66 73 67 69 64 28 29 3b 0a  fs_get_fsgid();.
a820: 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74  .       .Tcl_Set
a830: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
a840: 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74  , Tcl_NewWideInt
a850: 4f 62 6a 28 66 73 67 69 64 29 29 3b 0a 0a 09 72  Obj(fsgid));...r
a860: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d  eturn(TCL_OK);.}
a870: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c  ..static int tcl
a880: 5f 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  _appfs_get_path_
a890: 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68  info_cache_flush
a8a0: 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20  (ClientData cd, 
a8b0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
a8c0: 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63  rp, int objc, Tc
a8d0: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
a8e0: 76 5b 5d 29 20 7b 0a 09 69 6e 74 20 74 63 6c 5f  v[]) {..int tcl_
a8f0: 72 65 74 3b 0a 09 69 6e 74 20 6e 65 77 5f 73 69  ret;..int new_si
a900: 7a 65 3b 0a 0a 09 6e 65 77 5f 73 69 7a 65 20 3d  ze;...new_size =
a910: 20 2d 31 3b 0a 0a 09 69 66 20 28 6f 62 6a 63 20   -1;...if (objc 
a920: 3d 3d 20 32 29 20 7b 0a 09 09 74 63 6c 5f 72 65  == 2) {...tcl_re
a930: 74 20 3d 20 54 63 6c 5f 47 65 74 49 6e 74 46 72  t = Tcl_GetIntFr
a940: 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62  omObj(interp, ob
a950: 6a 76 5b 31 5d 2c 20 26 6e 65 77 5f 73 69 7a 65  jv[1], &new_size
a960: 29 3b 0a 09 09 69 66 20 28 74 63 6c 5f 72 65 74  );...if (tcl_ret
a970: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
a980: 09 72 65 74 75 72 6e 28 74 63 6c 5f 72 65 74 29  .return(tcl_ret)
a990: 3b 0a 09 09 7d 0a 09 7d 20 65 6c 73 65 20 69 66  ;...}..} else if
a9a0: 20 28 6f 62 6a 63 20 3e 20 32 20 7c 7c 20 6f 62   (objc > 2 || ob
a9b0: 6a 63 20 3c 20 31 29 20 7b 0a 20 20 20 20 20 20  jc < 1) {.      
a9c0: 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72            Tcl_Wr
a9d0: 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72  ongNumArgs(inter
a9e0: 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 3f 6e 65  p, 1, objv, "?ne
a9f0: 77 5f 63 61 63 68 65 5f 73 69 7a 65 3f 22 29 3b  w_cache_size?");
aa00: 0a 09 09 72 65 74 75 72 6e 28 54 43 4c 5f 45 52  ...return(TCL_ER
aa10: 52 4f 52 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  ROR);..}...appfs
aa20: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
aa30: 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c 20 6e  ache_flush(-1, n
aa40: 65 77 5f 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75  ew_size);...retu
aa50: 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73  rn(TCL_OK);.}..s
aa60: 74 61 74 69 63 20 69 6e 74 20 41 70 70 66 73 64  tatic int Appfsd
aa70: 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70  _Init(Tcl_Interp
aa80: 20 2a 69 6e 74 65 72 70 29 20 7b 0a 23 69 66 64   *interp) {.#ifd
aa90: 65 66 20 55 53 45 5f 54 43 4c 5f 53 54 55 42 53  ef USE_TCL_STUBS
aaa0: 0a 09 69 66 20 28 54 63 6c 5f 49 6e 69 74 53 74  ..if (Tcl_InitSt
aab0: 75 62 73 28 69 6e 74 65 72 70 2c 20 54 43 4c 5f  ubs(interp, TCL_
aac0: 56 45 52 53 49 4f 4e 2c 20 30 29 20 3d 3d 20 30  VERSION, 0) == 0
aad0: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 54 43  L) {...return(TC
aae0: 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 23 65 6e  L_ERROR);..}.#en
aaf0: 64 69 66 0a 0a 09 54 63 6c 5f 43 72 65 61 74 65  dif...Tcl_Create
ab00: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
ab10: 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f  p, "appfsd::get_
ab20: 68 6f 6d 65 64 69 72 22 2c 20 74 63 6c 5f 61 70  homedir", tcl_ap
ab30: 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 2c  pfs_get_homedir,
ab40: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54   NULL, NULL);..T
ab50: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
ab60: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70  and(interp, "app
ab70: 66 73 64 3a 3a 67 65 74 5f 66 73 75 69 64 22 2c  fsd::get_fsuid",
ab80: 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66   tcl_appfs_get_f
ab90: 73 75 69 64 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  suid, NULL, NULL
aba0: 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62  );..Tcl_CreateOb
abb0: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  jCommand(interp,
abc0: 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 66 73   "appfsd::get_fs
abd0: 67 69 64 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f  gid", tcl_appfs_
abe0: 67 65 74 5f 66 73 67 69 64 2c 20 4e 55 4c 4c 2c  get_fsgid, NULL,
abf0: 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65   NULL);..Tcl_Cre
ac00: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
ac10: 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 73  terp, "appfsd::s
ac20: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
ac30: 65 6e 74 65 72 22 2c 20 74 63 6c 5f 61 70 70 66  enter", tcl_appf
ac40: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
ac50: 66 73 5f 65 6e 74 65 72 2c 20 4e 55 4c 4c 2c 20  fs_enter, NULL, 
ac60: 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61  NULL);..Tcl_Crea
ac70: 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74  teObjCommand(int
ac80: 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 73 69  erp, "appfsd::si
ac90: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
aca0: 65 61 76 65 22 2c 20 74 63 6c 5f 61 70 70 66 73  eave", tcl_appfs
acb0: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
acc0: 73 5f 6c 65 61 76 65 2c 20 4e 55 4c 4c 2c 20 4e  s_leave, NULL, N
acd0: 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74  ULL);..Tcl_Creat
ace0: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
acf0: 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74  rp, "appfsd::get
ad00: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
ad10: 5f 66 6c 75 73 68 22 2c 20 74 63 6c 5f 61 70 70  _flush", tcl_app
ad20: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
ad30: 5f 63 61 63 68 65 5f 66 6c 75 73 68 2c 20 4e 55  _cache_flush, NU
ad40: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 54 63 6c  LL, NULL);...Tcl
ad50: 5f 50 6b 67 50 72 6f 76 69 64 65 28 69 6e 74 65  _PkgProvide(inte
ad60: 72 70 2c 20 22 61 70 70 66 73 64 22 2c 20 22 31  rp, "appfsd", "1
ad70: 2e 30 22 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54  .0");...return(T
ad80: 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  CL_OK);.}../*. *
ad90: 20 48 6f 74 2d 72 65 73 74 61 72 74 20 73 75 70   Hot-restart sup
ada0: 70 6f 72 74 0a 20 2a 2f 0a 2f 2a 20 49 6e 69 74  port. */./* Init
adb0: 69 61 74 65 20 61 20 68 6f 74 2d 72 65 73 74 61  iate a hot-resta
adc0: 72 74 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  rt */.static voi
add0: 64 20 61 70 70 66 73 5f 68 6f 74 5f 72 65 73 74  d appfs_hot_rest
ade0: 61 72 74 28 76 6f 69 64 29 20 7b 0a 09 41 50 50  art(void) {..APP
adf0: 46 53 5f 44 45 42 55 47 28 22 41 73 6b 65 64 20  FS_DEBUG("Asked 
ae00: 74 6f 20 69 6e 69 74 69 61 74 65 20 68 6f 74 20  to initiate hot 
ae10: 72 65 73 74 61 72 74 22 29 3b 0a 0a 09 61 70 70  restart");...app
ae20: 66 73 5f 74 63 6c 5f 52 65 73 65 74 49 6e 74 65  fs_tcl_ResetInte
ae30: 72 70 73 28 29 3b 0a 0a 09 61 70 70 66 73 5f 67  rps();...appfs_g
ae40: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
ae50: 68 65 5f 66 6c 75 73 68 28 2d 31 2c 20 2d 31 29  he_flush(-1, -1)
ae60: 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f  ;...return;.}../
ae70: 2a 0a 20 2a 20 53 69 67 6e 61 6c 20 68 61 6e 64  *. * Signal hand
ae80: 6c 65 72 0a 20 2a 20 20 20 20 20 20 20 20 20 53  ler. *         S
ae90: 49 47 48 55 50 20 69 6e 69 74 69 61 74 65 73 20  IGHUP initiates 
aea0: 61 20 68 6f 74 20 72 65 73 74 61 72 74 0a 20 2a  a hot restart. *
aeb0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  /.static void ap
aec0: 70 66 73 5f 73 69 67 6e 61 6c 5f 68 61 6e 64 6c  pfs_signal_handl
aed0: 65 72 28 69 6e 74 20 73 69 67 29 20 7b 0a 09 2f  er(int sig) {../
aee0: 2a 20 44 6f 20 6e 6f 74 20 68 61 6e 64 6c 65 20  * Do not handle 
aef0: 73 69 67 6e 61 6c 73 20 75 6e 74 69 6c 20 46 55  signals until FU
af00: 53 45 20 68 61 73 20 62 65 65 6e 20 73 74 61 72  SE has been star
af10: 74 65 64 20 2a 2f 0a 09 69 66 20 28 21 61 70 70  ted */..if (!app
af20: 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 29  fs_fuse_started)
af30: 20 7b 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a   {...return;..}.
af40: 0a 09 2f 2a 20 52 65 71 75 65 73 74 20 74 6f 20  ../* Request to 
af50: 70 65 72 66 6f 72 6d 20 61 20 22 68 6f 74 22 20  perform a "hot" 
af60: 72 65 73 74 61 72 74 20 2a 2f 0a 09 69 66 20 28  restart */..if (
af70: 73 69 67 20 3d 3d 20 53 49 47 48 55 50 29 20 7b  sig == SIGHUP) {
af80: 0a 09 09 61 70 70 66 73 5f 68 6f 74 5f 72 65 73  ...appfs_hot_res
af90: 74 61 72 74 28 29 3b 0a 09 7d 0a 0a 09 72 65 74  tart();..}...ret
afa0: 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 65  urn;.}../*. * Te
afb0: 72 6d 69 6e 61 74 65 20 61 20 74 68 72 65 61 64  rminate a thread
afc0: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  . */.static void
afd0: 20 61 70 70 66 73 5f 74 65 72 6d 69 6e 61 74 65   appfs_terminate
afe0: 5f 69 6e 74 65 72 70 5f 61 6e 64 5f 74 68 72 65  _interp_and_thre
aff0: 61 64 28 76 6f 69 64 20 2a 5f 69 6e 74 65 72 70  ad(void *_interp
b000: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
b010: 2a 69 6e 74 65 72 70 3b 0a 0a 09 41 50 50 46 53  *interp;...APPFS
b020: 5f 44 45 42 55 47 28 22 43 61 6c 6c 65 64 3a 20  _DEBUG("Called: 
b030: 5f 69 6e 74 65 72 70 20 3d 20 25 70 22 2c 20 5f  _interp = %p", _
b040: 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 5f  interp);...if (_
b050: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
b060: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
b070: 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 74 68 72  "Terminating thr
b080: 65 61 64 20 77 69 74 68 20 6e 6f 20 69 6e 74 65  ead with no inte
b090: 72 70 72 65 74 65 72 22 29 3b 0a 0a 09 09 72 65  rpreter");....re
b0a0: 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72  turn;..}...inter
b0b0: 70 20 3d 20 5f 69 6e 74 65 72 70 3b 0a 0a 09 41  p = _interp;...A
b0c0: 50 50 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d  PPFS_DEBUG("Term
b0d0: 69 6e 61 74 69 6e 67 20 69 6e 74 65 72 70 72 65  inating interpre
b0e0: 74 65 72 20 64 75 65 20 74 6f 20 74 68 72 65 61  ter due to threa
b0f0: 64 20 74 65 72 6d 69 6e 61 74 69 6f 6e 22 29 3b  d termination");
b100: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
b110: 62 74 63 6c 28 0a 09 09 54 63 6c 5f 44 65 6c 65  btcl(...Tcl_Dele
b120: 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29  teInterp(interp)
b130: 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..)...appfs_cal
b140: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 54 63 6c 5f  l_libtcl(...Tcl_
b150: 46 69 6e 61 6c 69 7a 65 54 68 72 65 61 64 28 29  FinalizeThread()
b160: 3b 0a 09 29 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d  ;..)...return;.}
b170: 0a 0a 2f 2a 0a 20 2a 20 43 6f 6d 6d 61 6e 64 2d  ../*. * Command-
b180: 6c 69 6e 65 20 70 61 72 73 69 6e 67 20 74 6f 6f  line parsing too
b190: 6c 73 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ls. */.static vo
b1a0: 69 64 20 61 70 70 66 73 5f 70 72 69 6e 74 5f 68  id appfs_print_h
b1b0: 65 6c 70 28 46 49 4c 45 20 2a 63 68 61 6e 6e 65  elp(FILE *channe
b1c0: 6c 29 20 7b 0a 09 66 70 72 69 6e 74 66 28 63 68  l) {..fprintf(ch
b1d0: 61 6e 6e 65 6c 2c 20 22 55 73 61 67 65 3a 20 7b  annel, "Usage: {
b1e0: 61 70 70 66 73 64 7c 6d 6f 75 6e 74 2e 61 70 70  appfsd|mount.app
b1f0: 66 73 7d 20 5b 2d 6f 20 3c 6f 70 74 69 6f 6e 3e  fs} [-o <option>
b200: 5d 20 5b 2d 64 66 73 68 5d 20 3c 63 61 63 68 65  ] [-dfsh] <cache
b210: 64 69 72 3e 20 3c 6d 6f 75 6e 74 70 6f 69 6e 74  dir> <mountpoint
b220: 3e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28  >\n");..fprintf(
b230: 63 68 61 6e 6e 65 6c 2c 20 22 5c 6e 22 29 3b 0a  channel, "\n");.
b240: 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c  .fprintf(channel
b250: 2c 20 22 4f 70 74 69 6f 6e 73 3a 5c 6e 22 29 3b  , "Options:\n");
b260: 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65  ..fprintf(channe
b270: 6c 2c 20 22 20 20 2d 64 20 20 20 20 20 20 20 20  l, "  -d        
b280: 20 20 20 20 20 20 45 6e 61 62 6c 65 20 46 55 53        Enable FUS
b290: 45 20 64 65 62 75 67 20 6d 6f 64 65 2e 5c 6e 22  E debug mode.\n"
b2a0: 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e  );..fprintf(chan
b2b0: 6e 65 6c 2c 20 22 20 20 2d 66 20 20 20 20 20 20  nel, "  -f      
b2c0: 20 20 20 20 20 20 20 20 52 75 6e 20 69 6e 20 66          Run in f
b2d0: 6f 72 65 67 72 6f 75 6e 64 2e 5c 6e 22 29 3b 0a  oreground.\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 73 20 20 20 20 20 20 20 20 20  , "  -s         
b300: 20 20 20 20 20 45 6e 61 62 6c 65 20 73 69 6e 67       Enable sing
b310: 6c 65 20 74 68 72 65 61 64 65 64 20 6d 6f 64 65  le threaded mode
b320: 2e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28  .\n");..fprintf(
b330: 63 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 68 20 20  channel, "  -h  
b340: 20 20 20 20 20 20 20 20 20 20 20 20 47 69 76 65              Give
b350: 20 74 68 69 73 20 68 65 6c 70 2e 5c 6e 22 29 3b   this help.\n");
b360: 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65  ..fprintf(channe
b370: 6c 2c 20 22 20 20 2d 6f 20 6e 6f 74 68 72 65 61  l, "  -o nothrea
b380: 64 73 20 20 20 20 45 6e 61 62 6c 65 20 73 69 6e  ds    Enable sin
b390: 67 6c 65 20 74 68 72 65 61 64 65 64 20 6d 6f 64  gle threaded mod
b3a0: 65 2e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66  e.\n");..fprintf
b3b0: 28 63 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 6f 20  (channel, "  -o 
b3c0: 61 6c 6c 6f 77 5f 6f 74 68 65 72 20 20 41 6c 6c  allow_other  All
b3d0: 6f 77 20 6f 74 68 65 72 20 75 73 65 72 73 20 74  ow other users t
b3e0: 6f 20 61 63 63 65 73 73 20 74 68 69 73 20 6d 6f  o access this mo
b3f0: 75 6e 74 70 6f 69 6e 74 20 28 64 65 66 61 75 6c  untpoint (defaul
b400: 74 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28  t\n");..fprintf(
b410: 63 68 61 6e 6e 65 6c 2c 20 22 20 20 20 20 20 20  channel, "      
b420: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 72              if r
b430: 6f 6f 74 29 2e 5c 6e 22 29 3b 0a 0a 09 72 65 74  oot).\n");...ret
b440: 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  urn;.}..static i
b450: 6e 74 20 61 70 70 66 73 5f 6f 70 74 5f 70 61 72  nt appfs_opt_par
b460: 73 65 28 69 6e 74 20 61 72 67 63 2c 20 63 68 61  se(int argc, cha
b470: 72 20 2a 2a 61 72 67 76 2c 20 20 73 74 72 75 63  r **argv,  struc
b480: 74 20 66 75 73 65 5f 61 72 67 73 20 2a 61 72 67  t fuse_args *arg
b490: 73 29 20 7b 0a 09 69 6e 74 20 63 68 3b 0a 09 63  s) {..int ch;..c
b4a0: 68 61 72 20 2a 6f 70 74 73 74 72 2c 20 2a 6f 70  har *optstr, *op
b4b0: 74 73 74 72 5f 6e 65 78 74 2c 20 2a 6f 70 74 73  tstr_next, *opts
b4c0: 74 72 5f 73 3b 0a 09 63 68 61 72 20 66 61 6b 65  tr_s;..char fake
b4d0: 5f 61 72 67 5b 33 5d 20 3d 20 7b 27 2d 27 2c 20  _arg[3] = {'-', 
b4e0: 30 2c 20 30 7d 3b 0a 0a 09 2f 2a 0a 09 20 2a 20  0, 0};.../*.. * 
b4f0: 44 65 66 61 75 6c 74 20 76 61 6c 75 65 73 0a 09  Default values..
b500: 20 2a 2f 0a 23 69 66 64 65 66 20 54 43 4c 5f 54   */.#ifdef TCL_T
b510: 48 52 45 41 44 53 0a 09 61 70 70 66 73 5f 74 68  HREADS..appfs_th
b520: 72 65 61 64 65 64 5f 74 63 6c 20 3d 20 31 3b 0a  readed_tcl = 1;.
b530: 23 65 6c 73 65 0a 09 61 70 70 66 73 5f 74 68 72  #else..appfs_thr
b540: 65 61 64 65 64 5f 74 63 6c 20 3d 20 30 3b 0a 23  eaded_tcl = 0;.#
b550: 65 6e 64 69 66 0a 0a 09 2f 2a 2a 0a 09 20 2a 2a  endif.../**.. **
b560: 20 41 64 64 20 46 55 53 45 20 61 72 67 75 6d 65   Add FUSE argume
b570: 6e 74 73 20 77 68 69 63 68 20 77 65 20 61 6c 77  nts which we alw
b580: 61 79 73 20 73 75 70 70 6c 79 0a 09 20 2a 2a 2f  ays supply.. **/
b590: 0a 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61  ..fuse_opt_add_a
b5a0: 72 67 28 61 72 67 73 2c 20 22 2d 6f 64 65 66 61  rg(args, "-odefa
b5b0: 75 6c 74 5f 70 65 72 6d 69 73 73 69 6f 6e 73 2c  ult_permissions,
b5c0: 66 73 6e 61 6d 65 3d 61 70 70 66 73 2c 73 75 62  fsname=appfs,sub
b5d0: 74 79 70 65 3d 61 70 70 66 73 64 2c 75 73 65 5f  type=appfsd,use_
b5e0: 69 6e 6f 2c 6b 65 72 6e 65 6c 5f 63 61 63 68 65  ino,kernel_cache
b5f0: 2c 65 6e 74 72 79 5f 74 69 6d 65 6f 75 74 3d 30  ,entry_timeout=0
b600: 2c 61 74 74 72 5f 74 69 6d 65 6f 75 74 3d 30 2c  ,attr_timeout=0,
b610: 62 69 67 5f 77 72 69 74 65 73 2c 69 6e 74 72 2c  big_writes,intr,
b620: 68 61 72 64 5f 72 65 6d 6f 76 65 22 29 3b 0a 0a  hard_remove");..
b630: 09 69 66 20 28 67 65 74 75 69 64 28 29 20 3d 3d  .if (getuid() ==
b640: 20 30 29 20 7b 0a 09 09 66 75 73 65 5f 6f 70 74   0) {...fuse_opt
b650: 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c  _parse(args, NUL
b660: 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  L, NULL, NULL);.
b670: 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61  ..fuse_opt_add_a
b680: 72 67 28 61 72 67 73 2c 20 22 2d 6f 61 6c 6c 6f  rg(args, "-oallo
b690: 77 5f 6f 74 68 65 72 22 29 3b 0a 0a 09 09 2f 2a  w_other");..../*
b6a0: 0a 09 09 20 2a 20 54 68 69 73 20 73 68 6f 75 6c  ... * This shoul
b6b0: 64 20 67 65 6e 65 72 61 6c 6c 79 20 62 65 20 61  d generally be a
b6c0: 76 6f 69 64 65 64 2c 20 62 75 74 20 69 66 20 74  voided, but if t
b6d0: 68 65 72 65 20 61 72 65 20 73 65 63 75 72 69 74  here are securit
b6e0: 79 0a 09 09 20 2a 20 63 6f 6e 63 65 72 6e 73 20  y... * concerns 
b6f0: 73 75 69 64 20 63 61 6e 20 62 65 20 64 69 73 61  suid can be disa
b700: 62 6c 65 64 20 63 6f 6d 70 6c 65 74 65 6c 79 20  bled completely 
b710: 6f 6e 20 74 68 65 20 63 6f 6d 6d 61 6e 64 6c 69  on the commandli
b720: 6e 65 0a 09 09 20 2a 2f 0a 09 09 66 75 73 65 5f  ne... */...fuse_
b730: 6f 70 74 5f 70 61 72 73 65 28 61 72 67 73 2c 20  opt_parse(args, 
b740: 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  NULL, NULL, NULL
b750: 29 3b 0a 09 09 66 75 73 65 5f 6f 70 74 5f 61 64  );...fuse_opt_ad
b760: 64 5f 61 72 67 28 61 72 67 73 2c 20 22 2d 6f 73  d_arg(args, "-os
b770: 75 69 64 22 29 3b 0a 09 7d 0a 0a 09 77 68 69 6c  uid");..}...whil
b780: 65 20 28 28 63 68 20 3d 20 67 65 74 6f 70 74 28  e ((ch = getopt(
b790: 61 72 67 63 2c 20 61 72 67 76 2c 20 22 64 66 73  argc, argv, "dfs
b7a0: 68 76 6f 3a 22 29 29 20 21 3d 20 2d 31 29 20 7b  hvo:")) != -1) {
b7b0: 0a 09 09 73 77 69 74 63 68 20 28 63 68 29 20 7b  ...switch (ch) {
b7c0: 0a 09 09 09 63 61 73 65 20 27 76 27 3a 0a 09 09  ....case 'v':...
b7d0: 09 09 2f 2a 20 49 67 6e 6f 72 65 64 20 2a 2f 0a  ../* Ignored */.
b7e0: 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61  ....break;....ca
b7f0: 73 65 20 27 6f 27 3a 0a 09 09 09 09 6f 70 74 73  se 'o':.....opts
b800: 74 72 5f 6e 65 78 74 20 3d 20 6f 70 74 73 74 72  tr_next = optstr
b810: 20 3d 20 6f 70 74 73 74 72 5f 73 20 3d 20 73 74   = optstr_s = st
b820: 72 64 75 70 28 6f 70 74 61 72 67 29 3b 0a 0a 09  rdup(optarg);...
b830: 09 09 09 77 68 69 6c 65 20 28 31 29 20 7b 0a 09  ...while (1) {..
b840: 09 09 09 09 6f 70 74 73 74 72 20 3d 20 6f 70 74  ....optstr = opt
b850: 73 74 72 5f 6e 65 78 74 3b 0a 0a 09 09 09 09 09  str_next;.......
b860: 69 66 20 28 21 6f 70 74 73 74 72 29 20 7b 0a 09  if (!optstr) {..
b870: 09 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 09  .....break;.....
b880: 09 7d 0a 0a 09 09 09 09 09 6f 70 74 73 74 72 5f  .}.......optstr_
b890: 6e 65 78 74 20 3d 20 73 74 72 63 68 72 28 6f 70  next = strchr(op
b8a0: 74 73 74 72 2c 20 27 2c 27 29 3b 0a 09 09 09 09  tstr, ',');.....
b8b0: 09 69 66 20 28 6f 70 74 73 74 72 5f 6e 65 78 74  .if (optstr_next
b8c0: 29 20 7b 0a 09 09 09 09 09 09 2a 6f 70 74 73 74  ) {.......*optst
b8d0: 72 5f 6e 65 78 74 20 3d 20 27 5c 30 27 3b 0a 09  r_next = '\0';..
b8e0: 09 09 09 09 09 6f 70 74 73 74 72 5f 6e 65 78 74  .....optstr_next
b8f0: 2b 2b 3b 0a 09 09 09 09 09 7d 0a 0a 09 09 09 09  ++;......}......
b900: 09 69 66 20 28 73 74 72 63 6d 70 28 6f 70 74 73  .if (strcmp(opts
b910: 74 72 2c 20 22 6e 6f 74 68 72 65 61 64 73 22 29  tr, "nothreads")
b920: 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09 09 41   == 0) {.......A
b930: 50 50 46 53 5f 44 45 42 55 47 28 22 50 61 73 73  PPFS_DEBUG("Pass
b940: 69 6e 67 20 6f 70 74 69 6f 6e 20 74 6f 20 46 55  ing option to FU
b950: 53 45 3a 20 2d 73 22 29 3b 0a 0a 09 09 09 09 09  SE: -s");.......
b960: 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28  .fuse_opt_parse(
b970: 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  args, NULL, NULL
b980: 2c 20 4e 55 4c 4c 29 3b 0a 09 09 09 09 09 09 66  , NULL);.......f
b990: 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28  use_opt_add_arg(
b9a0: 61 72 67 73 2c 20 22 2d 73 22 29 3b 0a 0a 09 09  args, "-s");....
b9b0: 09 09 09 09 61 70 70 66 73 5f 74 68 72 65 61 64  ....appfs_thread
b9c0: 65 64 5f 74 63 6c 20 3d 20 30 3b 0a 09 09 09 09  ed_tcl = 0;.....
b9d0: 09 7d 20 65 6c 73 65 20 69 66 20 28 73 74 72 63  .} else if (strc
b9e0: 6d 70 28 6f 70 74 73 74 72 2c 20 22 61 6c 6c 6f  mp(optstr, "allo
b9f0: 77 5f 6f 74 68 65 72 22 29 20 3d 3d 20 30 29 20  w_other") == 0) 
ba00: 7b 0a 09 09 09 09 09 09 41 50 50 46 53 5f 44 45  {.......APPFS_DE
ba10: 42 55 47 28 22 50 61 73 73 69 6e 67 20 6f 70 74  BUG("Passing opt
ba20: 69 6f 6e 20 74 6f 20 46 55 53 45 3a 20 2d 6f 20  ion to FUSE: -o 
ba30: 61 6c 6c 6f 77 5f 4f 74 68 65 72 22 29 3b 0a 0a  allow_Other");..
ba40: 09 09 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 70  ......fuse_opt_p
ba50: 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c  arse(args, NULL,
ba60: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09   NULL, NULL);...
ba70: 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64  ....fuse_opt_add
ba80: 5f 61 72 67 28 61 72 67 73 2c 20 22 2d 6f 61 6c  _arg(args, "-oal
ba90: 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 09 09 09  low_other");....
baa0: 09 09 7d 20 65 6c 73 65 20 69 66 20 28 73 74 72  ..} else if (str
bab0: 63 6d 70 28 6f 70 74 73 74 72 2c 20 22 72 77 22  cmp(optstr, "rw"
bac0: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09 09  ) == 0) {.......
bad0: 2f 2a 20 49 67 6e 6f 72 65 64 20 2a 2f 0a 09 09  /* Ignored */...
bae0: 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09  ...} else {.....
baf0: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
bb00: 2c 20 22 61 70 70 66 73 64 3a 20 69 6e 76 61 6c  , "appfsd: inval
bb10: 69 64 20 6f 70 74 69 6f 6e 3a 20 5c 22 2d 6f 20  id option: \"-o 
bb20: 25 73 5c 22 5c 6e 22 2c 20 6f 70 74 73 74 72 29  %s\"\n", optstr)
bb30: 3b 0a 0a 09 09 09 09 09 09 66 72 65 65 28 6f 70  ;........free(op
bb40: 74 73 74 72 5f 73 29 3b 0a 0a 09 09 09 09 09 09  tstr_s);........
bb50: 72 65 74 75 72 6e 28 31 29 3b 0a 09 09 09 09 09  return(1);......
bb60: 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66 72 65  }.....}......fre
bb70: 65 28 6f 70 74 73 74 72 5f 73 29 3b 0a 0a 09 09  e(optstr_s);....
bb80: 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65  ..break;....case
bb90: 20 27 64 27 3a 0a 09 09 09 63 61 73 65 20 27 66   'd':....case 'f
bba0: 27 3a 0a 09 09 09 63 61 73 65 20 27 73 27 3a 0a  ':....case 's':.
bbb0: 09 09 09 09 69 66 20 28 63 68 20 3d 3d 20 27 73  ....if (ch == 's
bbc0: 27 29 20 7b 0a 09 09 09 09 09 61 70 70 66 73 5f  ') {......appfs_
bbd0: 74 68 72 65 61 64 65 64 5f 74 63 6c 20 3d 20 30  threaded_tcl = 0
bbe0: 3b 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66 61 6b  ;.....}......fak
bbf0: 65 5f 61 72 67 5b 31 5d 20 3d 20 63 68 3b 0a 0a  e_arg[1] = ch;..
bc00: 09 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
bc10: 22 50 61 73 73 69 6e 67 20 6f 70 74 69 6f 6e 20  "Passing option 
bc20: 74 6f 20 46 55 53 45 3a 20 25 73 22 2c 20 66 61  to FUSE: %s", fa
bc30: 6b 65 5f 61 72 67 29 3b 0a 0a 09 09 09 09 66 75  ke_arg);......fu
bc40: 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67  se_opt_parse(arg
bc50: 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e  s, NULL, NULL, N
bc60: 55 4c 4c 29 3b 0a 09 09 09 09 66 75 73 65 5f 6f  ULL);.....fuse_o
bc70: 70 74 5f 61 64 64 5f 61 72 67 28 61 72 67 73 2c  pt_add_arg(args,
bc80: 20 66 61 6b 65 5f 61 72 67 29 3b 0a 09 09 09 09   fake_arg);.....
bc90: 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27  break;....case '
bca0: 68 27 3a 0a 09 09 09 09 61 70 70 66 73 5f 70 72  h':.....appfs_pr
bcb0: 69 6e 74 5f 68 65 6c 70 28 73 74 64 6f 75 74 29  int_help(stdout)
bcc0: 3b 0a 0a 09 09 09 09 72 65 74 75 72 6e 28 2d 31  ;......return(-1
bcd0: 29 3b 0a 09 09 09 63 61 73 65 20 27 3a 27 3a 0a  );....case ':':.
bce0: 09 09 09 63 61 73 65 20 27 3f 27 3a 0a 09 09 09  ...case '?':....
bcf0: 64 65 66 61 75 6c 74 3a 0a 09 09 09 09 61 70 70  default:.....app
bd00: 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28 73 74  fs_print_help(st
bd10: 64 65 72 72 29 3b 0a 0a 09 09 09 09 72 65 74 75  derr);......retu
bd20: 72 6e 28 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09  rn(1);...}..}...
bd30: 69 66 20 28 28 6f 70 74 69 6e 64 20 2b 20 32 29  if ((optind + 2)
bd40: 20 21 3d 20 61 72 67 63 29 20 7b 0a 09 09 69 66   != argc) {...if
bd50: 20 28 28 6f 70 74 69 6e 64 20 2b 20 32 29 20 3c   ((optind + 2) <
bd60: 20 61 72 67 63 29 20 7b 0a 09 09 09 66 70 72 69   argc) {....fpri
bd70: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54 6f 6f  ntf(stderr, "Too
bd80: 20 6d 61 6e 79 20 61 72 67 75 6d 65 6e 74 73 5c   many arguments\
bd90: 6e 22 29 3b 0a 09 09 7d 20 65 6c 73 65 20 7b 0a  n");...} else {.
bda0: 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
bdb0: 72 2c 20 22 4d 69 73 73 69 6e 67 20 63 61 63 68  r, "Missing cach
bdc0: 65 64 69 72 20 6f 72 20 6d 6f 75 6e 74 70 6f 69  edir or mountpoi
bdd0: 6e 74 5c 6e 22 29 3b 0a 09 09 7d 0a 0a 09 09 61  nt\n");...}....a
bde0: 70 70 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28  ppfs_print_help(
bdf0: 73 74 64 65 72 72 29 3b 0a 0a 09 09 72 65 74 75  stderr);....retu
be00: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  rn(1);..}.../*..
be10: 20 2a 20 53 65 74 20 63 61 63 68 65 20 64 69 72   * Set cache dir
be20: 20 61 73 20 66 69 72 73 74 20 61 72 67 75 6d 65   as first argume
be30: 6e 74 20 28 74 68 65 20 22 64 65 76 69 63 65 22  nt (the "device"
be40: 2c 20 65 73 73 65 6e 74 69 61 6c 6c 79 29 0a 09  , essentially)..
be50: 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65   */..appfs_cache
be60: 64 69 72 20 3d 20 61 72 67 76 5b 6f 70 74 69 6e  dir = argv[optin
be70: 64 5d 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 50 61 73  d];.../*.. * Pas
be80: 73 20 74 68 65 20 72 65 6d 61 69 6e 69 6e 67 20  s the remaining 
be90: 61 72 67 75 6d 65 6e 74 20 74 6f 20 46 55 53 45  argument to FUSE
bea0: 20 61 73 20 74 68 65 20 64 69 72 65 63 74 6f 72   as the director
beb0: 79 0a 09 20 2a 2f 0a 09 66 75 73 65 5f 6f 70 74  y.. */..fuse_opt
bec0: 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c  _parse(args, NUL
bed0: 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  L, NULL, NULL);.
bee0: 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72  .fuse_opt_add_ar
bef0: 67 28 61 72 67 73 2c 20 61 72 67 76 5b 6f 70 74  g(args, argv[opt
bf00: 69 6e 64 20 2b 20 31 5d 29 3b 0a 0a 09 72 65 74  ind + 1]);...ret
bf10: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 20  urn(0);.}.../*. 
bf20: 2a 20 46 55 53 45 20 6f 70 65 72 61 74 69 6f 6e  * FUSE operation
bf30: 73 20 73 74 72 75 63 74 75 72 65 0a 20 2a 2f 0a  s structure. */.
bf40: 73 74 61 74 69 63 20 73 74 72 75 63 74 20 66 75  static struct fu
bf50: 73 65 5f 6f 70 65 72 61 74 69 6f 6e 73 20 61 70  se_operations ap
bf60: 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 20 3d  pfs_operations =
bf70: 20 7b 0a 09 2e 67 65 74 61 74 74 72 20 20 20 3d   {...getattr   =
bf80: 20 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74 61   appfs_fuse_geta
bf90: 74 74 72 2c 0a 09 2e 72 65 61 64 64 69 72 20 20  ttr,...readdir  
bfa0: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65   = appfs_fuse_re
bfb0: 61 64 64 69 72 2c 0a 09 2e 72 65 61 64 6c 69 6e  addir,...readlin
bfc0: 6b 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f  k  = appfs_fuse_
bfd0: 72 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f 70 65 6e  readlink,...open
bfe0: 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75        = appfs_fu
bff0: 73 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65 6c 65 61  se_open,...relea
c000: 73 65 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73  se   = appfs_fus
c010: 65 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65 61 64 20  e_close,...read 
c020: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
c030: 65 5f 72 65 61 64 2c 0a 09 2e 77 72 69 74 65 20  e_read,...write 
c040: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
c050: 5f 77 72 69 74 65 2c 0a 09 2e 6d 6b 6e 6f 64 20  _write,...mknod 
c060: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
c070: 5f 6d 6b 6e 6f 64 2c 0a 09 2e 63 72 65 61 74 65  _mknod,...create
c080: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
c090: 5f 63 72 65 61 74 65 2c 0a 09 2e 74 72 75 6e 63  _create,...trunc
c0a0: 61 74 65 20 20 3d 20 61 70 70 66 73 5f 66 75 73  ate  = appfs_fus
c0b0: 65 5f 74 72 75 6e 63 61 74 65 2c 0a 09 2e 75 6e  e_truncate,...un
c0c0: 6c 69 6e 6b 20 20 20 20 3d 20 61 70 70 66 73 5f  link    = appfs_
c0d0: 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69  fuse_unlink_rmdi
c0e0: 72 2c 0a 09 2e 72 6d 64 69 72 20 20 20 20 20 3d  r,...rmdir     =
c0f0: 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69   appfs_fuse_unli
c100: 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 6d 6b 64 69  nk_rmdir,...mkdi
c110: 72 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  r     = appfs_fu
c120: 73 65 5f 6d 6b 64 69 72 2c 0a 09 2e 63 68 6d 6f  se_mkdir,...chmo
c130: 64 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  d     = appfs_fu
c140: 73 65 5f 63 68 6d 6f 64 2c 0a 09 2e 73 79 6d 6c  se_chmod,...syml
c150: 69 6e 6b 20 20 20 3d 20 61 70 70 66 73 5f 66 75  ink   = appfs_fu
c160: 73 65 5f 73 79 6d 6c 69 6e 6b 2c 0a 7d 3b 0a 0a  se_symlink,.};..
c170: 2f 2a 0a 20 2a 20 45 6e 74 72 79 20 70 6f 69 6e  /*. * Entry poin
c180: 74 20 69 6e 74 6f 20 74 68 69 73 20 70 72 6f 67  t into this prog
c190: 72 61 6d 2e 0a 20 2a 2f 0a 69 6e 74 20 6d 61 69  ram.. */.int mai
c1a0: 6e 28 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72  n(int argc, char
c1b0: 20 2a 2a 61 72 67 76 29 20 7b 0a 09 54 63 6c 5f   **argv) {..Tcl_
c1c0: 49 6e 74 65 72 70 20 2a 74 65 73 74 5f 69 6e 74  Interp *test_int
c1d0: 65 72 70 3b 0a 09 63 68 61 72 20 2a 74 65 73 74  erp;..char *test
c1e0: 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 3b 0a 09  _interp_error;..
c1f0: 73 74 72 75 63 74 20 66 75 73 65 5f 61 72 67 73  struct fuse_args
c200: 20 61 72 67 73 20 3d 20 46 55 53 45 5f 41 52 47   args = FUSE_ARG
c210: 53 5f 49 4e 49 54 28 30 2c 20 4e 55 4c 4c 29 3b  S_INIT(0, NULL);
c220: 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65  ..int pthread_re
c230: 74 2c 20 61 6f 70 5f 72 65 74 3b 0a 09 76 6f 69  t, aop_ret;..voi
c240: 64 20 2a 73 69 67 6e 61 6c 5f 72 65 74 3b 0a 09  d *signal_ret;..
c250: 63 68 61 72 20 2a 61 72 67 76 30 3b 0a 0a 09 2f  char *argv0;.../
c260: 2a 0a 09 20 2a 20 53 6b 69 70 20 70 61 73 73 65  *.. * Skip passe
c270: 64 20 70 72 6f 67 72 61 6d 20 6e 61 6d 65 0a 09  d program name..
c280: 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d   */..if (argc ==
c290: 20 30 20 7c 7c 20 61 72 67 76 20 3d 3d 20 4e 55   0 || argv == NU
c2a0: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 31  LL) {...return(1
c2b0: 29 3b 0a 09 7d 0a 0a 09 61 72 67 76 30 20 3d 20  );..}...argv0 = 
c2c0: 61 72 67 76 5b 30 5d 3b 0a 0a 09 61 72 67 63 2d  argv[0];...argc-
c2d0: 2d 3b 0a 09 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a  -;..argv++;.../*
c2e0: 0a 09 20 2a 20 53 65 74 20 61 70 70 72 6f 70 72  .. * Set appropr
c2f0: 69 61 74 65 20 75 6d 61 73 6b 0a 09 20 2a 2f 0a  iate umask.. */.
c300: 09 75 6d 61 73 6b 28 30 32 32 29 3b 0a 0a 09 2f  .umask(022);.../
c310: 2a 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c  *.. * Set global
c320: 20 76 61 72 69 61 62 6c 65 73 2c 20 74 68 65 73   variables, thes
c330: 65 20 73 68 6f 75 6c 64 20 62 65 20 63 6f 6e 66  e should be conf
c340: 69 67 75 72 61 74 69 6f 6e 20 6f 70 74 69 6f 6e  iguration option
c350: 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63  s... */..appfs_c
c360: 61 63 68 65 64 69 72 20 3d 20 41 50 50 46 53 5f  achedir = APPFS_
c370: 43 41 43 48 45 44 49 52 3b 0a 0a 09 2f 2a 0a 09  CACHEDIR;.../*..
c380: 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61   * Set global va
c390: 72 69 61 62 6c 65 20 66 6f 72 20 22 62 6f 6f 74  riable for "boot
c3a0: 20 74 69 6d 65 22 20 74 6f 20 73 65 74 20 61 20   time" to set a 
c3b0: 74 69 6d 65 20 6f 6e 20 64 69 72 65 63 74 6f 72  time on director
c3c0: 69 65 73 0a 09 20 2a 20 74 68 61 74 20 77 65 20  ies.. * that we 
c3d0: 66 61 6b 65 2e 0a 09 20 2a 2f 0a 09 61 70 70 66  fake... */..appf
c3e0: 73 5f 62 6f 6f 74 74 69 6d 65 20 3d 20 74 69 6d  s_boottime = tim
c3f0: 65 28 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20  e(NULL);.../*.. 
c400: 2a 20 52 65 67 69 73 74 65 72 20 22 73 68 61 31  * Register "sha1
c410: 22 20 61 6e 64 20 22 61 70 70 66 73 64 22 20 70  " and "appfsd" p
c420: 61 63 6b 61 67 65 20 77 69 74 68 20 6c 69 62 74  ackage with libt
c430: 63 6c 20 73 6f 20 74 68 61 74 20 61 6e 79 20 6e  cl so that any n
c440: 65 77 0a 09 20 2a 20 69 6e 74 65 72 70 72 65 74  ew.. * interpret
c450: 65 72 73 20 63 72 65 61 74 65 64 20 28 77 68 69  ers created (whi
c460: 63 68 20 61 72 65 20 64 6f 6e 65 20 64 79 6e 61  ch are done dyna
c470: 6d 69 63 61 6c 6c 79 20 62 79 20 46 55 53 45 29  mically by FUSE)
c480: 20 63 61 6e 20 68 61 76 65 0a 09 20 2a 20 74 68   can have.. * th
c490: 65 20 61 70 70 72 6f 70 72 69 61 74 65 20 63 6f  e appropriate co
c4a0: 6e 66 69 67 75 72 61 74 69 6f 6e 20 64 6f 6e 65  nfiguration done
c4b0: 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a   automatically..
c4c0: 09 20 2a 2f 0a 09 54 63 6c 5f 53 74 61 74 69 63  . */..Tcl_Static
c4d0: 50 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 73  Package(NULL, "s
c4e0: 68 61 31 22 2c 20 53 68 61 31 5f 49 6e 69 74 2c  ha1", Sha1_Init,
c4f0: 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 53 74 61   NULL);..Tcl_Sta
c500: 74 69 63 50 61 63 6b 61 67 65 28 4e 55 4c 4c 2c  ticPackage(NULL,
c510: 20 22 61 70 70 66 73 64 22 2c 20 41 70 70 66 73   "appfsd", Appfs
c520: 64 5f 49 6e 69 74 2c 20 4e 55 4c 4c 29 3b 0a 0a  d_Init, NULL);..
c530: 09 2f 2a 0a 09 20 2a 20 43 72 65 61 74 65 20 61  ./*.. * Create a
c540: 20 74 68 72 65 61 64 2d 73 70 65 63 69 66 69 63   thread-specific
c550: 2d 64 61 74 61 20 28 54 53 44 29 20 6b 65 79 20  -data (TSD) key 
c560: 66 6f 72 20 65 61 63 68 20 74 68 72 65 61 64 20  for each thread 
c570: 74 6f 20 72 65 66 65 72 0a 09 20 2a 20 74 6f 20  to refer.. * to 
c580: 69 74 73 20 6f 77 6e 20 54 63 6c 20 69 6e 74 65  its own Tcl inte
c590: 72 70 72 65 74 65 72 2e 20 20 54 63 6c 20 69 6e  rpreter.  Tcl in
c5a0: 74 65 72 70 72 65 74 65 72 73 20 6d 75 73 74 20  terpreters must 
c5b0: 62 65 20 75 6e 69 71 75 65 20 70 65 72 0a 09 20  be unique per.. 
c5c0: 2a 20 74 68 72 65 61 64 20 61 6e 64 20 6e 65 77  * thread and new
c5d0: 20 74 68 72 65 61 64 73 20 61 72 65 20 64 79 6e   threads are dyn
c5e0: 61 6d 69 63 61 6c 6c 79 20 63 72 65 61 74 65 64  amically created
c5f0: 20 62 79 20 46 55 53 45 2e 0a 09 20 2a 2f 0a 09   by FUSE... */..
c600: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
c610: 68 72 65 61 64 5f 6b 65 79 5f 63 72 65 61 74 65  hread_key_create
c620: 28 26 69 6e 74 65 72 70 4b 65 79 2c 20 61 70 70  (&interpKey, app
c630: 66 73 5f 74 65 72 6d 69 6e 61 74 65 5f 69 6e 74  fs_terminate_int
c640: 65 72 70 5f 61 6e 64 5f 74 68 72 65 61 64 29 3b  erp_and_thread);
c650: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
c660: 74 20 21 3d 20 30 29 20 7b 0a 09 09 66 70 72 69  t != 0) {...fpri
c670: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61  ntf(stderr, "Una
c680: 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54 53  ble to create TS
c690: 44 20 6b 65 79 20 66 6f 72 20 54 63 6c 2e 20 20  D key for Tcl.  
c6a0: 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a  Aborting.\n");..
c6b0: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
c6c0: 0a 09 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61 6c 6c  ../*.. * Manuall
c6d0: 79 20 73 70 65 63 69 66 79 20 63 61 63 68 65 20  y specify cache 
c6e0: 64 69 72 65 63 74 6f 72 79 2c 20 77 69 74 68 6f  directory, witho
c6f0: 75 74 20 46 55 53 45 20 63 61 6c 6c 62 61 63 6b  ut FUSE callback
c700: 0a 09 20 2a 20 54 68 69 73 20 6f 70 74 69 6f 6e  .. * This option
c710: 20 6f 6e 6c 79 20 77 6f 72 6b 73 20 77 68 65 6e   only works when
c720: 20 6e 6f 74 20 75 73 69 6e 67 20 46 55 53 45 2c   not using FUSE,
c730: 20 73 69 6e 63 65 20 77 65 0a 09 20 2a 20 64 6f   since we.. * do
c740: 20 6e 6f 74 20 70 72 6f 63 65 73 73 20 69 74 20   not process it 
c750: 77 69 74 68 20 46 55 53 45 73 20 6f 70 74 69 6f  with FUSEs optio
c760: 6e 20 70 72 6f 63 65 73 73 69 6e 67 2e 0a 09 20  n processing... 
c770: 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3e 3d 20  */..if (argc >= 
c780: 32 29 20 7b 0a 09 09 69 66 20 28 73 74 72 63 6d  2) {...if (strcm
c790: 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 63 61  p(argv[0], "--ca
c7a0: 63 68 65 64 69 72 22 29 20 3d 3d 20 30 29 20 7b  chedir") == 0) {
c7b0: 0a 09 09 09 61 70 70 66 73 5f 63 61 63 68 65 64  ....appfs_cached
c7c0: 69 72 20 3d 20 73 74 72 64 75 70 28 61 72 67 76  ir = strdup(argv
c7d0: 5b 31 5d 29 3b 0a 0a 09 09 09 61 72 67 63 20 2d  [1]);.....argc -
c7e0: 3d 20 32 3b 0a 09 09 09 61 72 67 76 20 2b 3d 20  = 2;....argv += 
c7f0: 32 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09  2;...}..}.../*..
c800: 20 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 2c   * SQLite3 mode,
c810: 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77   for running raw
c820: 20 53 51 4c 20 61 67 61 69 6e 73 74 20 74 68 65   SQL against the
c830: 20 63 61 63 68 65 20 64 61 74 61 62 61 73 65 0a   cache database.
c840: 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d  . */..if (argc =
c850: 3d 20 32 20 26 26 20 73 74 72 63 6d 70 28 61 72  = 2 && strcmp(ar
c860: 67 76 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69 74 65  gv[0], "--sqlite
c870: 33 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65  3") == 0) {...re
c880: 74 75 72 6e 28 61 70 70 66 73 5f 73 71 6c 69 74  turn(appfs_sqlit
c890: 65 33 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d  e3(argv[1]));..}
c8a0: 0a 0a 09 2f 2a 0a 09 20 2a 20 54 63 6c 20 6d 6f  .../*.. * Tcl mo
c8b0: 64 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20  de, for running 
c8c0: 72 61 77 20 54 63 6c 20 69 6e 20 74 68 65 20 73  raw Tcl in the s
c8d0: 61 6d 65 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20  ame environment 
c8e0: 41 70 70 46 53 64 20 77 6f 75 6c 64 0a 09 20 2a  AppFSd would.. *
c8f0: 20 72 75 6e 20 63 6f 64 65 2e 0a 09 20 2a 2f 0a   run code... */.
c900: 09 69 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26  .if (argc == 2 &
c910: 26 20 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d  & strcmp(argv[0]
c920: 2c 20 22 2d 2d 74 63 6c 22 29 20 3d 3d 20 30 29  , "--tcl") == 0)
c930: 20 7b 0a 09 09 72 65 74 75 72 6e 28 61 70 70 66   {...return(appf
c940: 73 5f 74 63 6c 28 61 72 67 76 5b 31 5d 29 29 3b  s_tcl(argv[1]));
c950: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 67  ..}.../*.. * Reg
c960: 69 73 74 65 72 20 61 20 73 69 67 6e 61 6c 20 68  ister a signal h
c970: 61 6e 64 6c 65 72 20 66 6f 72 20 68 6f 74 2d 72  andler for hot-r
c980: 65 73 74 61 72 74 20 72 65 71 75 65 73 74 73 0a  estart requests.
c990: 09 20 2a 2f 0a 09 73 69 67 6e 61 6c 5f 72 65 74  . */..signal_ret
c9a0: 20 3d 20 73 69 67 6e 61 6c 28 53 49 47 48 55 50   = signal(SIGHUP
c9b0: 2c 20 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f 68  , appfs_signal_h
c9c0: 61 6e 64 6c 65 72 29 3b 0a 09 69 66 20 28 73 69  andler);..if (si
c9d0: 67 6e 61 6c 5f 72 65 74 20 3d 3d 20 53 49 47 5f  gnal_ret == SIG_
c9e0: 45 52 52 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  ERR) {...fprintf
c9f0: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
ca00: 20 74 6f 20 69 6e 73 74 61 6c 6c 20 73 69 67 6e   to install sign
ca10: 61 6c 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 68  al handler for h
ca20: 6f 74 2d 72 65 73 74 61 72 74 5c 6e 22 29 3b 0a  ot-restart\n");.
ca30: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
ca40: 2c 20 22 48 6f 74 2d 72 65 73 74 61 72 74 20 77  , "Hot-restart w
ca50: 69 6c 6c 20 6e 6f 74 20 62 65 20 61 76 61 69 6c  ill not be avail
ca60: 61 62 6c 65 2e 5c 6e 22 29 3b 0a 09 7d 0a 0a 09  able.\n");..}...
ca70: 2f 2a 0a 09 20 2a 20 50 61 72 73 65 20 63 6f 6d  /*.. * Parse com
ca80: 6d 61 6e 64 20 6c 69 6e 65 20 61 72 67 75 6d 65  mand line argume
ca90: 6e 74 73 0a 09 20 2a 2f 0a 09 2f 2a 2a 0a 09 20  nts.. */../**.. 
caa0: 2a 2a 20 52 65 73 74 6f 72 65 20 61 72 67 63 2f  ** Restore argc/
cab0: 61 72 67 76 20 74 6f 20 6f 72 69 67 69 6e 61 6c  argv to original
cac0: 20 76 61 6c 75 65 73 2c 20 72 65 70 6c 61 63 69   values, replaci
cad0: 6e 67 20 61 72 67 76 5b 30 5d 20 69 6e 20 63 61  ng argv[0] in ca
cae0: 73 65 0a 09 20 2a 2a 20 69 74 20 77 61 73 20 6d  se.. ** it was m
caf0: 6f 69 66 69 65 64 20 62 79 20 2d 2d 63 61 63 68  oified by --cach
cb00: 65 64 69 72 20 6f 70 74 69 6f 6e 2e 0a 09 20 2a  edir option... *
cb10: 2a 2f 0a 09 61 72 67 63 2b 2b 3b 0a 09 61 72 67  */..argc++;..arg
cb20: 76 2d 2d 3b 0a 09 61 72 67 76 5b 30 5d 20 3d 20  v--;..argv[0] = 
cb30: 61 72 67 76 30 3b 0a 0a 09 2f 2a 2a 0a 09 20 2a  argv0;.../**.. *
cb40: 2a 20 50 65 72 66 6f 72 6d 20 74 68 65 20 61 72  * Perform the ar
cb50: 67 75 6d 65 6e 74 20 70 61 72 73 69 6e 67 0a 09  gument parsing..
cb60: 20 2a 2a 2f 0a 09 61 6f 70 5f 72 65 74 20 3d 20   **/..aop_ret = 
cb70: 61 70 70 66 73 5f 6f 70 74 5f 70 61 72 73 65 28  appfs_opt_parse(
cb80: 61 72 67 63 2c 20 61 72 67 76 2c 20 26 61 72 67  argc, argv, &arg
cb90: 73 29 3b 0a 09 69 66 20 28 61 6f 70 5f 72 65 74  s);..if (aop_ret
cba0: 20 21 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 61   != 0) {...if (a
cbb0: 6f 70 5f 72 65 74 20 3c 20 30 29 20 7b 0a 09 09  op_ret < 0) {...
cbc0: 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 09 7d 0a  .return(0);...}.
cbd0: 0a 09 09 72 65 74 75 72 6e 28 61 6f 70 5f 72 65  ...return(aop_re
cbe0: 74 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20  t);..}.../*.. * 
cbf0: 43 72 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74  Create a Tcl int
cc00: 65 72 70 72 65 74 65 72 20 6a 75 73 74 20 74 6f  erpreter just to
cc10: 20 76 65 72 69 66 79 20 74 68 61 74 20 74 68 69   verify that thi
cc20: 6e 67 73 20 61 72 65 20 69 6e 20 77 6f 72 6b 69  ngs are in worki
cc30: 6e 67 20 0a 09 20 2a 20 6f 72 64 65 72 20 62 65  ng .. * order be
cc40: 66 6f 72 65 20 77 65 20 62 65 63 6f 6d 65 20 61  fore we become a
cc50: 20 64 61 65 6d 6f 6e 2e 0a 09 20 2a 2f 0a 09 74   daemon... */..t
cc60: 65 73 74 5f 69 6e 74 65 72 70 20 3d 20 61 70 70  est_interp = app
cc70: 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74  fs_create_TclInt
cc80: 65 72 70 28 26 74 65 73 74 5f 69 6e 74 65 72 70  erp(&test_interp
cc90: 5f 65 72 72 6f 72 29 3b 0a 09 69 66 20 28 74 65  _error);..if (te
cca0: 73 74 5f 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  st_interp == NUL
ccb0: 4c 29 20 7b 0a 09 09 69 66 20 28 74 65 73 74 5f  L) {...if (test_
ccc0: 69 6e 74 65 72 70 5f 65 72 72 6f 72 20 3d 3d 20  interp_error == 
ccd0: 4e 55 4c 4c 29 20 7b 0a 09 09 09 74 65 73 74 5f  NULL) {....test_
cce0: 69 6e 74 65 72 70 5f 65 72 72 6f 72 20 3d 20 22  interp_error = "
ccf0: 55 6e 6b 6e 6f 77 6e 20 65 72 72 6f 72 22 3b 0a  Unknown error";.
cd00: 09 09 7d 0a 0a 09 09 66 70 72 69 6e 74 66 28 73  ..}....fprintf(s
cd10: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
cd20: 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c  o initialize Tcl
cd30: 20 69 6e 74 65 72 70 72 65 74 65 72 20 66 6f 72   interpreter for
cd40: 20 41 70 70 46 53 64 3a 5c 6e 22 29 3b 0a 09 09   AppFSd:\n");...
cd50: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
cd60: 22 25 73 5c 6e 22 2c 20 74 65 73 74 5f 69 6e 74  "%s\n", test_int
cd70: 65 72 70 5f 65 72 72 6f 72 29 3b 0a 0a 09 09 72  erp_error);....r
cd80: 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 54  eturn(1);..}...T
cd90: 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28  cl_DeleteInterp(
cda0: 74 65 73 74 5f 69 6e 74 65 72 70 29 3b 0a 0a 09  test_interp);...
cdb0: 69 66 20 28 61 70 70 66 73 5f 74 68 72 65 61 64  if (appfs_thread
cdc0: 65 64 5f 74 63 6c 29 20 7b 0a 09 09 54 63 6c 5f  ed_tcl) {...Tcl_
cdd0: 46 69 6e 61 6c 69 7a 65 4e 6f 74 69 66 69 65 72  FinalizeNotifier
cde0: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a  (NULL);..}.../*.
cdf0: 09 20 2a 20 45 6e 74 65 72 20 74 68 65 20 46 55  . * Enter the FU
ce00: 53 45 20 6d 61 69 6e 20 6c 6f 6f 70 20 2d 2d 20  SE main loop -- 
ce10: 74 68 69 73 20 77 69 6c 6c 20 70 72 6f 63 65 73  this will proces
ce20: 73 20 61 6e 79 20 61 72 67 75 6d 65 6e 74 73 0a  s any arguments.
ce30: 09 20 2a 20 61 6e 64 20 73 74 61 72 74 20 73 65  . * and start se
ce40: 72 76 69 63 69 6e 67 20 72 65 71 75 65 73 74 73  rvicing requests
ce50: 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 66 75  ... */..appfs_fu
ce60: 73 65 5f 73 74 61 72 74 65 64 20 3d 20 31 3b 0a  se_started = 1;.
ce70: 09 72 65 74 75 72 6e 28 66 75 73 65 5f 6d 61 69  .return(fuse_mai
ce80: 6e 28 61 72 67 73 2e 61 72 67 63 2c 20 61 72 67  n(args.argc, arg
ce90: 73 2e 61 72 67 76 2c 20 26 61 70 70 66 73 5f 6f  s.argv, &appfs_o
cea0: 70 65 72 61 74 69 6f 6e 73 2c 20 4e 55 4c 4c 29  perations, NULL)
ceb0: 29 3b 0a 7d 0a                                   );.}.