Hex Artifact Content

Artifact 6a6fdd4f927a6ffae34712d60c320842aafcacc0:


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 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20  th) {..unsigned 
3b40: 69 6e 74 20 72 65 74 76 61 6c 3b 0a 09 63 6f 6e  int retval;..con
3b50: 73 74 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72  st unsigned char
3b60: 20 2a 70 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20   *p;...retval = 
3b70: 32 31 36 36 31 33 36 32 36 31 3b 20 2f 2a 20 46  2166136261; /* F
3b80: 4e 56 2d 31 61 20 33 32 2d 62 69 74 20 6f 66 66  NV-1a 32-bit off
3b90: 73 65 74 5f 62 61 73 69 73 20 2a 2f 0a 0a 09 66  set_basis */...f
3ba0: 6f 72 20 28 70 20 3d 20 28 75 6e 73 69 67 6e 65  or (p = (unsigne
3bb0: 64 20 63 68 61 72 20 2a 29 20 70 61 74 68 3b 20  d char *) path; 
3bc0: 2a 70 3b 20 70 2b 2b 29 20 7b 0a 09 09 72 65 74  *p; p++) {...ret
3bd0: 76 61 6c 20 5e 3d 20 28 69 6e 74 29 20 2a 70 3b  val ^= (int) *p;
3be0: 0a 23 69 66 20 30 0a 09 09 72 65 74 76 61 6c 20  .#if 0...retval 
3bf0: 2a 3d 20 31 36 37 37 37 36 31 39 3b 20 2f 2a 20  *= 16777619; /* 
3c00: 46 4e 56 2d 31 61 20 33 32 2d 62 69 74 20 70 72  FNV-1a 32-bit pr
3c10: 69 6d 65 20 2a 2f 0a 23 65 6c 73 65 0a 09 09 2f  ime */.#else.../
3c20: 2a 20 47 43 43 20 4f 70 74 69 6d 69 7a 65 64 20  * GCC Optimized 
3c30: 72 65 70 6c 61 63 65 6d 65 6e 74 20 2a 2f 0a 09  replacement */..
3c40: 09 72 65 74 76 61 6c 20 2b 3d 20 28 72 65 74 76  .retval += (retv
3c50: 61 6c 20 3c 3c 20 31 29 20 2b 20 28 72 65 74 76  al << 1) + (retv
3c60: 61 6c 20 3c 3c 20 34 29 20 2b 20 28 72 65 74 76  al << 4) + (retv
3c70: 61 6c 20 3c 3c 20 37 29 20 2b 20 28 72 65 74 76  al << 7) + (retv
3c80: 61 6c 20 3c 3c 20 38 29 20 2b 20 28 72 65 74 76  al << 8) + (retv
3c90: 61 6c 20 3c 3c 20 32 34 29 3b 0a 23 65 6e 64 69  al << 24);.#endi
3ca0: 66 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65  f..}...return(re
3cb0: 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  tval);.}../*. * 
3cc0: 43 61 63 68 65 20 47 65 74 20 50 61 74 68 20 49  Cache Get Path I
3cd0: 6e 66 6f 20 6c 6f 6f 6b 75 70 73 20 66 6f 72 20  nfo lookups for 
3ce0: 73 70 65 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63  speed. */.static
3cf0: 20 69 6e 74 20 61 70 70 66 73 5f 67 65 74 5f 70   int appfs_get_p
3d00: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 67  ath_info_cache_g
3d10: 65 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  et(const char *p
3d20: 61 74 68 2c 20 75 69 64 5f 74 20 75 69 64 2c 20  ath, uid_t uid, 
3d30: 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74  struct appfs_pat
3d40: 68 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29  hinfo *pathinfo)
3d50: 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74   {..unsigned int
3d60: 20 68 61 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20   hash_idx;..int 
3d70: 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 09 69 6e  pthread_ret;..in
3d80: 74 20 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76  t retval;...retv
3d90: 61 6c 20 3d 20 31 3b 0a 0a 09 70 74 68 72 65 61  al = 1;...pthrea
3da0: 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f  d_ret = pthread_
3db0: 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66  mutex_lock(&appf
3dc0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
3dd0: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70  e_mutex);..if (p
3de0: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
3df0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
3e00: 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b  ("Unable to lock
3e10: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65   path_info cache
3e20: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72   mutex !");....r
3e30: 65 74 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09  eturn(-1);..}...
3e40: 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69  if (appfs_path_i
3e50: 6e 66 6f 5f 63 61 63 68 65 20 21 3d 20 4e 55 4c  nfo_cache != NUL
3e60: 4c 29 20 7b 0a 09 09 68 61 73 68 5f 69 64 78 20  L) {...hash_idx 
3e70: 3d 20 28 61 70 70 66 73 5f 67 65 74 5f 70 61 74  = (appfs_get_pat
3e80: 68 5f 69 6e 6f 64 65 28 70 61 74 68 29 20 2b 20  h_inode(path) + 
3e90: 75 69 64 29 20 25 20 61 70 70 66 73 5f 70 61 74  uid) % appfs_pat
3ea0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a  h_info_cache_siz
3eb0: 65 3b 0a 0a 09 09 69 66 20 28 61 70 70 66 73 5f  e;....if (appfs_
3ec0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
3ed0: 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65  hash_idx]._cache
3ee0: 5f 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b  _path != NULL) {
3ef0: 0a 09 09 09 69 66 20 28 73 74 72 63 6d 70 28 61  ....if (strcmp(a
3f00: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
3f10: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f  ache[hash_idx]._
3f20: 63 61 63 68 65 5f 70 61 74 68 2c 20 70 61 74 68  cache_path, path
3f30: 29 20 3d 3d 20 30 20 26 26 20 61 70 70 66 73 5f  ) == 0 && appfs_
3f40: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
3f50: 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65  hash_idx]._cache
3f60: 5f 75 69 64 20 3d 3d 20 75 69 64 29 20 7b 0a 09  _uid == uid) {..
3f70: 09 09 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a  ...retval = 0;..
3f80: 09 09 09 09 6d 65 6d 63 70 79 28 70 61 74 68 69  ....memcpy(pathi
3f90: 6e 66 6f 2c 20 26 61 70 70 66 73 5f 70 61 74 68  nfo, &appfs_path
3fa0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
3fb0: 5f 69 64 78 5d 2c 20 73 69 7a 65 6f 66 28 2a 70  _idx], sizeof(*p
3fc0: 61 74 68 69 6e 66 6f 29 29 3b 0a 09 09 09 09 70  athinfo));.....p
3fd0: 61 74 68 69 6e 66 6f 2d 3e 5f 63 61 63 68 65 5f  athinfo->_cache_
3fe0: 70 61 74 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 09  path = NULL;....
3ff0: 7d 0a 09 09 7d 0a 09 7d 0a 0a 09 70 74 68 72 65  }...}..}...pthre
4000: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  ad_ret = pthread
4010: 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61  _mutex_unlock(&a
4020: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4030: 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66  ache_mutex);..if
4040: 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d   (pthread_ret !=
4050: 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45   0) {...APPFS_DE
4060: 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 75  BUG("Unable to u
4070: 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20  nlock path_info 
4080: 63 61 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b  cache mutex !");
4090: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a  ....return(-1);.
40a0: 09 7d 0a 0a 09 69 66 20 28 72 65 74 76 61 6c 20  .}...if (retval 
40b0: 3d 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  == 0) {...APPFS_
40c0: 44 45 42 55 47 28 22 43 61 63 68 65 20 68 69 74  DEBUG("Cache hit
40d0: 20 6f 6e 20 25 73 22 2c 20 70 61 74 68 29 3b 0a   on %s", path);.
40e0: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 41 50 50 46  .} else {...APPF
40f0: 53 5f 44 45 42 55 47 28 22 43 61 63 68 65 20 6d  S_DEBUG("Cache m
4100: 69 73 73 20 6f 6e 20 25 73 22 2c 20 70 61 74 68  iss on %s", path
4110: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72  );..}...return(r
4120: 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69  etval);.}..stati
4130: 63 20 76 6f 69 64 20 61 70 70 66 73 5f 67 65 74  c void appfs_get
4140: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4150: 5f 61 64 64 28 63 6f 6e 73 74 20 63 68 61 72 20  _add(const char 
4160: 2a 70 61 74 68 2c 20 75 69 64 5f 74 20 75 69 64  *path, uid_t uid
4170: 2c 20 73 74 72 75 63 74 20 61 70 70 66 73 5f 70  , struct appfs_p
4180: 61 74 68 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66  athinfo *pathinf
4190: 6f 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69  o) {..unsigned i
41a0: 6e 74 20 68 61 73 68 5f 69 64 78 3b 0a 09 69 6e  nt hash_idx;..in
41b0: 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a  t pthread_ret;..
41c0: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
41d0: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63  thread_mutex_loc
41e0: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  k(&appfs_path_in
41f0: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b  fo_cache_mutex);
4200: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
4210: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  t != 0) {...APPF
4220: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20  S_DEBUG("Unable 
4230: 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66  to lock path_inf
4240: 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22  o cache mutex !"
4250: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d  );....return;..}
4260: 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70 61 74  ...if (appfs_pat
4270: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d 3d 20  h_info_cache == 
4280: 4e 55 4c 4c 29 20 7b 0a 09 09 61 70 70 66 73 5f  NULL) {...appfs_
4290: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20  path_info_cache 
42a0: 3d 20 63 61 6c 6c 6f 63 28 61 70 70 66 73 5f 70  = calloc(appfs_p
42b0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73  ath_info_cache_s
42c0: 69 7a 65 2c 20 73 69 7a 65 6f 66 28 2a 61 70 70  ize, sizeof(*app
42d0: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
42e0: 68 65 29 29 3b 0a 09 7d 0a 0a 09 68 61 73 68 5f  he));..}...hash_
42f0: 69 64 78 20 3d 20 28 61 70 70 66 73 5f 67 65 74  idx = (appfs_get
4300: 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74 68  _path_inode(path
4310: 29 20 2b 20 75 69 64 29 20 25 20 61 70 70 66 73  ) + uid) % appfs
4320: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4330: 5f 73 69 7a 65 3b 0a 0a 09 69 66 20 28 61 70 70  _size;...if (app
4340: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4350: 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61  he[hash_idx]._ca
4360: 63 68 65 5f 70 61 74 68 20 21 3d 20 4e 55 4c 4c  che_path != NULL
4370: 29 20 7b 0a 09 09 66 72 65 65 28 61 70 70 66 73  ) {...free(appfs
4380: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4390: 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68  [hash_idx]._cach
43a0: 65 5f 70 61 74 68 29 3b 0a 09 7d 0a 0a 09 6d 65  e_path);..}...me
43b0: 6d 63 70 79 28 26 61 70 70 66 73 5f 70 61 74 68  mcpy(&appfs_path
43c0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
43d0: 5f 69 64 78 5d 2c 20 70 61 74 68 69 6e 66 6f 2c  _idx], pathinfo,
43e0: 20 73 69 7a 65 6f 66 28 2a 70 61 74 68 69 6e 66   sizeof(*pathinf
43f0: 6f 29 29 3b 0a 0a 09 61 70 70 66 73 5f 70 61 74  o));...appfs_pat
4400: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73  h_info_cache[has
4410: 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61  h_idx]._cache_pa
4420: 74 68 20 3d 20 73 74 72 64 75 70 28 70 61 74 68  th = strdup(path
4430: 29 3b 0a 09 61 70 70 66 73 5f 70 61 74 68 5f 69  );..appfs_path_i
4440: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69  nfo_cache[hash_i
4450: 64 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64 20 20  dx]._cache_uid  
4460: 3d 20 75 69 64 3b 0a 0a 09 70 74 68 72 65 61 64  = uid;...pthread
4470: 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d  _ret = pthread_m
4480: 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70  utex_unlock(&app
4490: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
44a0: 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28  he_mutex);..if (
44b0: 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30  pthread_ret != 0
44c0: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
44d0: 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c  G("Unable to unl
44e0: 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61  ock path_info ca
44f0: 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a  che mutex !");..
4500: 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72  ..return;..}...r
4510: 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63  eturn;.}..static
4520: 20 76 6f 69 64 20 61 70 70 66 73 5f 67 65 74 5f   void appfs_get_
4530: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
4540: 72 6d 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  rm(const char *p
4550: 61 74 68 2c 20 75 69 64 5f 74 20 75 69 64 29 20  ath, uid_t uid) 
4560: 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  {..unsigned int 
4570: 68 61 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70  hash_idx;..int p
4580: 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 70 74  thread_ret;...pt
4590: 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72  hread_ret = pthr
45a0: 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26  ead_mutex_lock(&
45b0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
45c0: 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69  cache_mutex);..i
45d0: 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21  f (pthread_ret !
45e0: 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  = 0) {...APPFS_D
45f0: 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20  EBUG("Unable to 
4600: 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63  lock path_info c
4610: 61 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a  ache mutex !");.
4620: 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09  ...return;..}...
4630: 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69  if (appfs_path_i
4640: 6e 66 6f 5f 63 61 63 68 65 20 21 3d 20 4e 55 4c  nfo_cache != NUL
4650: 4c 29 20 7b 0a 09 09 68 61 73 68 5f 69 64 78 20  L) {...hash_idx 
4660: 3d 20 28 61 70 70 66 73 5f 67 65 74 5f 70 61 74  = (appfs_get_pat
4670: 68 5f 69 6e 6f 64 65 28 70 61 74 68 29 20 2b 20  h_inode(path) + 
4680: 75 69 64 29 20 25 20 61 70 70 66 73 5f 70 61 74  uid) % appfs_pat
4690: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a  h_info_cache_siz
46a0: 65 3b 0a 0a 09 09 69 66 20 28 61 70 70 66 73 5f  e;....if (appfs_
46b0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
46c0: 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65  hash_idx]._cache
46d0: 5f 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b  _path != NULL) {
46e0: 0a 09 09 09 66 72 65 65 28 61 70 70 66 73 5f 70  ....free(appfs_p
46f0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68  ath_info_cache[h
4700: 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f  ash_idx]._cache_
4710: 70 61 74 68 29 3b 0a 0a 09 09 09 61 70 70 66 73  path);.....appfs
4720: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4730: 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68  [hash_idx]._cach
4740: 65 5f 70 61 74 68 20 3d 20 4e 55 4c 4c 3b 0a 09  e_path = NULL;..
4750: 09 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f  .}..}...pthread_
4760: 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75  ret = pthread_mu
4770: 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66  tex_unlock(&appf
4780: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4790: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70  e_mutex);..if (p
47a0: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
47b0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
47c0: 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f  ("Unable to unlo
47d0: 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63  ck path_info cac
47e0: 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09  he mutex !");...
47f0: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65  .return;..}...re
4800: 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  turn;.}..static 
4810: 76 6f 69 64 20 61 70 70 66 73 5f 67 65 74 5f 70  void appfs_get_p
4820: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66  ath_info_cache_f
4830: 6c 75 73 68 28 75 69 64 5f 74 20 75 69 64 2c 20  lush(uid_t uid, 
4840: 69 6e 74 20 6e 65 77 5f 73 69 7a 65 29 20 7b 0a  int new_size) {.
4850: 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 64  .unsigned int id
4860: 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f  x;..int pthread_
4870: 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42  ret;...APPFS_DEB
4880: 55 47 28 22 46 6c 75 73 68 69 6e 67 20 41 70 70  UG("Flushing App
4890: 46 53 20 63 61 63 68 65 20 28 75 69 64 20 3d 20  FS cache (uid = 
48a0: 25 6c 6c 69 2c 20 6e 65 77 5f 73 69 7a 65 20 3d  %lli, new_size =
48b0: 20 25 69 29 22 2c 20 28 6c 6f 6e 67 20 6c 6f 6e   %i)", (long lon
48c0: 67 29 20 75 69 64 2c 20 6e 65 77 5f 73 69 7a 65  g) uid, new_size
48d0: 29 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74  );...pthread_ret
48e0: 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78   = pthread_mutex
48f0: 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74  _lock(&appfs_pat
4900: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74  h_info_cache_mut
4910: 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61  ex);..if (pthrea
4920: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
4930: 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61  APPFS_DEBUG("Una
4940: 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68  ble to lock path
4950: 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65  _info cache mute
4960: 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  x !");....return
4970: 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73  ;..}...if (appfs
4980: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4990: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 6f   != NULL) {...fo
49a0: 72 20 28 69 64 78 20 3d 20 30 3b 20 69 64 78 20  r (idx = 0; idx 
49b0: 3c 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  < appfs_path_inf
49c0: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 20 69 64  o_cache_size; id
49d0: 78 2b 2b 29 20 7b 0a 09 09 09 69 66 20 28 61 70  x++) {....if (ap
49e0: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
49f0: 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f  che[idx]._cache_
4a00: 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  path != NULL) {.
4a10: 09 09 09 09 69 66 20 28 75 69 64 20 21 3d 20 28  ....if (uid != (
4a20: 28 75 69 64 5f 74 29 20 2d 31 29 29 20 7b 0a 09  (uid_t) -1)) {..
4a30: 09 09 09 09 69 66 20 28 61 70 70 66 73 5f 70 61  ....if (appfs_pa
4a40: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64  th_info_cache[id
4a50: 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64 20 21 3d  x]._cache_uid !=
4a60: 20 75 69 64 29 20 7b 0a 09 09 09 09 09 09 63 6f   uid) {.......co
4a70: 6e 74 69 6e 75 65 3b 0a 09 09 09 09 09 7d 0a 09  ntinue;......}..
4a80: 09 09 09 7d 0a 0a 09 09 09 09 66 72 65 65 28 61  ...}......free(a
4a90: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4aa0: 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65  ache[idx]._cache
4ab0: 5f 70 61 74 68 29 3b 0a 0a 09 09 09 09 61 70 70  _path);......app
4ac0: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4ad0: 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70  he[idx]._cache_p
4ae0: 61 74 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 09 7d  ath = NULL;....}
4af0: 0a 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 75 69  ...}..}...if (ui
4b00: 64 20 3d 3d 20 28 28 75 69 64 5f 74 29 20 2d 31  d == ((uid_t) -1
4b10: 29 29 20 7b 0a 09 09 66 72 65 65 28 61 70 70 66  )) {...free(appf
4b20: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4b30: 65 29 3b 0a 0a 09 09 61 70 70 66 73 5f 70 61 74  e);....appfs_pat
4b40: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20 4e  h_info_cache = N
4b50: 55 4c 4c 3b 0a 0a 09 09 69 66 20 28 6e 65 77 5f  ULL;....if (new_
4b60: 73 69 7a 65 20 21 3d 20 2d 31 29 20 7b 0a 09 09  size != -1) {...
4b70: 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  .appfs_path_info
4b80: 5f 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 6e 65  _cache_size = ne
4b90: 77 5f 73 69 7a 65 3b 0a 09 09 7d 0a 09 7d 0a 0a  w_size;...}..}..
4ba0: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
4bb0: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c  thread_mutex_unl
4bc0: 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f  ock(&appfs_path_
4bd0: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
4be0: 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f  );..if (pthread_
4bf0: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ret != 0) {...AP
4c00: 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c  PFS_DEBUG("Unabl
4c10: 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68  e to unlock path
4c20: 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65  _info cache mute
4c30: 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  x !");....return
4c40: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d  ;..}...return;.}
4c50: 0a 0a 2f 2a 20 47 65 74 20 69 6e 66 6f 72 6d 61  ../* Get informa
4c60: 74 69 6f 6e 20 61 62 6f 75 74 20 61 20 70 61 74  tion about a pat
4c70: 68 2c 20 61 6e 64 20 6f 70 74 69 6f 6e 61 6c 6c  h, and optionall
4c80: 79 20 6c 69 73 74 20 63 68 69 6c 64 72 65 6e 20  y list children 
4c90: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  */.static int ap
4ca0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
4cb0: 6f 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  o(const char *pa
4cc0: 74 68 2c 20 73 74 72 75 63 74 20 61 70 70 66 73  th, struct appfs
4cd0: 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61 74 68 69  _pathinfo *pathi
4ce0: 6e 66 6f 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  nfo) {..Tcl_Inte
4cf0: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c  rp *interp;..Tcl
4d00: 5f 4f 62 6a 20 2a 61 74 74 72 73 5f 64 69 63 74  _Obj *attrs_dict
4d10: 2c 20 2a 61 74 74 72 5f 76 61 6c 75 65 3b 0a 09  , *attr_value;..
4d20: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 74 74 72  const char *attr
4d30: 5f 76 61 6c 75 65 5f 73 74 72 2c 20 2a 61 74 74  _value_str, *att
4d40: 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 3b 0a 09  r_value_str_i;..
4d50: 54 63 6c 5f 57 69 64 65 49 6e 74 20 61 74 74 72  Tcl_WideInt attr
4d60: 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 69 6e  _value_wide;..in
4d70: 74 20 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74  t attr_value_int
4d80: 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65  ;..static __thre
4d90: 61 64 20 54 63 6c 5f 4f 62 6a 20 2a 61 74 74 72  ad Tcl_Obj *attr
4da0: 5f 6b 65 79 5f 74 79 70 65 20 3d 20 4e 55 4c 4c  _key_type = NULL
4db0: 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d  , *attr_key_perm
4dc0: 73 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f  s = NULL, *attr_
4dd0: 6b 65 79 5f 73 69 7a 65 20 3d 20 4e 55 4c 4c 2c  key_size = NULL,
4de0: 20 2a 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 20   *attr_key_time 
4df0: 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65  = NULL, *attr_ke
4e00: 79 5f 73 6f 75 72 63 65 20 3d 20 4e 55 4c 4c 2c  y_source = NULL,
4e10: 20 2a 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64   *attr_key_child
4e20: 63 6f 75 6e 74 20 3d 20 4e 55 4c 4c 2c 20 2a 61  count = NULL, *a
4e30: 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64  ttr_key_packaged
4e40: 20 3d 20 4e 55 4c 4c 3b 0a 09 69 6e 74 20 63 61   = NULL;..int ca
4e50: 63 68 65 5f 72 65 74 3b 0a 09 69 6e 74 20 74 63  che_ret;..int tc
4e60: 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65 74 76  l_ret;..int retv
4e70: 61 6c 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64  al;..uid_t fsuid
4e80: 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a  ;...retval = 0;.
4e90: 0a 09 66 73 75 69 64 20 3d 20 61 70 70 66 73 5f  ..fsuid = appfs_
4ea0: 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 0a 09 63  get_fsuid();...c
4eb0: 61 63 68 65 5f 72 65 74 20 3d 20 61 70 70 66 73  ache_ret = appfs
4ec0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
4ed0: 61 63 68 65 5f 67 65 74 28 70 61 74 68 2c 20 66  ache_get(path, f
4ee0: 73 75 69 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b  suid, pathinfo);
4ef0: 0a 09 69 66 20 28 63 61 63 68 65 5f 72 65 74 20  ..if (cache_ret 
4f00: 3d 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 70 61  == 0) {...if (pa
4f10: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d 20  thinfo->type == 
4f20: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44  APPFS_PATHTYPE_D
4f30: 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 29 20 7b  OES_NOT_EXIST) {
4f40: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
4f50: 22 52 65 74 75 72 6e 69 6e 67 20 66 72 6f 6d 20  "Returning from 
4f60: 63 61 63 68 65 3a 20 64 6f 65 73 20 6e 6f 74 20  cache: does not 
4f70: 65 78 69 73 74 20 5c 22 25 73 5c 22 22 2c 20 70  exist \"%s\"", p
4f80: 61 74 68 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e  ath);.....return
4f90: 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09 09 7d 0a 0a  (-ENOENT);...}..
4fa0: 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2d 3e  ..if (pathinfo->
4fb0: 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50 41  type == APPFS_PA
4fc0: 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 29 20  THTYPE_INVALID) 
4fd0: 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  {....APPFS_DEBUG
4fe0: 28 22 52 65 74 75 72 6e 69 6e 67 20 66 72 6f 6d  ("Returning from
4ff0: 20 63 61 63 68 65 3a 20 69 6e 76 61 6c 69 64 20   cache: invalid 
5000: 6f 62 6a 65 63 74 20 5c 22 25 73 5c 22 22 2c 20  object \"%s\"", 
5010: 70 61 74 68 29 3b 0a 0a 09 09 09 72 65 74 75 72  path);.....retur
5020: 6e 28 2d 45 49 4f 29 3b 0a 09 09 7d 0a 0a 09 09  n(-EIO);...}....
5030: 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09  return(0);..}...
5040: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54  interp = appfs_T
5050: 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20  clInterp();..if 
5060: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
5070: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
5080: 28 22 65 72 72 6f 72 3a 20 55 6e 61 62 6c 65 20  ("error: Unable 
5090: 74 6f 20 67 65 74 20 61 6e 20 69 6e 74 65 72 70  to get an interp
50a0: 72 65 74 65 72 22 29 3b 0a 0a 09 09 72 65 74 75  reter");....retu
50b0: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
50c0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
50d0: 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e  (Tcl_Preserve(in
50e0: 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72 65  terp);)...tcl_re
50f0: 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76  t = appfs_Tcl_Ev
5100: 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a  al(interp, 2, ":
5110: 3a 61 70 70 66 73 3a 3a 67 65 74 61 74 74 72 22  :appfs::getattr"
5120: 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28 74 63  , path);..if (tc
5130: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
5140: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
5150: 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61 74  ("::appfs::getat
5160: 74 72 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c  tr(%s) failed.",
5170: 20 70 61 74 68 29 3b 0a 09 09 61 70 70 66 73 5f   path);...appfs_
5180: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
5190: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c  APPFS_DEBUG("Tcl
51a0: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20   Error is: %s", 
51b0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
51c0: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
51d0: 29 0a 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  )....pathinfo->t
51e0: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48  ype = APPFS_PATH
51f0: 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58  TYPE_DOES_NOT_EX
5200: 49 53 54 3b 0a 0a 09 09 61 70 70 66 73 5f 67 65  IST;....appfs_ge
5210: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
5220: 65 5f 61 64 64 28 70 61 74 68 2c 20 66 73 75 69  e_add(path, fsui
5230: 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a 0a 09  d, pathinfo);...
5240: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
5250: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
5260: 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75  nterp);)....retu
5270: 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09 7d 0a  rn(-ENOENT);..}.
5280: 0a 09 69 66 20 28 61 74 74 72 5f 6b 65 79 5f 74  ..if (attr_key_t
5290: 79 70 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ype == NULL) {..
52a0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
52b0: 63 6c 28 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f  cl(....attr_key_
52c0: 74 79 70 65 20 20 20 20 20 20 20 3d 20 54 63 6c  type       = Tcl
52d0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 74  _NewStringObj("t
52e0: 79 70 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74  ype", -1);....at
52f0: 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20 20 20 20  tr_key_perms    
5300: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e    = Tcl_NewStrin
5310: 67 4f 62 6a 28 22 70 65 72 6d 73 22 2c 20 2d 31  gObj("perms", -1
5320: 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 73  );....attr_key_s
5330: 69 7a 65 20 20 20 20 20 20 20 3d 20 54 63 6c 5f  ize       = Tcl_
5340: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 73 69  NewStringObj("si
5350: 7a 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74  ze", -1);....att
5360: 72 5f 6b 65 79 5f 74 69 6d 65 20 20 20 20 20 20  r_key_time      
5370: 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67   = Tcl_NewString
5380: 4f 62 6a 28 22 74 69 6d 65 22 2c 20 2d 31 29 3b  Obj("time", -1);
5390: 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 73 6f 75  ....attr_key_sou
53a0: 72 63 65 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65  rce     = Tcl_Ne
53b0: 77 53 74 72 69 6e 67 4f 62 6a 28 22 73 6f 75 72  wStringObj("sour
53c0: 63 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74  ce", -1);....att
53d0: 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74  r_key_childcount
53e0: 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67   = Tcl_NewString
53f0: 4f 62 6a 28 22 63 68 69 6c 64 63 6f 75 6e 74 22  Obj("childcount"
5400: 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b  , -1);....attr_k
5410: 65 79 5f 70 61 63 6b 61 67 65 64 20 20 20 3d 20  ey_packaged   = 
5420: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
5430: 28 22 70 61 63 6b 61 67 65 64 22 2c 20 2d 31 29  ("packaged", -1)
5440: 3b 0a 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65  ;.....Tcl_IncrRe
5450: 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f  fCount(attr_key_
5460: 74 79 70 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e  type);....Tcl_In
5470: 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f  crRefCount(attr_
5480: 6b 65 79 5f 70 65 72 6d 73 29 3b 0a 09 09 09 54  key_perms);....T
5490: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
54a0: 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 29 3b 0a  attr_key_size);.
54b0: 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f  ...Tcl_IncrRefCo
54c0: 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 74 69 6d  unt(attr_key_tim
54d0: 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52  e);....Tcl_IncrR
54e0: 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79  efCount(attr_key
54f0: 5f 73 6f 75 72 63 65 29 3b 0a 09 09 09 54 63 6c  _source);....Tcl
5500: 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74  _IncrRefCount(at
5510: 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e  tr_key_childcoun
5520: 74 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52  t);....Tcl_IncrR
5530: 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79  efCount(attr_key
5540: 5f 70 61 63 6b 61 67 65 64 29 3b 0a 09 09 29 0a  _packaged);...).
5550: 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .}...appfs_call_
5560: 6c 69 62 74 63 6c 28 0a 09 09 61 74 74 72 73 5f  libtcl(...attrs_
5570: 64 69 63 74 20 3d 20 54 63 6c 5f 47 65 74 4f 62  dict = Tcl_GetOb
5580: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  jResult(interp);
5590: 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
55a0: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
55b0: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
55c0: 61 74 74 72 5f 6b 65 79 5f 74 79 70 65 2c 20 26  attr_key_type, &
55d0: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 29 0a  attr_value);..).
55e0: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
55f0: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
5600: 53 5f 44 45 42 55 47 28 22 5b 64 69 63 74 20 67  S_DEBUG("[dict g
5610: 65 74 20 5c 22 74 79 70 65 5c 22 5d 20 66 61 69  et \"type\"] fai
5620: 6c 65 64 22 29 3b 0a 09 09 61 70 70 66 73 5f 63  led");...appfs_c
5630: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41  all_libtcl(....A
5640: 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20  PPFS_DEBUG("Tcl 
5650: 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54  Error is: %s", T
5660: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
5670: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29  lt(interp));...)
5680: 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
5690: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
56a0: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72  e(interp);)....r
56b0: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
56c0: 0a 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65  ..if (attr_value
56d0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50   == NULL) {...AP
56e0: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
56f0: 3a 20 55 6e 61 62 6c 65 20 74 6f 20 67 65 74 20  : Unable to get 
5700: 74 79 70 65 20 66 6f 72 20 5c 22 25 73 5c 22 20  type for \"%s\" 
5710: 66 72 6f 6d 20 54 63 6c 22 2c 20 70 61 74 68 29  from Tcl", path)
5720: 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  ;....appfs_call_
5730: 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61  libtcl(Tcl_Relea
5740: 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09  se(interp);)....
5750: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
5760: 0a 0a 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63  ...pathinfo->pac
5770: 6b 61 67 65 64 20 3d 20 30 3b 0a 09 70 61 74 68  kaged = 0;..path
5780: 69 6e 66 6f 2d 3e 69 6e 6f 64 65 20 3d 20 61 70  info->inode = ap
5790: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f  pfs_get_path_ino
57a0: 64 65 28 70 61 74 68 29 3b 0a 0a 09 61 70 70 66  de(path);...appf
57b0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
57c0: 09 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 20  .attr_value_str 
57d0: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  = Tcl_GetString(
57e0: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 0a 09 09  attr_value);....
57f0: 73 77 69 74 63 68 20 28 61 74 74 72 5f 76 61 6c  switch (attr_val
5800: 75 65 5f 73 74 72 5b 30 5d 29 20 7b 0a 09 09 09  ue_str[0]) {....
5810: 63 61 73 65 20 27 64 27 3a 20 2f 2a 20 64 69 72  case 'd': /* dir
5820: 65 63 74 6f 72 79 20 2a 2f 0a 09 09 09 09 70 61  ectory */.....pa
5830: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41  thinfo->type = A
5840: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49  PPFS_PATHTYPE_DI
5850: 52 45 43 54 4f 52 59 3b 0a 09 09 09 09 70 61 74  RECTORY;.....pat
5860: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
5870: 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d  dir.childcount =
5880: 20 30 3b 0a 0a 09 09 09 09 54 63 6c 5f 44 69 63   0;......Tcl_Dic
5890: 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20  tObjGet(interp, 
58a0: 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72  attrs_dict, attr
58b0: 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 2c  _key_childcount,
58c0: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
58d0: 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75  ...if (attr_valu
58e0: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  e != NULL) {....
58f0: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
5900: 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62  GetWideIntFromOb
5910: 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c  j(NULL, attr_val
5920: 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f  ue, &attr_value_
5930: 77 69 64 65 29 3b 0a 09 09 09 09 09 69 66 20 28  wide);......if (
5940: 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f  tcl_ret == TCL_O
5950: 4b 29 20 7b 0a 09 09 09 09 09 09 70 61 74 68 69  K) {.......pathi
5960: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64 69  nfo->typeinfo.di
5970: 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 61  r.childcount = a
5980: 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a  ttr_value_wide;.
5990: 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09  .....}.....}....
59a0: 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65  ..break;....case
59b0: 20 27 66 27 3a 20 2f 2a 20 66 69 6c 65 20 2a 2f   'f': /* file */
59c0: 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
59d0: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48  ype = APPFS_PATH
59e0: 54 59 50 45 5f 46 49 4c 45 3b 0a 09 09 09 09 70  TYPE_FILE;.....p
59f0: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
5a00: 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 3d 20 30 3b  o.file.size = 0;
5a10: 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
5a20: 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65  ypeinfo.file.exe
5a30: 63 75 74 61 62 6c 65 20 3d 20 30 3b 0a 09 09 09  cutable = 0;....
5a40: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  .pathinfo->typei
5a50: 6e 66 6f 2e 66 69 6c 65 2e 73 75 69 64 52 6f 6f  nfo.file.suidRoo
5a60: 74 20 3d 20 30 3b 0a 09 09 09 09 70 61 74 68 69  t = 0;.....pathi
5a70: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69  nfo->typeinfo.fi
5a80: 6c 65 2e 77 6f 72 6c 64 61 63 63 65 73 73 69 62  le.worldaccessib
5a90: 6c 65 20 3d 20 30 3b 0a 0a 09 09 09 09 54 63 6c  le = 0;......Tcl
5aa0: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
5ab0: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
5ac0: 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 2c 20 26  attr_key_size, &
5ad0: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09  attr_value);....
5ae0: 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20  .if (attr_value 
5af0: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 09  != NULL) {......
5b00: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65  tcl_ret = Tcl_Ge
5b10: 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28  tWideIntFromObj(
5b20: 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65  NULL, attr_value
5b30: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69  , &attr_value_wi
5b40: 64 65 29 3b 0a 09 09 09 09 09 69 66 20 28 74 63  de);......if (tc
5b50: 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29  l_ret == TCL_OK)
5b60: 20 7b 0a 09 09 09 09 09 09 70 61 74 68 69 6e 66   {.......pathinf
5b70: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  o->typeinfo.file
5b80: 2e 73 69 7a 65 20 3d 20 61 74 74 72 5f 76 61 6c  .size = attr_val
5b90: 75 65 5f 77 69 64 65 3b 0a 09 09 09 09 09 7d 0a  ue_wide;......}.
5ba0: 09 09 09 09 7d 0a 0a 09 09 09 09 54 63 6c 5f 44  ....}......Tcl_D
5bb0: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
5bc0: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
5bd0: 74 72 5f 6b 65 79 5f 70 65 72 6d 73 2c 20 26 61  tr_key_perms, &a
5be0: 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09  ttr_value);.....
5bf0: 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21  if (attr_value !
5c00: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 09 61  = NULL) {......a
5c10: 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20  ttr_value_str = 
5c20: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 61 74  Tcl_GetString(at
5c30: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09 09  tr_value);......
5c40: 66 6f 72 20 28 61 74 74 72 5f 76 61 6c 75 65 5f  for (attr_value_
5c50: 73 74 72 5f 69 20 3d 20 26 61 74 74 72 5f 76 61  str_i = &attr_va
5c60: 6c 75 65 5f 73 74 72 5b 30 5d 3b 20 2a 61 74 74  lue_str[0]; *att
5c70: 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 20 21 3d  r_value_str_i !=
5c80: 20 27 5c 30 27 3b 20 61 74 74 72 5f 76 61 6c 75   '\0'; attr_valu
5c90: 65 5f 73 74 72 5f 69 2b 2b 29 20 7b 0a 09 09 09  e_str_i++) {....
5ca0: 09 09 09 73 77 69 74 63 68 20 28 2a 61 74 74 72  ...switch (*attr
5cb0: 5f 76 61 6c 75 65 5f 73 74 72 5f 69 29 20 7b 0a  _value_str_i) {.
5cc0: 09 09 09 09 09 09 09 63 61 73 65 20 27 78 27 3a  .......case 'x':
5cd0: 0a 09 09 09 09 09 09 09 09 70 61 74 68 69 6e 66  .........pathinf
5ce0: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  o->typeinfo.file
5cf0: 2e 65 78 65 63 75 74 61 62 6c 65 20 3d 20 31 3b  .executable = 1;
5d00: 0a 0a 09 09 09 09 09 09 09 09 62 72 65 61 6b 3b  ..........break;
5d10: 0a 09 09 09 09 09 09 09 63 61 73 65 20 27 55 27  ........case 'U'
5d20: 3a 0a 09 09 09 09 09 09 09 09 70 61 74 68 69 6e  :.........pathin
5d30: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  fo->typeinfo.fil
5d40: 65 2e 73 75 69 64 52 6f 6f 74 20 3d 20 31 3b 0a  e.suidRoot = 1;.
5d50: 0a 09 09 09 09 09 09 09 09 62 72 65 61 6b 3b 0a  .........break;.
5d60: 09 09 09 09 09 09 09 63 61 73 65 20 27 2d 27 3a  .......case '-':
5d70: 0a 09 09 09 09 09 09 09 09 70 61 74 68 69 6e 66  .........pathinf
5d80: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  o->typeinfo.file
5d90: 2e 77 6f 72 6c 64 61 63 63 65 73 73 69 62 6c 65  .worldaccessible
5da0: 20 3d 20 31 3b 0a 0a 09 09 09 09 09 09 09 09 62   = 1;..........b
5db0: 72 65 61 6b 3b 0a 09 09 09 09 09 09 7d 0a 09 09  reak;.......}...
5dc0: 09 09 09 7d 0a 09 09 09 09 7d 0a 09 09 09 09 62  ...}.....}.....b
5dd0: 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 73  reak;....case 's
5de0: 27 3a 20 2f 2a 20 73 79 6d 6c 69 6e 6b 20 2a 2f  ': /* symlink */
5df0: 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
5e00: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48  ype = APPFS_PATH
5e10: 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3b 0a 09 09  TYPE_SYMLINK;...
5e20: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
5e30: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a  info.symlink.siz
5e40: 65 20 3d 20 30 3b 0a 09 09 09 09 70 61 74 68 69  e = 0;.....pathi
5e50: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79  nfo->typeinfo.sy
5e60: 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b 30 5d 20  mlink.source[0] 
5e70: 3d 20 27 5c 30 27 3b 0a 0a 09 09 09 09 54 63 6c  = '\0';......Tcl
5e80: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
5e90: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
5ea0: 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65 2c  attr_key_source,
5eb0: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
5ec0: 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75  ...if (attr_valu
5ed0: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  e != NULL) {....
5ee0: 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72  ..attr_value_str
5ef0: 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67   = Tcl_GetString
5f00: 46 72 6f 6d 4f 62 6a 28 61 74 74 72 5f 76 61 6c  FromObj(attr_val
5f10: 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f  ue, &attr_value_
5f20: 69 6e 74 29 3b 20 0a 0a 09 09 09 09 09 69 66 20  int); .......if 
5f30: 28 28 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74  ((attr_value_int
5f40: 20 2b 20 31 29 20 3c 3d 20 73 69 7a 65 6f 66 28   + 1) <= sizeof(
5f50: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
5f60: 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63  fo.symlink.sourc
5f70: 65 29 29 20 7b 0a 09 09 09 09 09 09 70 61 74 68  e)) {.......path
5f80: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73  info->typeinfo.s
5f90: 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20 61 74  ymlink.size = at
5fa0: 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a 09 09  tr_value_int;...
5fb0: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
5fc0: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
5fd0: 6f 75 72 63 65 5b 61 74 74 72 5f 76 61 6c 75 65  ource[attr_value
5fe0: 5f 69 6e 74 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09  _int] = '\0';...
5ff0: 09 09 09 09 09 6d 65 6d 63 70 79 28 70 61 74 68  .....memcpy(path
6000: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73  info->typeinfo.s
6010: 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c 20 61  ymlink.source, a
6020: 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 2c 20 61  ttr_value_str, a
6030: 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 0a  ttr_value_int);.
6040: 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 09 09 09  .....}.....}....
6050: 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20  .break;....case 
6060: 27 46 27 3a 20 2f 2a 20 70 69 70 65 2f 66 69 66  'F': /* pipe/fif
6070: 6f 20 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66  o */.....pathinf
6080: 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f  o->type = APPFS_
6090: 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3b 0a 09  PATHTYPE_FIFO;..
60a0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73  ...break;....cas
60b0: 65 20 27 53 27 3a 20 2f 2a 20 55 4e 49 58 20 64  e 'S': /* UNIX d
60c0: 6f 6d 61 69 6e 20 73 6f 63 6b 65 74 20 2a 2f 0a  omain socket */.
60d0: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
60e0: 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54  pe = APPFS_PATHT
60f0: 59 50 45 5f 53 4f 43 4b 45 54 3b 0a 09 09 09 09  YPE_SOCKET;.....
6100: 62 72 65 61 6b 3b 0a 09 09 09 64 65 66 61 75 6c  break;....defaul
6110: 74 3a 0a 09 09 09 09 72 65 74 76 61 6c 20 3d 20  t:.....retval = 
6120: 2d 45 49 4f 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c  -EIO;...}....Tcl
6130: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
6140: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
6150: 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65  attr_key_package
6160: 64 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  d, &attr_value);
6170: 0a 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75  ...if (attr_valu
6180: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  e != NULL) {....
6190: 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67  pathinfo->packag
61a0: 65 64 20 3d 20 31 3b 0a 09 09 7d 0a 0a 09 09 54  ed = 1;...}....T
61b0: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
61c0: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
61d0: 2c 20 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 2c  , attr_key_time,
61e0: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
61f0: 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20  .if (attr_value 
6200: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 74 63  != NULL) {....tc
6210: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 57  l_ret = Tcl_GetW
6220: 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e 55  ideIntFromObj(NU
6230: 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c 20  LL, attr_value, 
6240: 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65  &attr_value_wide
6250: 29 3b 0a 09 09 09 69 66 20 28 74 63 6c 5f 72 65  );....if (tcl_re
6260: 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t == TCL_OK) {..
6270: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 69 6d  ...pathinfo->tim
6280: 65 20 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 77  e = attr_value_w
6290: 69 64 65 3b 0a 09 09 09 7d 0a 09 09 7d 20 65 6c  ide;....}...} el
62a0: 73 65 20 7b 0a 09 09 09 70 61 74 68 69 6e 66 6f  se {....pathinfo
62b0: 2d 3e 74 69 6d 65 20 3d 20 61 70 70 66 73 5f 62  ->time = appfs_b
62c0: 6f 6f 74 74 69 6d 65 3b 0a 09 09 7d 0a 0a 09 09  oottime;...}....
62d0: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
62e0: 72 70 29 3b 0a 09 29 0a 0a 09 69 66 20 28 72 65  rp);..)...if (re
62f0: 74 76 61 6c 20 3d 3d 20 30 29 20 7b 0a 09 09 61  tval == 0) {...a
6300: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
6310: 66 6f 5f 63 61 63 68 65 5f 61 64 64 28 70 61 74  fo_cache_add(pat
6320: 68 2c 20 66 73 75 69 64 2c 20 70 61 74 68 69 6e  h, fsuid, pathin
6330: 66 6f 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09  fo);..} else {..
6340: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72  .APPFS_DEBUG("er
6350: 72 6f 72 3a 20 49 6e 76 61 6c 69 64 20 74 79 70  ror: Invalid typ
6360: 65 20 66 6f 72 20 5c 22 25 73 5c 22 20 66 72 6f  e for \"%s\" fro
6370: 6d 20 54 63 6c 22 2c 20 70 61 74 68 29 3b 0a 09  m Tcl", path);..
6380: 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61  }...return(retva
6390: 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68  l);.}..static ch
63a0: 61 72 20 2a 61 70 70 66 73 5f 70 72 65 70 61 72  ar *appfs_prepar
63b0: 65 5f 74 6f 5f 63 72 65 61 74 65 28 63 6f 6e 73  e_to_create(cons
63c0: 74 20 63 68 61 72 20 2a 70 61 74 68 29 20 7b 0a  t char *path) {.
63d0: 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  .Tcl_Interp *int
63e0: 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72  erp;..const char
63f0: 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e   *real_path;..in
6400: 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 61 70 70  t tcl_ret;...app
6410: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
6420: 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70  _cache_flush(app
6430: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20  fs_get_fsuid(), 
6440: 2d 31 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20  -1);...interp = 
6450: 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28  appfs_TclInterp(
6460: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  );..if (interp =
6470: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
6480: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61  rn(NULL);..}...a
6490: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
64a0: 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e  (Tcl_Preserve(in
64b0: 74 65 72 70 29 3b 29 0a 0a 09 61 70 70 66 73 5f  terp);)...appfs_
64c0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74  call_libtcl(...t
64d0: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
64e0: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
64f0: 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65  2, "::appfs::pre
6500: 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 22 2c  pare_to_create",
6510: 20 70 61 74 68 29 3b 0a 09 29 0a 09 69 66 20 28   path);..)..if (
6520: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
6530: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
6540: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65  UG("::appfs::pre
6550: 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 25  pare_to_create(%
6560: 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  s) failed.", pat
6570: 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  h);...appfs_call
6580: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46  _libtcl(....APPF
6590: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72  S_DEBUG("Tcl Err
65a0: 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f  or is: %s", Tcl_
65b0: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
65c0: 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09  interp));...)...
65d0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
65e0: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
65f0: 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75  nterp);)....retu
6600: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61  rn(NULL);..}...a
6610: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
6620: 28 0a 09 09 72 65 61 6c 5f 70 61 74 68 20 3d 20  (...real_path = 
6630: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
6640: 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a  ult(interp);..).
6650: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
6660: 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28  tcl(Tcl_Release(
6670: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 69 66 20 28  interp);)...if (
6680: 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c  real_path == NUL
6690: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55  L) {...return(NU
66a0: 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  LL);..}...return
66b0: 28 73 74 72 64 75 70 28 72 65 61 6c 5f 70 61 74  (strdup(real_pat
66c0: 68 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63  h));.}..static c
66d0: 68 61 72 20 2a 61 70 70 66 73 5f 6c 6f 63 61 6c  har *appfs_local
66e0: 70 61 74 68 28 63 6f 6e 73 74 20 63 68 61 72 20  path(const char 
66f0: 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e  *path) {..Tcl_In
6700: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63  terp *interp;..c
6710: 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f  onst char *real_
6720: 70 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72  path;..int tcl_r
6730: 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61  et;...interp = a
6740: 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29  ppfs_TclInterp()
6750: 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ;..if (interp ==
6760: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
6770: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70  n(NULL);..}...ap
6780: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
6790: 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74  Tcl_Preserve(int
67a0: 65 72 70 29 3b 29 0a 0a 09 61 70 70 66 73 5f 63  erp);)...appfs_c
67b0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63  all_libtcl(...tc
67c0: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
67d0: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32  l_Eval(interp, 2
67e0: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63 61  , "::appfs::loca
67f0: 6c 70 61 74 68 22 2c 20 70 61 74 68 29 3b 0a 09  lpath", path);..
6800: 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  )..if (tcl_ret !
6810: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50  = TCL_OK) {...AP
6820: 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70  PFS_DEBUG("::app
6830: 66 73 3a 3a 6c 6f 63 61 6c 70 61 74 68 28 25 73  fs::localpath(%s
6840: 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68  ) failed.", path
6850: 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  );...appfs_call_
6860: 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53  libtcl(....APPFS
6870: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
6880: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
6890: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
68a0: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
68b0: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
68c0: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
68d0: 62 74 63 6c 28 0a 09 09 72 65 61 6c 5f 70 61 74  btcl(...real_pat
68e0: 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  h = Tcl_GetStrin
68f0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  gResult(interp);
6900: 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..)...appfs_call
6910: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
6920: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
6930: 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d  if (real_path ==
6940: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
6950: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65  n(NULL);..}...re
6960: 74 75 72 6e 28 73 74 72 64 75 70 28 72 65 61 6c  turn(strdup(real
6970: 5f 70 61 74 68 29 29 3b 0a 7d 0a 0a 23 69 66 20  _path));.}..#if 
6980: 28 64 65 66 69 6e 65 64 28 44 45 42 55 47 29 20  (defined(DEBUG) 
6990: 26 26 20 64 65 66 69 6e 65 64 28 41 50 50 46 53  && defined(APPFS
69a0: 5f 45 58 49 54 5f 50 41 54 48 29 29 20 7c 7c 20  _EXIT_PATH)) || 
69b0: 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58  defined(APPFS_EX
69c0: 49 54 5f 50 41 54 48 5f 45 4e 41 42 4c 45 5f 4d  IT_PATH_ENABLE_M
69d0: 41 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f 48 4f  AJOR_SECURITY_HO
69e0: 4c 45 29 0a 73 74 61 74 69 63 20 76 6f 69 64 20  LE).static void 
69f0: 61 70 70 66 73 5f 65 78 69 74 28 76 6f 69 64 29  appfs_exit(void)
6a00: 20 7b 0a 09 69 6e 74 20 67 6c 6f 62 61 6c 5f 69   {..int global_i
6a10: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 3b  nterp_reset_key;
6a20: 0a 0a 09 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70  ...global_interp
6a30: 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 5f 5f 73  _reset_key = __s
6a40: 79 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 61 64  ync_fetch_and_ad
6a50: 64 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  d(&interp_reset_
6a60: 6b 65 79 2c 20 30 29 3b 0a 09 5f 5f 73 79 6e 63  key, 0);..__sync
6a70: 5f 66 65 74 63 68 5f 61 6e 64 5f 73 75 62 28 26  _fetch_and_sub(&
6a80: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
6a90: 2c 20 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f  , global_interp_
6aa0: 72 65 73 65 74 5f 6b 65 79 29 3b 0a 0a 09 77 68  reset_key);...wh
6ab0: 69 6c 65 20 28 5f 5f 73 79 6e 63 5f 73 75 62 5f  ile (__sync_sub_
6ac0: 61 6e 64 5f 66 65 74 63 68 28 26 69 6e 74 65 72  and_fetch(&inter
6ad0: 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 31 29 20  p_reset_key, 1) 
6ae0: 3e 3d 20 30 29 20 7b 0a 09 09 2f 2a 20 42 75 73  >= 0) {.../* Bus
6af0: 79 20 4c 6f 6f 70 20 2a 2f 0a 09 7d 0a 0a 09 67  y Loop */..}...g
6b00: 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73  lobal_interp_res
6b10: 65 74 5f 6b 65 79 20 3d 20 5f 5f 73 79 6e 63 5f  et_key = __sync_
6b20: 66 65 74 63 68 5f 61 6e 64 5f 61 64 64 28 26 69  fetch_and_add(&i
6b30: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c  nterp_reset_key,
6b40: 20 30 29 3b 0a 09 69 66 20 28 67 6c 6f 62 61 6c   0);..if (global
6b50: 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65  _interp_reset_ke
6b60: 79 20 21 3d 20 2d 31 29 20 7b 0a 09 09 41 50 50  y != -1) {...APP
6b70: 46 53 5f 44 45 42 55 47 28 22 45 72 72 6f 72 20  FS_DEBUG("Error 
6b80: 73 65 6e 64 69 6e 67 20 6b 69 6c 6c 20 73 69 67  sending kill sig
6b90: 6e 61 6c 20 74 6f 20 61 6c 6c 20 74 68 72 65 61  nal to all threa
6ba0: 64 73 2c 20 61 62 6f 72 74 69 6e 67 20 61 6e 79  ds, aborting any
6bb0: 77 61 79 2e 22 29 3b 0a 09 7d 0a 0a 09 61 70 70  way.");..}...app
6bc0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
6bd0: 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c  _cache_flush(-1,
6be0: 20 2d 31 29 3b 0a 0a 09 66 75 73 65 5f 65 78 69   -1);...fuse_exi
6bf0: 74 28 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65  t(fuse_get_conte
6c00: 78 74 28 29 2d 3e 66 75 73 65 29 3b 0a 0a 09 72  xt()->fuse);...r
6c10: 65 74 75 72 6e 3b 0a 7d 0a 23 65 6e 64 69 66 0a  eturn;.}.#endif.
6c20: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
6c30: 73 5f 66 75 73 65 5f 72 65 61 64 6c 69 6e 6b 28  s_fuse_readlink(
6c40: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
6c50: 2c 20 63 68 61 72 20 2a 62 75 66 2c 20 73 69 7a  , char *buf, siz
6c60: 65 5f 74 20 73 69 7a 65 29 20 7b 0a 09 73 74 72  e_t size) {..str
6c70: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e  uct appfs_pathin
6c80: 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69 6e  fo pathinfo;..in
6c90: 74 20 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09  t retval = 0;...
6ca0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
6cb0: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
6cc0: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 70  ..)", path);...p
6cd0: 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41  athinfo.type = A
6ce0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e  PPFS_PATHTYPE_IN
6cf0: 56 41 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20  VALID;...retval 
6d00: 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  = appfs_get_path
6d10: 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74  _info(path, &pat
6d20: 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65 74  hinfo);..if (ret
6d30: 76 61 6c 20 21 3d 20 30 29 20 7b 0a 09 09 72 65  val != 0) {...re
6d40: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d  turn(retval);..}
6d50: 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e  ...if (pathinfo.
6d60: 74 79 70 65 20 21 3d 20 41 50 50 46 53 5f 50 41  type != APPFS_PA
6d70: 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 29 20  THTYPE_SYMLINK) 
6d80: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4e 56  {...return(-EINV
6d90: 41 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 73  AL);..}...if ((s
6da0: 74 72 6c 65 6e 28 70 61 74 68 69 6e 66 6f 2e 74  trlen(pathinfo.t
6db0: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e  ypeinfo.symlink.
6dc0: 73 6f 75 72 63 65 29 20 2b 20 31 29 20 3e 20 73  source) + 1) > s
6dd0: 69 7a 65 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ize) {...return(
6de0: 2d 45 4e 41 4d 45 54 4f 4f 4c 4f 4e 47 29 3b 0a  -ENAMETOOLONG);.
6df0: 09 7d 0a 0a 09 6d 65 6d 63 70 79 28 62 75 66 2c  .}...memcpy(buf,
6e00: 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e   pathinfo.typein
6e10: 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63  fo.symlink.sourc
6e20: 65 2c 20 73 74 72 6c 65 6e 28 70 61 74 68 69 6e  e, strlen(pathin
6e30: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c  fo.typeinfo.syml
6e40: 69 6e 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31 29  ink.source) + 1)
6e50: 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  ;...return(0);.}
6e60: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
6e70: 66 73 5f 66 75 73 65 5f 67 65 74 61 74 74 72 28  fs_fuse_getattr(
6e80: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
6e90: 2c 20 73 74 72 75 63 74 20 73 74 61 74 20 2a 73  , struct stat *s
6ea0: 74 62 75 66 29 20 7b 0a 09 73 74 72 75 63 74 20  tbuf) {..struct 
6eb0: 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70  appfs_pathinfo p
6ec0: 61 74 68 69 6e 66 6f 3b 0a 09 69 6e 74 20 63 68  athinfo;..int ch
6ed0: 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65 72 49  angeOwnerToUserI
6ee0: 66 50 61 63 6b 61 67 65 64 3b 0a 09 69 6e 74 20  fPackaged;..int 
6ef0: 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c  retval;...retval
6f00: 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45   = 0;...APPFS_DE
6f10: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
6f20: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
6f30: 74 68 29 3b 0a 0a 23 69 66 20 28 64 65 66 69 6e  th);..#if (defin
6f40: 65 64 28 44 45 42 55 47 29 20 26 26 20 64 65 66  ed(DEBUG) && def
6f50: 69 6e 65 64 28 41 50 50 46 53 5f 45 58 49 54 5f  ined(APPFS_EXIT_
6f60: 50 41 54 48 29 29 20 7c 7c 20 64 65 66 69 6e 65  PATH)) || define
6f70: 64 28 41 50 50 46 53 5f 45 58 49 54 5f 50 41 54  d(APPFS_EXIT_PAT
6f80: 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f 53  H_ENABLE_MAJOR_S
6f90: 45 43 55 52 49 54 59 5f 48 4f 4c 45 29 0a 09 2f  ECURITY_HOLE)../
6fa0: 2a 0a 09 20 2a 20 54 68 69 73 20 69 73 20 61 20  *.. * This is a 
6fb0: 6d 61 6a 6f 72 20 73 65 63 75 72 69 74 79 20 69  major security i
6fc0: 73 73 75 65 20 73 6f 20 77 65 20 63 61 6e 6e 6f  ssue so we canno
6fd0: 74 20 6c 65 74 20 69 74 20 62 65 20 63 6f 6d 70  t let it be comp
6fe0: 69 6c 65 64 20 69 6e 74 6f 0a 09 20 2a 20 61 6e  iled into.. * an
6ff0: 79 20 72 65 6c 65 61 73 65 0a 09 20 2a 2f 0a 0a  y release.. */..
7000: 09 69 66 20 28 73 74 72 63 6d 70 28 70 61 74 68  .if (strcmp(path
7010: 2c 20 22 2f 65 78 69 74 22 29 20 3d 3d 20 30 29  , "/exit") == 0)
7020: 20 7b 0a 09 09 61 70 70 66 73 5f 65 78 69 74 28   {...appfs_exit(
7030: 29 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 70  );..}.#endif...p
7040: 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41  athinfo.type = A
7050: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e  PPFS_PATHTYPE_IN
7060: 56 41 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20  VALID;...retval 
7070: 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  = appfs_get_path
7080: 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74  _info(path, &pat
7090: 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65 74  hinfo);..if (ret
70a0: 76 61 6c 20 21 3d 20 30 29 20 7b 0a 09 09 69 66  val != 0) {...if
70b0: 20 28 72 65 74 76 61 6c 20 3d 3d 20 2d 45 4e 4f   (retval == -ENO
70c0: 45 4e 54 29 20 7b 0a 09 09 09 41 50 50 46 53 5f  ENT) {....APPFS_
70d0: 44 45 42 55 47 28 22 67 65 74 5f 70 61 74 68 5f  DEBUG("get_path_
70e0: 69 6e 66 6f 20 72 65 74 75 72 6e 65 64 20 45 4e  info returned EN
70f0: 4f 45 4e 54 2c 20 72 65 74 75 72 6e 69 6e 67 20  OENT, returning 
7100: 69 74 20 61 73 20 77 65 6c 6c 2e 22 29 3b 0a 09  it as well.");..
7110: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 41 50 50  .} else {....APP
7120: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
7130: 20 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20 66   get_path_info f
7140: 61 69 6c 65 64 22 29 3b 0a 09 09 7d 0a 0a 09 09  ailed");...}....
7150: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a  return(retval);.
7160: 09 7d 0a 0a 09 6d 65 6d 73 65 74 28 73 74 62 75  .}...memset(stbu
7170: 66 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73 74 72  f, 0, sizeof(str
7180: 75 63 74 20 73 74 61 74 29 29 3b 0a 0a 09 73 74  uct stat));...st
7190: 62 75 66 2d 3e 73 74 5f 6d 74 69 6d 65 20 3d 20  buf->st_mtime = 
71a0: 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09  pathinfo.time;..
71b0: 73 74 62 75 66 2d 3e 73 74 5f 63 74 69 6d 65 20  stbuf->st_ctime 
71c0: 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b  = pathinfo.time;
71d0: 0a 09 73 74 62 75 66 2d 3e 73 74 5f 61 74 69 6d  ..stbuf->st_atim
71e0: 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d  e = pathinfo.tim
71f0: 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 69 6e  e;..stbuf->st_in
7200: 6f 20 20 20 3d 20 70 61 74 68 69 6e 66 6f 2e 69  o   = pathinfo.i
7210: 6e 6f 64 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74  node;..stbuf->st
7220: 5f 6d 6f 64 65 20 20 3d 20 30 3b 0a 0a 09 63 68  _mode  = 0;...ch
7230: 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65 72 49  angeOwnerToUserI
7240: 66 50 61 63 6b 61 67 65 64 20 3d 20 31 3b 0a 0a  fPackaged = 1;..
7250: 09 73 77 69 74 63 68 20 28 70 61 74 68 69 6e 66  .switch (pathinf
7260: 6f 2e 74 79 70 65 29 20 7b 0a 09 09 63 61 73 65  o.type) {...case
7270: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
7280: 44 49 52 45 43 54 4f 52 59 3a 0a 09 09 09 73 74  DIRECTORY:....st
7290: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53  buf->st_mode = S
72a0: 5f 49 46 44 49 52 20 7c 20 30 35 35 35 3b 0a 09  _IFDIR | 0555;..
72b0: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e  ..stbuf->st_nlin
72c0: 6b 20 3d 20 32 20 2b 20 70 61 74 68 69 6e 66 6f  k = 2 + pathinfo
72d0: 2e 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68  .typeinfo.dir.ch
72e0: 69 6c 64 63 6f 75 6e 74 3b 0a 09 09 09 62 72 65  ildcount;....bre
72f0: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53  ak;...case APPFS
7300: 5f 50 41 54 48 54 59 50 45 5f 46 49 4c 45 3a 0a  _PATHTYPE_FILE:.
7310: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ...stbuf->st_mod
7320: 65 20 3d 20 53 5f 49 46 52 45 47 20 7c 20 30 34  e = S_IFREG | 04
7330: 34 34 3b 0a 0a 09 09 09 69 66 20 28 70 61 74 68  44;.....if (path
7340: 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69  info.typeinfo.fi
7350: 6c 65 2e 65 78 65 63 75 74 61 62 6c 65 29 20 7b  le.executable) {
7360: 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d  .....stbuf->st_m
7370: 6f 64 65 20 7c 3d 20 30 31 31 31 3b 0a 09 09 09  ode |= 0111;....
7380: 7d 0a 0a 09 09 09 69 66 20 28 70 61 74 68 69 6e  }.....if (pathin
7390: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  fo.typeinfo.file
73a0: 2e 73 75 69 64 52 6f 6f 74 29 20 7b 0a 09 09 09  .suidRoot) {....
73b0: 09 63 68 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73  .changeOwnerToUs
73c0: 65 72 49 66 50 61 63 6b 61 67 65 64 20 3d 20 30  erIfPackaged = 0
73d0: 3b 0a 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74  ;......stbuf->st
73e0: 5f 6d 6f 64 65 20 7c 3d 20 30 34 30 30 30 3b 0a  _mode |= 04000;.
73f0: 09 09 09 7d 0a 0a 09 09 09 69 66 20 28 70 61 74  ...}.....if (pat
7400: 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66  hinfo.typeinfo.f
7410: 69 6c 65 2e 77 6f 72 6c 64 61 63 63 65 73 73 69  ile.worldaccessi
7420: 62 6c 65 29 20 7b 0a 09 09 09 09 73 74 62 75 66  ble) {.....stbuf
7430: 2d 3e 73 74 5f 6d 6f 64 65 20 26 3d 20 7e 30 37  ->st_mode &= ~07
7440: 37 3b 0a 09 09 09 7d 0a 0a 09 09 09 73 74 62 75  7;....}.....stbu
7450: 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b  f->st_nlink = 1;
7460: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69  ....stbuf->st_si
7470: 7a 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 79  ze = pathinfo.ty
7480: 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65  peinfo.file.size
7490: 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63  ;.....break;...c
74a0: 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59  ase APPFS_PATHTY
74b0: 50 45 5f 53 59 4d 4c 49 4e 4b 3a 0a 09 09 09 73  PE_SYMLINK:....s
74c0: 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20  tbuf->st_mode = 
74d0: 53 5f 49 46 4c 4e 4b 20 7c 20 30 35 35 35 3b 0a  S_IFLNK | 0555;.
74e0: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69  ...stbuf->st_nli
74f0: 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66  nk = 1;....stbuf
7500: 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 70 61 74 68  ->st_size = path
7510: 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79  info.typeinfo.sy
7520: 6d 6c 69 6e 6b 2e 73 69 7a 65 3b 0a 09 09 09 62  mlink.size;....b
7530: 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50  reak;...case APP
7540: 46 53 5f 50 41 54 48 54 59 50 45 5f 53 4f 43 4b  FS_PATHTYPE_SOCK
7550: 45 54 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74  ET:....stbuf->st
7560: 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 53 4f 43 4b  _mode = S_IFSOCK
7570: 20 7c 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75   | 0555;....stbu
7580: 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b  f->st_nlink = 1;
7590: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69  ....stbuf->st_si
75a0: 7a 65 20 3d 20 30 3b 0a 09 09 09 62 72 65 61 6b  ze = 0;....break
75b0: 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50  ;...case APPFS_P
75c0: 41 54 48 54 59 50 45 5f 46 49 46 4f 3a 0a 09 09  ATHTYPE_FIFO:...
75d0: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
75e0: 3d 20 53 5f 49 46 49 46 4f 20 7c 20 30 35 35 35  = S_IFIFO | 0555
75f0: 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e  ;....stbuf->st_n
7600: 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62  link = 1;....stb
7610: 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 30 3b  uf->st_size = 0;
7620: 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73  ....break;...cas
7630: 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  e APPFS_PATHTYPE
7640: 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 3a  _DOES_NOT_EXIST:
7650: 0a 09 09 09 72 65 74 76 61 6c 20 3d 20 2d 45 4e  ....retval = -EN
7660: 4f 45 4e 54 3b 0a 0a 09 09 09 62 72 65 61 6b 3b  OENT;.....break;
7670: 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41  ...case APPFS_PA
7680: 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3a 0a  THTYPE_INVALID:.
7690: 09 09 09 72 65 74 76 61 6c 20 3d 20 2d 45 49 4f  ...retval = -EIO
76a0: 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a 09 7d 0a  ;.....break;..}.
76b0: 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 70  ..if (pathinfo.p
76c0: 61 63 6b 61 67 65 64 20 26 26 20 63 68 61 6e 67  ackaged && chang
76d0: 65 4f 77 6e 65 72 54 6f 55 73 65 72 49 66 50 61  eOwnerToUserIfPa
76e0: 63 6b 61 67 65 64 29 20 7b 0a 09 09 73 74 62 75  ckaged) {...stbu
76f0: 66 2d 3e 73 74 5f 75 69 64 20 20 20 3d 20 61 70  f->st_uid   = ap
7700: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b  pfs_get_fsuid();
7710: 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f 67 69 64  ...stbuf->st_gid
7720: 20 20 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66     = appfs_get_f
7730: 73 67 69 64 28 29 3b 0a 09 09 73 74 62 75 66 2d  sgid();...stbuf-
7740: 3e 73 74 5f 6d 6f 64 65 20 7c 3d 20 30 32 30 30  >st_mode |= 0200
7750: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65  ;..}...return(re
7760: 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  tval);.}..static
7770: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
7780: 72 65 61 64 64 69 72 28 63 6f 6e 73 74 20 63 68  readdir(const ch
7790: 61 72 20 2a 70 61 74 68 2c 20 76 6f 69 64 20 2a  ar *path, void *
77a0: 62 75 66 2c 20 66 75 73 65 5f 66 69 6c 6c 5f 64  buf, fuse_fill_d
77b0: 69 72 5f 74 20 66 69 6c 6c 65 72 2c 20 6f 66 66  ir_t filler, off
77c0: 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63  _t offset, struc
77d0: 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f  t fuse_file_info
77e0: 20 2a 66 69 29 20 7b 0a 09 54 63 6c 5f 49 6e 74   *fi) {..Tcl_Int
77f0: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63  erp *interp;..Tc
7800: 6c 5f 4f 62 6a 20 2a 2a 63 68 69 6c 64 72 65 6e  l_Obj **children
7810: 3b 0a 09 69 6e 74 20 63 68 69 6c 64 72 65 6e 5f  ;..int children_
7820: 63 6f 75 6e 74 2c 20 69 64 78 3b 0a 09 69 6e 74  count, idx;..int
7830: 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46   tcl_ret;...APPF
7840: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
7850: 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22  path = %s, ...)"
7860: 2c 20 70 61 74 68 29 3b 0a 0a 09 69 6e 74 65 72  , path);...inter
7870: 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74  p = appfs_TclInt
7880: 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65  erp();..if (inte
7890: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
78a0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72  APPFS_DEBUG("err
78b0: 6f 72 3a 20 55 6e 61 62 6c 65 20 74 6f 20 67 65  or: Unable to ge
78c0: 74 20 61 6e 20 69 6e 74 65 72 70 72 65 74 65 72  t an interpreter
78d0: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30 29  ");....return(0)
78e0: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
78f0: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65  l_libtcl(Tcl_Pre
7900: 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a  serve(interp);).
7910: 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e  ..filler(buf, ".
7920: 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 66 69  ", NULL, 0);..fi
7930: 6c 6c 65 72 28 62 75 66 2c 20 22 2e 2e 22 2c 20  ller(buf, "..", 
7940: 4e 55 4c 4c 2c 20 30 29 3b 0a 0a 09 74 63 6c 5f  NULL, 0);...tcl_
7950: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
7960: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20  Eval(interp, 2, 
7970: 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 63 68 69  "::appfs::getchi
7980: 6c 64 72 65 6e 22 2c 20 70 61 74 68 29 3b 0a 09  ldren", path);..
7990: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
79a0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
79b0: 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a  _DEBUG("::appfs:
79c0: 3a 67 65 74 63 68 69 6c 64 72 65 6e 28 25 73 29  :getchildren(%s)
79d0: 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29   failed.", path)
79e0: 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ;...appfs_call_l
79f0: 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f  ibtcl(....APPFS_
7a00: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72  DEBUG("Tcl Error
7a10: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
7a20: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
7a30: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61  terp));...)....a
7a40: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
7a50: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
7a60: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e  erp);)....return
7a70: 28 30 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  (0);..}...appfs_
7a80: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74  call_libtcl(...t
7a90: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 4c 69 73  cl_ret = Tcl_Lis
7aa0: 74 4f 62 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28  tObjGetElements(
7ab0: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 4f  interp, Tcl_GetO
7ac0: 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  bjResult(interp)
7ad0: 2c 20 26 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e  , &children_coun
7ae0: 74 2c 20 26 63 68 69 6c 64 72 65 6e 29 3b 0a 09  t, &children);..
7af0: 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  )..if (tcl_ret !
7b00: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50  = TCL_OK) {...AP
7b10: 50 46 53 5f 44 45 42 55 47 28 22 50 61 72 73 69  PFS_DEBUG("Parsi
7b20: 6e 67 20 6c 69 73 74 20 6f 66 20 63 68 69 6c 64  ng list of child
7b30: 72 65 6e 20 6f 6e 20 70 61 74 68 20 25 73 20 66  ren on path %s f
7b40: 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a  ailed.", path);.
7b50: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
7b60: 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45  tcl(....APPFS_DE
7b70: 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69  BUG("Tcl Error i
7b80: 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53  s: %s", Tcl_GetS
7b90: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
7ba0: 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70  rp));...)....app
7bb0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
7bc0: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
7bd0: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 30  p);)....return(0
7be0: 29 3b 0a 09 7d 0a 0a 09 66 6f 72 20 28 69 64 78  );..}...for (idx
7bf0: 20 3d 20 30 3b 20 69 64 78 20 3c 20 63 68 69 6c   = 0; idx < chil
7c00: 64 72 65 6e 5f 63 6f 75 6e 74 3b 20 69 64 78 2b  dren_count; idx+
7c10: 2b 29 20 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c  +) {...appfs_cal
7c20: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 66 69 6c  l_libtcl(....fil
7c30: 6c 65 72 28 62 75 66 2c 20 54 63 6c 5f 47 65 74  ler(buf, Tcl_Get
7c40: 53 74 72 69 6e 67 28 63 68 69 6c 64 72 65 6e 5b  String(children[
7c50: 69 64 78 5d 29 2c 20 4e 55 4c 4c 2c 20 30 29 3b  idx]), NULL, 0);
7c60: 0a 09 09 29 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  ...)..}...appfs_
7c70: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
7c80: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
7c90: 29 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  )...return(0);.}
7ca0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
7cb0: 66 73 5f 66 75 73 65 5f 6f 70 65 6e 28 63 6f 6e  fs_fuse_open(con
7cc0: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73  st char *path, s
7cd0: 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f  truct fuse_file_
7ce0: 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c  info *fi) {..Tcl
7cf0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
7d00: 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70  ..struct appfs_p
7d10: 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f  athinfo pathinfo
7d20: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72  ;..const char *r
7d30: 65 61 6c 5f 70 61 74 68 2c 20 2a 6d 6f 64 65 3b  eal_path, *mode;
7d40: 0a 09 69 6e 74 20 67 70 69 5f 72 65 74 2c 20 74  ..int gpi_ret, t
7d50: 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 66 68 3b  cl_ret;..int fh;
7d60: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
7d70: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
7d80: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
7d90: 0a 09 67 70 69 5f 72 65 74 20 3d 20 61 70 70 66  ..gpi_ret = appf
7da0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28  s_get_path_info(
7db0: 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29  path, &pathinfo)
7dc0: 3b 0a 0a 09 69 66 20 28 28 66 69 2d 3e 66 6c 61  ;...if ((fi->fla
7dd0: 67 73 20 26 20 28 4f 5f 57 52 4f 4e 4c 59 7c 4f  gs & (O_WRONLY|O
7de0: 5f 43 52 45 41 54 29 29 20 3d 3d 20 28 4f 5f 43  _CREAT)) == (O_C
7df0: 52 45 41 54 7c 4f 5f 57 52 4f 4e 4c 59 29 29 20  REAT|O_WRONLY)) 
7e00: 7b 0a 09 09 2f 2a 20 54 68 65 20 66 69 6c 65 20  {.../* The file 
7e10: 77 69 6c 6c 20 62 65 20 63 72 65 61 74 65 64 20  will be created 
7e20: 69 66 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 65  if it does not e
7e30: 78 69 73 74 20 2a 2f 0a 09 09 69 66 20 28 67 70  xist */...if (gp
7e40: 69 5f 72 65 74 20 21 3d 20 30 20 26 26 20 67 70  i_ret != 0 && gp
7e50: 69 5f 72 65 74 20 21 3d 20 2d 45 4e 4f 45 4e 54  i_ret != -ENOENT
7e60: 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42  ) {....APPFS_DEB
7e70: 55 47 28 22 65 72 72 6f 72 3a 20 67 65 74 5f 70  UG("error: get_p
7e80: 61 74 68 5f 69 6e 66 6f 20 66 61 69 6c 65 64 22  ath_info failed"
7e90: 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 67 70  );.....return(gp
7ea0: 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d  i_ret);...}....m
7eb0: 6f 64 65 20 3d 20 22 63 72 65 61 74 65 22 3b 0a  ode = "create";.
7ec0: 0a 09 09 2f 2a 0a 09 09 20 2a 20 57 65 20 68 61  .../*... * We ha
7ed0: 76 65 20 74 6f 20 63 6c 65 61 72 20 74 68 65 20  ve to clear the 
7ee0: 63 61 63 68 65 20 68 65 72 65 20 73 6f 20 74 68  cache here so th
7ef0: 61 74 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  at the number of
7f00: 0a 09 09 20 2a 20 6c 69 6e 6b 73 20 67 65 74 73  ... * links gets
7f10: 20 6d 61 69 6e 74 61 69 6e 65 64 20 6f 6e 20 74   maintained on t
7f20: 68 65 20 70 61 72 65 6e 74 20 64 69 72 65 63 74  he parent direct
7f30: 6f 72 79 0a 09 09 20 2a 2f 0a 09 09 61 70 70 66  ory... */...appf
7f40: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
7f50: 63 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66  cache_flush(appf
7f60: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d  s_get_fsuid(), -
7f70: 31 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09  1);..} else {...
7f80: 2f 2a 20 54 68 65 20 66 69 6c 65 20 6d 75 73 74  /* The file must
7f90: 20 61 6c 72 65 61 64 79 20 65 78 69 73 74 20 2a   already exist *
7fa0: 2f 0a 09 09 69 66 20 28 67 70 69 5f 72 65 74 20  /...if (gpi_ret 
7fb0: 21 3d 20 30 29 20 7b 0a 09 09 09 41 50 50 46 53  != 0) {....APPFS
7fc0: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 67  _DEBUG("error: g
7fd0: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20 66 61 69  et_path_info fai
7fe0: 6c 65 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72  led");.....retur
7ff0: 6e 28 67 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a  n(gpi_ret);...}.
8000: 0a 09 09 6d 6f 64 65 20 3d 20 22 22 3b 0a 0a 09  ...mode = "";...
8010: 09 69 66 20 28 28 66 69 2d 3e 66 6c 61 67 73 20  .if ((fi->flags 
8020: 26 20 4f 5f 57 52 4f 4e 4c 59 29 20 3d 3d 20 4f  & O_WRONLY) == O
8030: 5f 57 52 4f 4e 4c 59 29 20 7b 0a 09 09 09 6d 6f  _WRONLY) {....mo
8040: 64 65 20 3d 20 22 77 72 69 74 65 22 3b 0a 09 09  de = "write";...
8050: 7d 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69  }..}...if (pathi
8060: 6e 66 6f 2e 74 79 70 65 20 3d 3d 20 41 50 50 46  nfo.type == APPF
8070: 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45 43  S_PATHTYPE_DIREC
8080: 54 4f 52 59 29 20 7b 0a 09 09 41 50 50 46 53 5f  TORY) {...APPFS_
8090: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 41 73  DEBUG("error: As
80a0: 6b 65 64 20 74 6f 20 6f 70 65 6e 20 61 20 64 69  ked to open a di
80b0: 72 65 63 74 6f 72 79 2e 22 29 3b 0a 0a 09 09 72  rectory.");....r
80c0: 65 74 75 72 6e 28 2d 45 49 53 44 49 52 29 3b 0a  eturn(-EISDIR);.
80d0: 09 7d 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  .}...interp = ap
80e0: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  pfs_TclInterp();
80f0: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
8100: 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f  NULL) {...APPFS_
8110: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 55 6e  DEBUG("error: Un
8120: 61 62 6c 65 20 74 6f 20 67 65 74 20 61 6e 20 69  able to get an i
8130: 6e 74 65 72 70 72 65 74 65 72 22 29 3b 0a 0a 09  nterpreter");...
8140: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
8150: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
8160: 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72  ibtcl(Tcl_Preser
8170: 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74  ve(interp);)...t
8180: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
8190: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
81a0: 33 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65  3, "::appfs::ope
81b0: 6e 70 61 74 68 22 2c 20 70 61 74 68 2c 20 6d 6f  npath", path, mo
81c0: 64 65 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65  de);..if (tcl_re
81d0: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
81e0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a  .APPFS_DEBUG("::
81f0: 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28  appfs::openpath(
8200: 25 73 2c 20 25 73 29 20 66 61 69 6c 65 64 2e 22  %s, %s) failed."
8210: 2c 20 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 09  , path, mode);..
8220: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
8230: 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42  cl(....APPFS_DEB
8240: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
8250: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
8260: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
8270: 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66  p));...)....appf
8280: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
8290: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
82a0: 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45  );)....return(-E
82b0: 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  IO);..}...appfs_
82c0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72  call_libtcl(...r
82d0: 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47  eal_path = Tcl_G
82e0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
82f0: 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70  nterp);..)...app
8300: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
8310: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
8320: 70 29 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f  p);)...if (real_
8330: 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  path == NULL) {.
8340: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65  ..APPFS_DEBUG("e
8350: 72 72 6f 72 3a 20 72 65 61 6c 5f 70 61 74 68 20  rror: real_path 
8360: 77 61 73 20 4e 55 4c 4c 2e 22 29 0a 0a 09 09 72  was NULL.")....r
8370: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
8380: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
8390: 72 61 6e 73 6c 61 74 65 64 20 72 65 71 75 65 73  ranslated reques
83a0: 74 20 74 6f 20 6f 70 65 6e 20 25 73 20 74 6f 20  t to open %s to 
83b0: 6f 70 65 6e 69 6e 67 20 25 73 20 28 6d 6f 64 65  opening %s (mode
83c0: 20 3d 20 5c 22 25 73 5c 22 29 22 2c 20 70 61 74   = \"%s\")", pat
83d0: 68 2c 20 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f  h, real_path, mo
83e0: 64 65 29 3b 0a 0a 09 66 68 20 3d 20 6f 70 65 6e  de);...fh = open
83f0: 28 72 65 61 6c 5f 70 61 74 68 2c 20 66 69 2d 3e  (real_path, fi->
8400: 66 6c 61 67 73 2c 20 30 36 30 30 29 3b 0a 0a 09  flags, 0600);...
8410: 69 66 20 28 66 68 20 3c 20 30 29 20 7b 0a 09 09  if (fh < 0) {...
8420: 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72  APPFS_DEBUG("err
8430: 6f 72 3a 20 6f 70 65 6e 20 66 61 69 6c 65 64 22  or: open failed"
8440: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 65 72 72  );....return(err
8450: 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66  no * -1);..}...f
8460: 69 2d 3e 66 68 20 3d 20 66 68 3b 0a 0a 09 72 65  i->fh = fh;...re
8470: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
8480: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
8490: 65 5f 63 6c 6f 73 65 28 63 6f 6e 73 74 20 63 68  e_close(const ch
84a0: 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74  ar *path, struct
84b0: 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20   fuse_file_info 
84c0: 2a 66 69 29 20 7b 0a 09 69 6e 74 20 63 6c 6f 73  *fi) {..int clos
84d0: 65 5f 72 65 74 3b 0a 0a 09 61 70 70 66 73 5f 67  e_ret;...appfs_g
84e0: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
84f0: 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70 70 66  he_rm(path, appf
8500: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a  s_get_fsuid());.
8510: 0a 09 63 6c 6f 73 65 5f 72 65 74 20 3d 20 63 6c  ..close_ret = cl
8520: 6f 73 65 28 66 69 2d 3e 66 68 29 3b 0a 09 69 66  ose(fi->fh);..if
8530: 20 28 63 6c 6f 73 65 5f 72 65 74 20 21 3d 20 30   (close_ret != 0
8540: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
8550: 47 28 22 65 72 72 6f 72 3a 20 63 6c 6f 73 65 20  G("error: close 
8560: 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09 72 65 74  failed");....ret
8570: 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b  urn(errno * -1);
8580: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  ..}...return(0);
8590: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
85a0: 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 28 63  ppfs_fuse_read(c
85b0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
85c0: 20 63 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65   char *buf, size
85d0: 5f 74 20 73 69 7a 65 2c 20 6f 66 66 5f 74 20 6f  _t size, off_t o
85e0: 66 66 73 65 74 2c 20 73 74 72 75 63 74 20 66 75  ffset, struct fu
85f0: 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69  se_file_info *fi
8600: 29 20 7b 0a 09 73 73 69 7a 65 5f 74 20 72 65 61  ) {..ssize_t rea
8610: 64 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65 74 76  d_ret;..int retv
8620: 61 6c 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  al;...APPFS_DEBU
8630: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
8640: 20 25 73 2c 20 62 75 66 2c 20 25 6c 6c 69 2c 20   %s, buf, %lli, 
8650: 25 6c 6c 69 2c 20 66 64 3d 25 6c 6c 69 29 22 2c  %lli, fd=%lli)",
8660: 20 70 61 74 68 2c 20 28 6c 6f 6e 67 20 6c 6f 6e   path, (long lon
8670: 67 29 20 73 69 7a 65 2c 20 28 6c 6f 6e 67 20 6c  g) size, (long l
8680: 6f 6e 67 29 20 6f 66 66 73 65 74 2c 20 28 6c 6f  ong) offset, (lo
8690: 6e 67 20 6c 6f 6e 67 29 20 66 69 2d 3e 66 68 29  ng long) fi->fh)
86a0: 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a  ;...retval = 0;.
86b0: 0a 09 77 68 69 6c 65 20 28 73 69 7a 65 20 21 3d  ..while (size !=
86c0: 20 30 29 20 7b 0a 09 09 72 65 61 64 5f 72 65 74   0) {...read_ret
86d0: 20 3d 20 70 72 65 61 64 28 66 69 2d 3e 66 68 2c   = pread(fi->fh,
86e0: 20 62 75 66 2c 20 73 69 7a 65 2c 20 6f 66 66 73   buf, size, offs
86f0: 65 74 29 3b 0a 0a 09 09 69 66 20 28 72 65 61 64  et);....if (read
8700: 5f 72 65 74 20 3c 20 30 29 20 7b 0a 09 09 09 41  _ret < 0) {....A
8710: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
8720: 72 3a 20 72 65 61 64 20 66 61 69 6c 65 64 22 29  r: read failed")
8730: 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 65 72 72  ;.....return(err
8740: 6e 6f 20 2a 20 2d 31 29 3b 0a 09 09 7d 0a 0a 09  no * -1);...}...
8750: 09 69 66 20 28 72 65 61 64 5f 72 65 74 20 3d 3d  .if (read_ret ==
8760: 20 30 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b 0a   0) {....break;.
8770: 09 09 7d 0a 0a 09 09 73 69 7a 65 20 2d 3d 20 72  ..}....size -= r
8780: 65 61 64 5f 72 65 74 3b 0a 09 09 62 75 66 20 20  ead_ret;...buf  
8790: 2b 3d 20 72 65 61 64 5f 72 65 74 3b 0a 09 09 6f  += read_ret;...o
87a0: 66 66 73 65 74 20 2b 3d 20 72 65 61 64 5f 72 65  ffset += read_re
87b0: 74 3b 0a 09 09 72 65 74 76 61 6c 20 2b 3d 20 72  t;...retval += r
87c0: 65 61 64 5f 72 65 74 3b 0a 09 7d 0a 0a 09 69 66  ead_ret;..}...if
87d0: 20 28 73 69 7a 65 20 21 3d 20 30 29 20 7b 0a 09   (size != 0) {..
87e0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72  .APPFS_DEBUG("er
87f0: 72 6f 72 3a 20 69 6e 63 6f 6d 70 6c 65 74 65 20  ror: incomplete 
8800: 72 65 61 64 20 28 74 68 69 73 20 6d 69 67 68 74  read (this might
8810: 20 62 65 20 61 6e 20 65 72 72 6f 72 20 62 65 63   be an error bec
8820: 61 75 73 65 20 46 55 53 45 20 77 69 6c 6c 20 72  ause FUSE will r
8830: 65 71 75 65 73 74 20 74 68 65 20 65 78 61 63 74  equest the exact
8840: 20 6c 65 6e 67 74 68 20 6f 66 20 74 68 65 20 66   length of the f
8850: 69 6c 65 29 22 29 3b 0a 09 7d 0a 0a 09 41 50 50  ile)");..}...APP
8860: 46 53 5f 44 45 42 55 47 28 22 52 65 74 75 72 6e  FS_DEBUG("Return
8870: 69 6e 67 3a 20 25 69 22 2c 20 72 65 74 76 61 6c  ing: %i", retval
8880: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76  );...return(retv
8890: 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  al);.}..static i
88a0: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 77 72  nt appfs_fuse_wr
88b0: 69 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ite(const char *
88c0: 70 61 74 68 2c 20 63 6f 6e 73 74 20 63 68 61 72  path, const char
88d0: 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69   *buf, size_t si
88e0: 7a 65 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74  ze, off_t offset
88f0: 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69  , struct fuse_fi
8900: 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09  le_info *fi) {..
8910: 73 73 69 7a 65 5f 74 20 77 72 69 74 65 5f 72 65  ssize_t write_re
8920: 74 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a  t;..int retval;.
8930: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45  ..APPFS_DEBUG("E
8940: 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c  nter (path = %s,
8950: 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a   ...)", path);..
8960: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  .appfs_get_path_
8970: 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61  info_cache_rm(pa
8980: 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73  th, appfs_get_fs
8990: 75 69 64 28 29 29 3b 0a 0a 09 72 65 74 76 61 6c  uid());...retval
89a0: 20 3d 20 30 3b 0a 0a 09 77 68 69 6c 65 20 28 73   = 0;...while (s
89b0: 69 7a 65 20 21 3d 20 30 29 20 7b 0a 09 09 77 72  ize != 0) {...wr
89c0: 69 74 65 5f 72 65 74 20 3d 20 70 77 72 69 74 65  ite_ret = pwrite
89d0: 28 66 69 2d 3e 66 68 2c 20 62 75 66 2c 20 73 69  (fi->fh, buf, si
89e0: 7a 65 2c 20 6f 66 66 73 65 74 29 3b 0a 0a 09 09  ze, offset);....
89f0: 69 66 20 28 77 72 69 74 65 5f 72 65 74 20 3c 20  if (write_ret < 
8a00: 30 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45  0) {....APPFS_DE
8a10: 42 55 47 28 22 65 72 72 6f 72 3a 20 77 72 69 74  BUG("error: writ
8a20: 65 20 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09 09  e failed");.....
8a30: 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d  return(errno * -
8a40: 31 29 3b 0a 09 09 7d 0a 0a 09 09 69 66 20 28 77  1);...}....if (w
8a50: 72 69 74 65 5f 72 65 74 20 3d 3d 20 30 29 20 7b  rite_ret == 0) {
8a60: 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 7d 0a 0a  ....break;...}..
8a70: 09 09 73 69 7a 65 20 2d 3d 20 77 72 69 74 65 5f  ..size -= write_
8a80: 72 65 74 3b 0a 09 09 62 75 66 20 20 2b 3d 20 77  ret;...buf  += w
8a90: 72 69 74 65 5f 72 65 74 3b 0a 09 09 6f 66 66 73  rite_ret;...offs
8aa0: 65 74 20 2b 3d 20 77 72 69 74 65 5f 72 65 74 3b  et += write_ret;
8ab0: 0a 09 09 72 65 74 76 61 6c 20 2b 3d 20 77 72 69  ...retval += wri
8ac0: 74 65 5f 72 65 74 3b 0a 09 7d 0a 0a 09 69 66 20  te_ret;..}...if 
8ad0: 28 73 69 7a 65 20 21 3d 20 30 29 20 7b 0a 09 09  (size != 0) {...
8ae0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72  APPFS_DEBUG("err
8af0: 6f 72 3a 20 69 6e 63 6f 6d 70 6c 65 74 65 20 77  or: incomplete w
8b00: 72 69 74 65 22 29 3b 0a 09 7d 0a 0a 09 72 65 74  rite");..}...ret
8b10: 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a  urn(retval);.}..
8b20: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
8b30: 5f 66 75 73 65 5f 6d 6b 6e 6f 64 28 63 6f 6e 73  _fuse_mknod(cons
8b40: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f  t char *path, mo
8b50: 64 65 5f 74 20 6d 6f 64 65 2c 20 64 65 76 5f 74  de_t mode, dev_t
8b60: 20 64 65 76 69 63 65 29 20 7b 0a 09 63 68 61 72   device) {..char
8b70: 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e   *real_path;..in
8b80: 74 20 6d 6b 6e 6f 64 5f 72 65 74 3b 0a 0a 09 41  t mknod_ret;...A
8b90: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
8ba0: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
8bb0: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69 66  .)", path);...if
8bc0: 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 43 48   ((mode & S_IFCH
8bd0: 52 29 20 3d 3d 20 53 5f 49 46 43 48 52 29 20 7b  R) == S_IFCHR) {
8be0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45 52 4d  ...return(-EPERM
8bf0: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 6d 6f 64  );..}...if ((mod
8c00: 65 20 26 20 53 5f 49 46 42 4c 4b 29 20 3d 3d 20  e & S_IFBLK) == 
8c10: 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09 72 65 74  S_IFBLK) {...ret
8c20: 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a  urn(-EPERM);..}.
8c30: 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70  ..real_path = ap
8c40: 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63  pfs_prepare_to_c
8c50: 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09 69 66  reate(path);..if
8c60: 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e   (real_path == N
8c70: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
8c80: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  -EIO);..}...appf
8c90: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
8ca0: 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b  fs_enter();...mk
8cb0: 6e 6f 64 5f 72 65 74 20 3d 20 6d 6b 6e 6f 64 28  nod_ret = mknod(
8cc0: 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 2c  real_path, mode,
8cd0: 20 64 65 76 69 63 65 29 3b 0a 0a 09 61 70 70 66   device);...appf
8ce0: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
8cf0: 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72  fs_leave();...fr
8d00: 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a  ee(real_path);..
8d10: 09 69 66 20 28 6d 6b 6e 6f 64 5f 72 65 74 20 21  .if (mknod_ret !
8d20: 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  = 0) {...return(
8d30: 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a  errno * -1);..}.
8d40: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
8d50: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
8d60: 5f 66 75 73 65 5f 63 72 65 61 74 65 28 63 6f 6e  _fuse_create(con
8d70: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d  st char *path, m
8d80: 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 73 74 72 75  ode_t mode, stru
8d90: 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66  ct fuse_file_inf
8da0: 6f 20 2a 66 69 29 20 7b 0a 09 63 68 61 72 20 2a  o *fi) {..char *
8db0: 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20  real_path;..int 
8dc0: 66 64 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  fd;...APPFS_DEBU
8dd0: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
8de0: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
8df0: 29 3b 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26  );...if ((mode &
8e00: 20 53 5f 49 46 43 48 52 29 20 3d 3d 20 53 5f 49   S_IFCHR) == S_I
8e10: 46 43 48 52 29 20 7b 0a 09 09 72 65 74 75 72 6e  FCHR) {...return
8e20: 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69  (-EPERM);..}...i
8e30: 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 42  f ((mode & S_IFB
8e40: 4c 4b 29 20 3d 3d 20 53 5f 49 46 42 4c 4b 29 20  LK) == S_IFBLK) 
8e50: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45 52  {...return(-EPER
8e60: 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61  M);..}...real_pa
8e70: 74 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70 61  th = appfs_prepa
8e80: 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 70 61 74  re_to_create(pat
8e90: 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61  h);..if (real_pa
8ea0: 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th == NULL) {...
8eb0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
8ec0: 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  ...appfs_simulat
8ed0: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
8ee0: 29 3b 0a 0a 09 66 64 20 3d 20 63 72 65 61 74 28  );...fd = creat(
8ef0: 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29  real_path, mode)
8f00: 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61  ;...appfs_simula
8f10: 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65  te_user_fs_leave
8f20: 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f  ();...free(real_
8f30: 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 66 64 20  path);...if (fd 
8f40: 3c 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  < 0) {...return(
8f50: 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a  errno * -1);..}.
8f60: 0a 09 66 69 2d 3e 66 68 20 3d 20 66 64 3b 0a 0a  ..fi->fh = fd;..
8f70: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
8f80: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
8f90: 66 75 73 65 5f 74 72 75 6e 63 61 74 65 28 63 6f  fuse_truncate(co
8fa0: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
8fb0: 6f 66 66 5f 74 20 73 69 7a 65 29 20 7b 0a 09 63  off_t size) {..c
8fc0: 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a  har *real_path;.
8fd0: 09 69 6e 74 20 74 72 75 6e 63 61 74 65 5f 72 65  .int truncate_re
8fe0: 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  t;...APPFS_DEBUG
8ff0: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
9000: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
9010: 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20  ;...real_path = 
9020: 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61 74 68 28  appfs_localpath(
9030: 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c  path);..if (real
9040: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
9050: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
9060: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f  ..}...appfs_get_
9070: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
9080: 72 6d 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67  rm(path, appfs_g
9090: 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 61  et_fsuid());...a
90a0: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
90b0: 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a  er_fs_enter();..
90c0: 09 74 72 75 6e 63 61 74 65 5f 72 65 74 20 3d 20  .truncate_ret = 
90d0: 74 72 75 6e 63 61 74 65 28 72 65 61 6c 5f 70 61  truncate(real_pa
90e0: 74 68 2c 20 73 69 7a 65 29 3b 0a 0a 09 61 70 70  th, size);...app
90f0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
9100: 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66  _fs_leave();...f
9110: 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a  ree(real_path);.
9120: 0a 09 69 66 20 28 74 72 75 6e 63 61 74 65 5f 72  ..if (truncate_r
9130: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74  et != 0) {...ret
9140: 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b  urn(errno * -1);
9150: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  ..}...return(0);
9160: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
9170: 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b  ppfs_fuse_unlink
9180: 5f 72 6d 64 69 72 28 63 6f 6e 73 74 20 63 68 61  _rmdir(const cha
9190: 72 20 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f  r *path) {..Tcl_
91a0: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
91b0: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09  .int tcl_ret;...
91c0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
91d0: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
91e0: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61  ..)", path);...a
91f0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
9200: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 61  fo_cache_flush(a
9210: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
9220: 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74 65 72 70 20  , -1);...interp 
9230: 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72  = appfs_TclInter
9240: 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  p();..if (interp
9250: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
9260: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
9270: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
9280: 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28  cl(Tcl_Preserve(
9290: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f  interp);)...tcl_
92a0: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
92b0: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20  Eval(interp, 2, 
92c0: 22 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c 69 6e 6b  "::appfs::unlink
92d0: 70 61 74 68 22 2c 20 70 61 74 68 29 3b 0a 09 69  path", path);..i
92e0: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
92f0: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
9300: 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a  DEBUG("::appfs::
9310: 75 6e 6c 69 6e 6b 70 61 74 68 28 25 73 29 20 66  unlinkpath(%s) f
9320: 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a  ailed.", path);.
9330: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
9340: 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45  tcl(....APPFS_DE
9350: 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69  BUG("Tcl Error i
9360: 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53  s: %s", Tcl_GetS
9370: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
9380: 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70  rp));...)....app
9390: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
93a0: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
93b0: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d  p);)....return(-
93c0: 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  EIO);..}...appfs
93d0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
93e0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
93f0: 3b 29 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  ;)...return(0);.
9400: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
9410: 70 66 73 5f 66 75 73 65 5f 6d 6b 64 69 72 28 63  pfs_fuse_mkdir(c
9420: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
9430: 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 29 20 7b 0a   mode_t mode) {.
9440: 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68  .char *real_path
9450: 3b 0a 09 69 6e 74 20 6d 6b 64 69 72 5f 72 65 74  ;..int mkdir_ret
9460: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
9470: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
9480: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b  s, ...)", path);
9490: 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61  ...real_path = a
94a0: 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f  ppfs_prepare_to_
94b0: 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09 69  create(path);..i
94c0: 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20  f (real_path == 
94d0: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
94e0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70  (-EIO);..}...app
94f0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
9500: 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 6d  _fs_enter();...m
9510: 6b 64 69 72 5f 72 65 74 20 3d 20 6d 6b 64 69 72  kdir_ret = mkdir
9520: 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65  (real_path, mode
9530: 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c  );...appfs_simul
9540: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76  ate_user_fs_leav
9550: 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c  e();...free(real
9560: 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 6d 6b  _path);...if (mk
9570: 64 69 72 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  dir_ret != 0) {.
9580: 09 09 69 66 20 28 65 72 72 6e 6f 20 21 3d 20 45  ..if (errno != E
9590: 45 58 49 53 54 29 20 7b 0a 09 09 09 72 65 74 75  EXIST) {....retu
95a0: 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a  rn(errno * -1);.
95b0: 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  ..}..}...return(
95c0: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
95d0: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 63 68 6d  t appfs_fuse_chm
95e0: 6f 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  od(const char *p
95f0: 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65  ath, mode_t mode
9600: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
9610: 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20  *interp;..const 
9620: 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b  char *real_path;
9630: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 2c 20 63  ..int tcl_ret, c
9640: 68 6d 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46  hmod_ret;...APPF
9650: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
9660: 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22  path = %s, ...)"
9670: 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 73  , path);...appfs
9680: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
9690: 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70  ache_rm(path, ap
96a0: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29  pfs_get_fsuid())
96b0: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  ;...interp = app
96c0: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a  fs_TclInterp();.
96d0: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
96e0: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
96f0: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  -EIO);..}...appf
9700: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
9710: 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72  l_Preserve(inter
9720: 70 29 3b 29 0a 0a 09 74 63 6c 5f 72 65 74 20 3d  p);)...tcl_ret =
9730: 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28   appfs_Tcl_Eval(
9740: 69 6e 74 65 72 70 2c 20 33 2c 20 22 3a 3a 61 70  interp, 3, "::ap
9750: 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 22 2c 20  pfs::openpath", 
9760: 70 61 74 68 2c 20 22 77 72 69 74 65 22 29 3b 0a  path, "write");.
9770: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
9780: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
9790: 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73  S_DEBUG("::appfs
97a0: 3a 3a 6f 70 65 6e 70 61 74 68 28 25 73 2c 20 25  ::openpath(%s, %
97b0: 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  s) failed.", pat
97c0: 68 2c 20 22 77 72 69 74 65 22 29 3b 0a 09 09 61  h, "write");...a
97d0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
97e0: 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  (....APPFS_DEBUG
97f0: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20  ("Tcl Error is: 
9800: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  %s", Tcl_GetStri
9810: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
9820: 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f  );...)....appfs_
9830: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
9840: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
9850: 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f  )....return(-EIO
9860: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61  );..}...appfs_ca
9870: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 61  ll_libtcl(...rea
9880: 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74  l_path = Tcl_Get
9890: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
98a0: 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73  erp);..)...appfs
98b0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
98c0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
98d0: 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61  ;)...if (real_pa
98e0: 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th == NULL) {...
98f0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
9900: 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  ...appfs_simulat
9910: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
9920: 29 3b 0a 0a 09 63 68 6d 6f 64 5f 72 65 74 20 3d  );...chmod_ret =
9930: 20 63 68 6d 6f 64 28 72 65 61 6c 5f 70 61 74 68   chmod(real_path
9940: 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73  , mode);...appfs
9950: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
9960: 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 72 65 74  s_leave();...ret
9970: 75 72 6e 28 63 68 6d 6f 64 5f 72 65 74 29 3b 0a  urn(chmod_ret);.
9980: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
9990: 70 66 73 5f 66 75 73 65 5f 73 79 6d 6c 69 6e 6b  pfs_fuse_symlink
99a0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 6f 6c 64  (const char *old
99b0: 70 61 74 68 2c 20 63 6f 6e 73 74 20 63 68 61 72  path, const char
99c0: 20 2a 6e 65 77 70 61 74 68 29 20 7b 0a 09 63 68   *newpath) {..ch
99d0: 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09  ar *real_path;..
99e0: 69 6e 74 20 73 79 6d 6c 69 6e 6b 5f 72 65 74 3b  int symlink_ret;
99f0: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
9a00: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
9a10: 2c 20 25 73 29 22 2c 20 6f 6c 64 70 61 74 68 2c  , %s)", oldpath,
9a20: 20 6e 65 77 70 61 74 68 29 3b 0a 0a 09 72 65 61   newpath);...rea
9a30: 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70  l_path = appfs_p
9a40: 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65  repare_to_create
9a50: 28 6e 65 77 70 61 74 68 29 3b 0a 09 69 66 20 28  (newpath);..if (
9a60: 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c  real_path == NUL
9a70: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  L) {...return(-E
9a80: 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  IO);..}...appfs_
9a90: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
9aa0: 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 73 79 6d 6c  _enter();...syml
9ab0: 69 6e 6b 5f 72 65 74 20 3d 20 73 79 6d 6c 69 6e  ink_ret = symlin
9ac0: 6b 28 6f 6c 64 70 61 74 68 2c 20 72 65 61 6c 5f  k(oldpath, real_
9ad0: 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f 73  path);...appfs_s
9ae0: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
9af0: 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28  leave();...free(
9b00: 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66  real_path);...if
9b10: 20 28 73 79 6d 6c 69 6e 6b 5f 72 65 74 20 21 3d   (symlink_ret !=
9b20: 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 65   0) {...return(e
9b30: 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a  rrno * -1);..}..
9b40: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f  .return(0);.}../
9b50: 2a 0a 20 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64  *. * SQLite3 mod
9b60: 65 3a 20 45 78 65 63 75 74 65 20 72 61 77 20 53  e: Execute raw S
9b70: 51 4c 20 61 6e 64 20 72 65 74 75 72 6e 20 73 75  QL and return su
9b80: 63 63 65 73 73 20 6f 72 20 66 61 69 6c 75 72 65  ccess or failure
9b90: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  . */.static int 
9ba0: 61 70 70 66 73 5f 73 71 6c 69 74 65 33 28 63 6f  appfs_sqlite3(co
9bb0: 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 29 20 7b  nst char *sql) {
9bc0: 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  ..Tcl_Interp *in
9bd0: 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61  terp;..const cha
9be0: 72 20 2a 73 71 6c 5f 72 65 74 3b 0a 09 69 6e 74  r *sql_ret;..int
9bf0: 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65   tcl_ret;...inte
9c00: 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61 74  rp = appfs_creat
9c10: 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c  e_TclInterp(NULL
9c20: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  );..if (interp =
9c30: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69  = NULL) {...fpri
9c40: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61  ntf(stderr, "Una
9c50: 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20 61 20  ble to create a 
9c60: 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e  Tcl interpreter.
9c70: 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b    Aborting.\n");
9c80: 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  ....return(1);..
9c90: 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70  }...tcl_ret = ap
9ca0: 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74  pfs_Tcl_Eval(int
9cb0: 65 72 70 2c 20 35 2c 20 22 3a 3a 61 70 70 66 73  erp, 5, "::appfs
9cc0: 3a 3a 64 62 22 2c 20 22 65 76 61 6c 22 2c 20 73  ::db", "eval", s
9cd0: 71 6c 2c 20 22 72 6f 77 22 2c 20 22 75 6e 73 65  ql, "row", "unse
9ce0: 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 72 6f  t -nocomplain ro
9cf0: 77 28 2a 29 3b 20 70 61 72 72 61 79 20 72 6f 77  w(*); parray row
9d00: 3b 20 70 75 74 73 20 5c 22 2d 2d 2d 2d 5c 22 22  ; puts \"----\""
9d10: 29 3b 0a 09 73 71 6c 5f 72 65 74 20 3d 20 54 63  );..sql_ret = Tc
9d20: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
9d30: 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20  t(interp);...if 
9d40: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
9d50: 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28  OK) {...fprintf(
9d60: 73 74 64 65 72 72 2c 20 22 5b 65 72 72 6f 72 5d  stderr, "[error]
9d70: 20 25 73 5c 6e 22 2c 20 73 71 6c 5f 72 65 74 29   %s\n", sql_ret)
9d80: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a  ;....return(1);.
9d90: 09 7d 0a 0a 09 69 66 20 28 73 71 6c 5f 72 65 74  .}...if (sql_ret
9da0: 20 26 26 20 73 71 6c 5f 72 65 74 5b 30 5d 20 21   && sql_ret[0] !
9db0: 3d 20 27 5c 30 27 29 20 7b 0a 09 09 70 72 69 6e  = '\0') {...prin
9dc0: 74 66 28 22 25 73 5c 6e 22 2c 20 73 71 6c 5f 72  tf("%s\n", sql_r
9dd0: 65 74 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  et);..}...return
9de0: 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 63  (0);.}../*. * Tc
9df0: 6c 20 6d 6f 64 65 3a 20 45 78 65 63 75 74 65 20  l mode: Execute 
9e00: 72 61 77 20 54 63 6c 20 61 6e 64 20 72 65 74 75  raw Tcl and retu
9e10: 72 6e 20 73 75 63 63 65 73 73 20 6f 72 20 66 61  rn success or fa
9e20: 69 6c 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63  ilure. */.static
9e30: 20 69 6e 74 20 61 70 70 66 73 5f 74 63 6c 28 63   int appfs_tcl(c
9e40: 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c 29 20  onst char *tcl) 
9e50: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
9e60: 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68  nterp;..const ch
9e70: 61 72 20 2a 74 63 6c 5f 72 65 73 75 6c 74 3b 0a  ar *tcl_result;.
9e80: 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09  .int tcl_ret;...
9e90: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63  interp = appfs_c
9ea0: 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28  reate_TclInterp(
9eb0: 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65  NULL);..if (inte
9ec0: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
9ed0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
9ee0: 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74  "Unable to creat
9ef0: 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65  e a Tcl interpre
9f00: 74 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c  ter.  Aborting.\
9f10: 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31  n");....return(1
9f20: 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20  );..}...tcl_ret 
9f30: 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  = Tcl_Eval(inter
9f40: 70 2c 20 74 63 6c 29 3b 0a 09 74 63 6c 5f 72 65  p, tcl);..tcl_re
9f50: 73 75 6c 74 20 3d 20 54 63 6c 5f 47 65 74 53 74  sult = Tcl_GetSt
9f60: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
9f70: 70 29 3b 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65  p);...if (tcl_re
9f80: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
9f90: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
9fa0: 20 22 5b 65 72 72 6f 72 5d 20 25 73 5c 6e 22 2c   "[error] %s\n",
9fb0: 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65   Tcl_GetVar(inte
9fc0: 72 70 2c 20 22 65 72 72 6f 72 49 6e 66 6f 22 2c  rp, "errorInfo",
9fd0: 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59   TCL_GLOBAL_ONLY
9fe0: 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29  ));....return(1)
9ff0: 3b 0a 09 7d 0a 0a 09 69 66 20 28 74 63 6c 5f 72  ;..}...if (tcl_r
a000: 65 73 75 6c 74 20 26 26 20 74 63 6c 5f 72 65 73  esult && tcl_res
a010: 75 6c 74 5b 30 5d 20 21 3d 20 27 5c 30 27 29 20  ult[0] != '\0') 
a020: 7b 0a 09 09 70 72 69 6e 74 66 28 22 25 73 5c 6e  {...printf("%s\n
a030: 22 2c 20 74 63 6c 5f 72 65 73 75 6c 74 29 3b 0a  ", tcl_result);.
a040: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  .}...return(0);.
a050: 7d 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 64 20  }../*. * AppFSd 
a060: 50 61 63 6b 61 67 65 20 66 6f 72 20 54 63 6c 3a  Package for Tcl:
a070: 0a 20 2a 20 20 20 20 20 20 20 20 20 42 72 69 64  . *         Brid
a080: 67 65 20 66 6f 72 20 49 2f 4f 20 6f 70 65 72 61  ge for I/O opera
a090: 74 69 6f 6e 73 20 74 6f 20 72 65 71 75 65 73 74  tions to request
a0a0: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f   information abo
a0b0: 75 74 20 74 68 65 20 63 75 72 72 65 6e 74 0a 20  ut the current. 
a0c0: 2a 20 20 20 20 20 20 20 20 20 74 72 61 6e 73 61  *         transa
a0d0: 63 74 69 6f 6e 0a 20 2a 2f 0a 2f 2a 0a 20 2a 20  ction. */./*. * 
a0e0: 54 63 6c 20 69 6e 74 65 72 66 61 63 65 20 74 6f  Tcl interface to
a0f0: 20 67 65 74 20 74 68 65 20 68 6f 6d 65 20 64 69   get the home di
a100: 72 65 63 74 6f 72 79 20 66 6f 72 20 74 68 65 20  rectory for the 
a110: 75 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20  user making the 
a120: 22 63 75 72 72 65 6e 74 22 0a 20 2a 20 46 55 53  "current". * FUS
a130: 45 20 49 2f 4f 20 72 65 71 75 65 73 74 0a 20 2a  E I/O request. *
a140: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c  /.static int tcl
a150: 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64  _appfs_get_homed
a160: 69 72 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64  ir(ClientData cd
a170: 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  , Tcl_Interp *in
a180: 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20  terp, int objc, 
a190: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
a1a0: 62 6a 76 5b 5d 29 20 7b 0a 09 63 68 61 72 20 2a  bjv[]) {..char *
a1b0: 68 6f 6d 65 64 69 72 3b 0a 09 54 63 6c 5f 4f 62  homedir;..Tcl_Ob
a1c0: 6a 20 2a 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a  j *homedir_obj;.
a1d0: 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a 09 73  .uid_t fsuid;..s
a1e0: 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64 20 54  tatic __thread T
a1f0: 63 6c 5f 4f 62 6a 20 2a 6c 61 73 74 5f 68 6f 6d  cl_Obj *last_hom
a200: 65 64 69 72 5f 6f 62 6a 20 3d 20 4e 55 4c 4c 3b  edir_obj = NULL;
a210: 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61  ..static __threa
a220: 64 20 75 69 64 5f 74 20 6c 61 73 74 5f 66 73 75  d uid_t last_fsu
a230: 69 64 20 3d 20 2d 31 3b 0a 0a 20 20 20 20 20 20  id = -1;..      
a240: 20 20 69 66 20 28 6f 62 6a 63 20 21 3d 20 31 29    if (objc != 1)
a250: 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20   {.             
a260: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
a270: 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f  rgs(interp, 1, o
a280: 62 6a 76 2c 20 4e 55 4c 4c 29 3b 0a 20 20 20 20  bjv, NULL);.    
a290: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75              retu
a2a0: 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 20  rn(TCL_ERROR);. 
a2b0: 20 20 20 20 20 20 20 7d 0a 0a 09 66 73 75 69 64         }...fsuid
a2c0: 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75   = appfs_get_fsu
a2d0: 69 64 28 29 3b 0a 0a 09 69 66 20 28 66 73 75 69  id();...if (fsui
a2e0: 64 20 3d 3d 20 6c 61 73 74 5f 66 73 75 69 64 20  d == last_fsuid 
a2f0: 26 26 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f  && last_homedir_
a300: 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  obj != NULL) {..
a310: 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 6c  .homedir_obj = l
a320: 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b  ast_homedir_obj;
a330: 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43  ....Tcl_IncrRefC
a340: 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a  ount(homedir_obj
a350: 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 68  );..} else {...h
a360: 6f 6d 65 64 69 72 20 3d 20 61 70 70 66 73 5f 67  omedir = appfs_g
a370: 65 74 5f 68 6f 6d 65 64 69 72 28 61 70 70 66 73  et_homedir(appfs
a380: 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a  _get_fsuid());..
a390: 09 09 69 66 20 28 68 6f 6d 65 64 69 72 20 3d 3d  ..if (homedir ==
a3a0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74 75   NULL) {....retu
a3b0: 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09  rn(TCL_ERROR);..
a3c0: 09 7d 0a 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62  .}....homedir_ob
a3d0: 6a 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  j = Tcl_NewStrin
a3e0: 67 4f 62 6a 28 68 6f 6d 65 64 69 72 2c 20 2d 31  gObj(homedir, -1
a3f0: 29 3b 0a 0a 09 09 66 72 65 65 28 68 6f 6d 65 64  );....free(homed
a400: 69 72 29 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72  ir);....Tcl_Incr
a410: 52 65 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72  RefCount(homedir
a420: 5f 6f 62 6a 29 3b 0a 0a 09 09 69 66 20 28 6c 61  _obj);....if (la
a430: 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 21  st_homedir_obj !
a440: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 54 63 6c  = NULL) {....Tcl
a450: 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 6c 61  _DecrRefCount(la
a460: 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b  st_homedir_obj);
a470: 0a 09 09 7d 0a 0a 09 09 6c 61 73 74 5f 68 6f 6d  ...}....last_hom
a480: 65 64 69 72 5f 6f 62 6a 20 3d 20 68 6f 6d 65 64  edir_obj = homed
a490: 69 72 5f 6f 62 6a 3b 0a 09 09 6c 61 73 74 5f 66  ir_obj;...last_f
a4a0: 73 75 69 64 20 3d 20 66 73 75 69 64 3b 0a 0a 09  suid = fsuid;...
a4b0: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
a4c0: 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a  t(homedir_obj);.
a4d0: 09 7d 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f  .}..       .Tcl_
a4e0: 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  SetObjResult(int
a4f0: 65 72 70 2c 20 68 6f 6d 65 64 69 72 5f 6f 62 6a  erp, homedir_obj
a500: 29 3b 0a 0a 09 54 63 6c 5f 44 65 63 72 52 65 66  );...Tcl_DecrRef
a510: 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62  Count(homedir_ob
a520: 6a 29 3b 0a 0a 20 20 20 20 20 20 20 20 72 65 74  j);..        ret
a530: 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a  urn(TCL_OK);.}..
a540: 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61  static int tcl_a
a550: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
a560: 65 72 5f 66 73 5f 65 6e 74 65 72 28 43 6c 69 65  er_fs_enter(Clie
a570: 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49  ntData cd, Tcl_I
a580: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69  nterp *interp, i
a590: 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a  nt objc, Tcl_Obj
a5a0: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20   *CONST objv[]) 
a5b0: 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  {..appfs_simulat
a5c0: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
a5d0: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f  );...return(TCL_
a5e0: 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  OK);.}..static i
a5f0: 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f 73 69 6d  nt tcl_appfs_sim
a600: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65  ulate_user_fs_le
a610: 61 76 65 28 43 6c 69 65 6e 74 44 61 74 61 20 63  ave(ClientData c
a620: 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  d, Tcl_Interp *i
a630: 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c  nterp, int objc,
a640: 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20   Tcl_Obj *CONST 
a650: 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70 70 66 73  objv[]) {..appfs
a660: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
a670: 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 72 65 74  s_leave();...ret
a680: 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a  urn(TCL_OK);.}..
a690: 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61  static int tcl_a
a6a0: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 43  ppfs_get_fsuid(C
a6b0: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63  lientData cd, Tc
a6c0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
a6d0: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f  , int objc, Tcl_
a6e0: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
a6f0: 5d 29 20 7b 0a 09 75 69 64 5f 74 20 66 73 75 69  ]) {..uid_t fsui
a700: 64 3b 0a 0a 09 66 73 75 69 64 20 3d 20 61 70 70  d;...fsuid = app
a710: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b 0a  fs_get_fsuid();.
a720: 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74  .       .Tcl_Set
a730: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
a740: 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74  , Tcl_NewWideInt
a750: 4f 62 6a 28 66 73 75 69 64 29 29 3b 0a 0a 09 72  Obj(fsuid));...r
a760: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d  eturn(TCL_OK);.}
a770: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c  ..static int tcl
a780: 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64  _appfs_get_fsgid
a790: 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20  (ClientData cd, 
a7a0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
a7b0: 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63  rp, int objc, Tc
a7c0: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
a7d0: 76 5b 5d 29 20 7b 0a 09 67 69 64 5f 74 20 66 73  v[]) {..gid_t fs
a7e0: 67 69 64 3b 0a 0a 09 66 73 67 69 64 20 3d 20 61  gid;...fsgid = a
a7f0: 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28 29  ppfs_get_fsgid()
a800: 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53  ;..       .Tcl_S
a810: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65  etObjResult(inte
a820: 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65 49  rp, Tcl_NewWideI
a830: 6e 74 4f 62 6a 28 66 73 67 69 64 29 29 3b 0a 0a  ntObj(fsgid));..
a840: 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b  .return(TCL_OK);
a850: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
a860: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 70 61 74  cl_appfs_get_pat
a870: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75  h_info_cache_flu
a880: 73 68 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64  sh(ClientData cd
a890: 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  , Tcl_Interp *in
a8a0: 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20  terp, int objc, 
a8b0: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
a8c0: 62 6a 76 5b 5d 29 20 7b 0a 09 69 6e 74 20 74 63  bjv[]) {..int tc
a8d0: 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 6e 65 77 5f  l_ret;..int new_
a8e0: 73 69 7a 65 3b 0a 0a 09 6e 65 77 5f 73 69 7a 65  size;...new_size
a8f0: 20 3d 20 2d 31 3b 0a 0a 09 69 66 20 28 6f 62 6a   = -1;...if (obj
a900: 63 20 3d 3d 20 32 29 20 7b 0a 09 09 74 63 6c 5f  c == 2) {...tcl_
a910: 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 49 6e 74  ret = Tcl_GetInt
a920: 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20  FromObj(interp, 
a930: 6f 62 6a 76 5b 31 5d 2c 20 26 6e 65 77 5f 73 69  objv[1], &new_si
a940: 7a 65 29 3b 0a 09 09 69 66 20 28 74 63 6c 5f 72  ze);...if (tcl_r
a950: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
a960: 09 09 09 72 65 74 75 72 6e 28 74 63 6c 5f 72 65  ...return(tcl_re
a970: 74 29 3b 0a 09 09 7d 0a 09 7d 20 65 6c 73 65 20  t);...}..} else 
a980: 69 66 20 28 6f 62 6a 63 20 3e 20 32 20 7c 7c 20  if (objc > 2 || 
a990: 6f 62 6a 63 20 3c 20 31 29 20 7b 0a 20 20 20 20  objc < 1) {.    
a9a0: 20 20 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f              Tcl_
a9b0: 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74  WrongNumArgs(int
a9c0: 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 3f  erp, 1, objv, "?
a9d0: 6e 65 77 5f 63 61 63 68 65 5f 73 69 7a 65 3f 22  new_cache_size?"
a9e0: 29 3b 0a 09 09 72 65 74 75 72 6e 28 54 43 4c 5f  );...return(TCL_
a9f0: 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09 61 70 70  ERROR);..}...app
aa00: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
aa10: 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c  _cache_flush(-1,
aa20: 20 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a 09 72 65   new_size);...re
aa30: 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a  turn(TCL_OK);.}.
aa40: 0a 73 74 61 74 69 63 20 69 6e 74 20 41 70 70 66  .static int Appf
aa50: 73 64 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65  sd_Init(Tcl_Inte
aa60: 72 70 20 2a 69 6e 74 65 72 70 29 20 7b 0a 23 69  rp *interp) {.#i
aa70: 66 64 65 66 20 55 53 45 5f 54 43 4c 5f 53 54 55  fdef USE_TCL_STU
aa80: 42 53 0a 09 69 66 20 28 54 63 6c 5f 49 6e 69 74  BS..if (Tcl_Init
aa90: 53 74 75 62 73 28 69 6e 74 65 72 70 2c 20 54 43  Stubs(interp, TC
aaa0: 4c 5f 56 45 52 53 49 4f 4e 2c 20 30 29 20 3d 3d  L_VERSION, 0) ==
aab0: 20 30 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28   0L) {...return(
aac0: 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 23  TCL_ERROR);..}.#
aad0: 65 6e 64 69 66 0a 0a 09 54 63 6c 5f 43 72 65 61  endif...Tcl_Crea
aae0: 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74  teObjCommand(int
aaf0: 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65  erp, "appfsd::ge
ab00: 74 5f 68 6f 6d 65 64 69 72 22 2c 20 74 63 6c 5f  t_homedir", tcl_
ab10: 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69  appfs_get_homedi
ab20: 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  r, NULL, NULL);.
ab30: 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f  .Tcl_CreateObjCo
ab40: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61  mmand(interp, "a
ab50: 70 70 66 73 64 3a 3a 67 65 74 5f 66 73 75 69 64  ppfsd::get_fsuid
ab60: 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74  ", tcl_appfs_get
ab70: 5f 66 73 75 69 64 2c 20 4e 55 4c 4c 2c 20 4e 55  _fsuid, NULL, NU
ab80: 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65  LL);..Tcl_Create
ab90: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
aba0: 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f  p, "appfsd::get_
abb0: 66 73 67 69 64 22 2c 20 74 63 6c 5f 61 70 70 66  fsgid", tcl_appf
abc0: 73 5f 67 65 74 5f 66 73 67 69 64 2c 20 4e 55 4c  s_get_fsgid, NUL
abd0: 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43  L, NULL);..Tcl_C
abe0: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
abf0: 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a  interp, "appfsd:
ac00: 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  :simulate_user_f
ac10: 73 5f 65 6e 74 65 72 22 2c 20 74 63 6c 5f 61 70  s_enter", tcl_ap
ac20: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
ac30: 72 5f 66 73 5f 65 6e 74 65 72 2c 20 4e 55 4c 4c  r_fs_enter, NULL
ac40: 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72  , NULL);..Tcl_Cr
ac50: 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69  eateObjCommand(i
ac60: 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a  nterp, "appfsd::
ac70: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
ac80: 5f 6c 65 61 76 65 22 2c 20 74 63 6c 5f 61 70 70  _leave", tcl_app
ac90: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
aca0: 5f 66 73 5f 6c 65 61 76 65 2c 20 4e 55 4c 4c 2c  _fs_leave, NULL,
acb0: 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65   NULL);..Tcl_Cre
acc0: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
acd0: 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67  terp, "appfsd::g
ace0: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
acf0: 68 65 5f 66 6c 75 73 68 22 2c 20 74 63 6c 5f 61  he_flush", tcl_a
ad00: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
ad10: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 2c 20  fo_cache_flush, 
ad20: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 54  NULL, NULL);...T
ad30: 63 6c 5f 50 6b 67 50 72 6f 76 69 64 65 28 69 6e  cl_PkgProvide(in
ad40: 74 65 72 70 2c 20 22 61 70 70 66 73 64 22 2c 20  terp, "appfsd", 
ad50: 22 31 2e 30 22 29 3b 0a 0a 09 72 65 74 75 72 6e  "1.0");...return
ad60: 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 2f 2a 0a  (TCL_OK);.}../*.
ad70: 20 2a 20 48 6f 74 2d 72 65 73 74 61 72 74 20 73   * Hot-restart s
ad80: 75 70 70 6f 72 74 0a 20 2a 2f 0a 2f 2a 20 49 6e  upport. */./* In
ad90: 69 74 69 61 74 65 20 61 20 68 6f 74 2d 72 65 73  itiate a hot-res
ada0: 74 61 72 74 20 2a 2f 0a 73 74 61 74 69 63 20 76  tart */.static v
adb0: 6f 69 64 20 61 70 70 66 73 5f 68 6f 74 5f 72 65  oid appfs_hot_re
adc0: 73 74 61 72 74 28 76 6f 69 64 29 20 7b 0a 09 41  start(void) {..A
add0: 50 50 46 53 5f 44 45 42 55 47 28 22 41 73 6b 65  PPFS_DEBUG("Aske
ade0: 64 20 74 6f 20 69 6e 69 74 69 61 74 65 20 68 6f  d to initiate ho
adf0: 74 20 72 65 73 74 61 72 74 22 29 3b 0a 0a 09 61  t restart");...a
ae00: 70 70 66 73 5f 74 63 6c 5f 52 65 73 65 74 49 6e  ppfs_tcl_ResetIn
ae10: 74 65 72 70 73 28 29 3b 0a 0a 09 61 70 70 66 73  terps();...appfs
ae20: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
ae30: 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c 20 2d  ache_flush(-1, -
ae40: 31 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a  1);...return;.}.
ae50: 0a 2f 2a 0a 20 2a 20 53 69 67 6e 61 6c 20 68 61  ./*. * Signal ha
ae60: 6e 64 6c 65 72 0a 20 2a 20 20 20 20 20 20 20 20  ndler. *        
ae70: 20 53 49 47 48 55 50 20 69 6e 69 74 69 61 74 65   SIGHUP initiate
ae80: 73 20 61 20 68 6f 74 20 72 65 73 74 61 72 74 0a  s a hot restart.
ae90: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
aea0: 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f 68 61 6e  appfs_signal_han
aeb0: 64 6c 65 72 28 69 6e 74 20 73 69 67 29 20 7b 0a  dler(int sig) {.
aec0: 09 2f 2a 20 44 6f 20 6e 6f 74 20 68 61 6e 64 6c  ./* Do not handl
aed0: 65 20 73 69 67 6e 61 6c 73 20 75 6e 74 69 6c 20  e signals until 
aee0: 46 55 53 45 20 68 61 73 20 62 65 65 6e 20 73 74  FUSE has been st
aef0: 61 72 74 65 64 20 2a 2f 0a 09 69 66 20 28 21 61  arted */..if (!a
af00: 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65  ppfs_fuse_starte
af10: 64 29 20 7b 0a 09 09 72 65 74 75 72 6e 3b 0a 09  d) {...return;..
af20: 7d 0a 0a 09 2f 2a 20 52 65 71 75 65 73 74 20 74  }.../* Request t
af30: 6f 20 70 65 72 66 6f 72 6d 20 61 20 22 68 6f 74  o perform a "hot
af40: 22 20 72 65 73 74 61 72 74 20 2a 2f 0a 09 69 66  " restart */..if
af50: 20 28 73 69 67 20 3d 3d 20 53 49 47 48 55 50 29   (sig == SIGHUP)
af60: 20 7b 0a 09 09 61 70 70 66 73 5f 68 6f 74 5f 72   {...appfs_hot_r
af70: 65 73 74 61 72 74 28 29 3b 0a 09 7d 0a 0a 09 72  estart();..}...r
af80: 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  eturn;.}../*. * 
af90: 54 65 72 6d 69 6e 61 74 65 20 61 20 74 68 72 65  Terminate a thre
afa0: 61 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ad. */.static vo
afb0: 69 64 20 61 70 70 66 73 5f 74 65 72 6d 69 6e 61  id appfs_termina
afc0: 74 65 5f 69 6e 74 65 72 70 5f 61 6e 64 5f 74 68  te_interp_and_th
afd0: 72 65 61 64 28 76 6f 69 64 20 2a 5f 69 6e 74 65  read(void *_inte
afe0: 72 70 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  rp) {..Tcl_Inter
aff0: 70 20 2a 69 6e 74 65 72 70 3b 0a 0a 09 41 50 50  p *interp;...APP
b000: 46 53 5f 44 45 42 55 47 28 22 43 61 6c 6c 65 64  FS_DEBUG("Called
b010: 3a 20 5f 69 6e 74 65 72 70 20 3d 20 25 70 22 2c  : _interp = %p",
b020: 20 5f 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20   _interp);...if 
b030: 28 5f 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c  (_interp == NULL
b040: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
b050: 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 74  G("Terminating t
b060: 68 72 65 61 64 20 77 69 74 68 20 6e 6f 20 69 6e  hread with no in
b070: 74 65 72 70 72 65 74 65 72 22 29 3b 0a 0a 09 09  terpreter");....
b080: 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 6e 74  return;..}...int
b090: 65 72 70 20 3d 20 5f 69 6e 74 65 72 70 3b 0a 0a  erp = _interp;..
b0a0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 65  .APPFS_DEBUG("Te
b0b0: 72 6d 69 6e 61 74 69 6e 67 20 69 6e 74 65 72 70  rminating interp
b0c0: 72 65 74 65 72 20 64 75 65 20 74 6f 20 74 68 72  reter due to thr
b0d0: 65 61 64 20 74 65 72 6d 69 6e 61 74 69 6f 6e 22  ead termination"
b0e0: 29 3b 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  );...appfs_call_
b0f0: 6c 69 62 74 63 6c 28 0a 09 09 54 63 6c 5f 44 65  libtcl(...Tcl_De
b100: 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72  leteInterp(inter
b110: 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63  p);..)...appfs_c
b120: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 54 63  all_libtcl(...Tc
b130: 6c 5f 46 69 6e 61 6c 69 7a 65 54 68 72 65 61 64  l_FinalizeThread
b140: 28 29 3b 0a 09 29 0a 0a 09 72 65 74 75 72 6e 3b  ();..)...return;
b150: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 6f 6d 6d 61 6e  .}../*. * Comman
b160: 64 2d 6c 69 6e 65 20 70 61 72 73 69 6e 67 20 74  d-line parsing t
b170: 6f 6f 6c 73 0a 20 2a 2f 0a 73 74 61 74 69 63 20  ools. */.static 
b180: 76 6f 69 64 20 61 70 70 66 73 5f 70 72 69 6e 74  void appfs_print
b190: 5f 68 65 6c 70 28 46 49 4c 45 20 2a 63 68 61 6e  _help(FILE *chan
b1a0: 6e 65 6c 29 20 7b 0a 09 66 70 72 69 6e 74 66 28  nel) {..fprintf(
b1b0: 63 68 61 6e 6e 65 6c 2c 20 22 55 73 61 67 65 3a  channel, "Usage:
b1c0: 20 7b 61 70 70 66 73 64 7c 6d 6f 75 6e 74 2e 61   {appfsd|mount.a
b1d0: 70 70 66 73 7d 20 5b 2d 6f 20 3c 6f 70 74 69 6f  ppfs} [-o <optio
b1e0: 6e 3e 5d 20 5b 2d 64 66 73 68 5d 20 3c 63 61 63  n>] [-dfsh] <cac
b1f0: 68 65 64 69 72 3e 20 3c 6d 6f 75 6e 74 70 6f 69  hedir> <mountpoi
b200: 6e 74 3e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74  nt>\n");..fprint
b210: 66 28 63 68 61 6e 6e 65 6c 2c 20 22 5c 6e 22 29  f(channel, "\n")
b220: 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e  ;..fprintf(chann
b230: 65 6c 2c 20 22 4f 70 74 69 6f 6e 73 3a 5c 6e 22  el, "Options:\n"
b240: 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e  );..fprintf(chan
b250: 6e 65 6c 2c 20 22 20 20 2d 64 20 20 20 20 20 20  nel, "  -d      
b260: 20 20 20 20 20 20 20 20 45 6e 61 62 6c 65 20 46          Enable F
b270: 55 53 45 20 64 65 62 75 67 20 6d 6f 64 65 2e 5c  USE debug mode.\
b280: 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68  n");..fprintf(ch
b290: 61 6e 6e 65 6c 2c 20 22 20 20 2d 66 20 20 20 20  annel, "  -f    
b2a0: 20 20 20 20 20 20 20 20 20 20 52 75 6e 20 69 6e            Run in
b2b0: 20 66 6f 72 65 67 72 6f 75 6e 64 2e 5c 6e 22 29   foreground.\n")
b2c0: 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e  ;..fprintf(chann
b2d0: 65 6c 2c 20 22 20 20 2d 73 20 20 20 20 20 20 20  el, "  -s       
b2e0: 20 20 20 20 20 20 20 45 6e 61 62 6c 65 20 73 69         Enable si
b2f0: 6e 67 6c 65 20 74 68 72 65 61 64 65 64 20 6d 6f  ngle threaded mo
b300: 64 65 2e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74  de.\n");..fprint
b310: 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 68  f(channel, "  -h
b320: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 47 69                Gi
b330: 76 65 20 74 68 69 73 20 68 65 6c 70 2e 5c 6e 22  ve this help.\n"
b340: 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e  );..fprintf(chan
b350: 6e 65 6c 2c 20 22 20 20 2d 6f 20 6e 6f 74 68 72  nel, "  -o nothr
b360: 65 61 64 73 20 20 20 20 45 6e 61 62 6c 65 20 73  eads    Enable s
b370: 69 6e 67 6c 65 20 74 68 72 65 61 64 65 64 20 6d  ingle threaded m
b380: 6f 64 65 2e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e  ode.\n");..fprin
b390: 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20 20 2d  tf(channel, "  -
b3a0: 6f 20 61 6c 6c 6f 77 5f 6f 74 68 65 72 20 20 41  o allow_other  A
b3b0: 6c 6c 6f 77 20 6f 74 68 65 72 20 75 73 65 72 73  llow other users
b3c0: 20 74 6f 20 61 63 63 65 73 73 20 74 68 69 73 20   to access this 
b3d0: 6d 6f 75 6e 74 70 6f 69 6e 74 20 28 64 65 66 61  mountpoint (defa
b3e0: 75 6c 74 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74  ult\n");..fprint
b3f0: 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20 20 20 20  f(channel, "    
b400: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 69 66                if
b410: 20 72 6f 6f 74 29 2e 5c 6e 22 29 3b 0a 0a 09 72   root).\n");...r
b420: 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63  eturn;.}..static
b430: 20 69 6e 74 20 61 70 70 66 73 5f 6f 70 74 5f 70   int appfs_opt_p
b440: 61 72 73 65 28 69 6e 74 20 61 72 67 63 2c 20 63  arse(int argc, c
b450: 68 61 72 20 2a 2a 61 72 67 76 2c 20 20 73 74 72  har **argv,  str
b460: 75 63 74 20 66 75 73 65 5f 61 72 67 73 20 2a 61  uct fuse_args *a
b470: 72 67 73 29 20 7b 0a 09 69 6e 74 20 63 68 3b 0a  rgs) {..int ch;.
b480: 09 63 68 61 72 20 2a 6f 70 74 73 74 72 2c 20 2a  .char *optstr, *
b490: 6f 70 74 73 74 72 5f 6e 65 78 74 2c 20 2a 6f 70  optstr_next, *op
b4a0: 74 73 74 72 5f 73 3b 0a 09 63 68 61 72 20 66 61  tstr_s;..char fa
b4b0: 6b 65 5f 61 72 67 5b 33 5d 20 3d 20 7b 27 2d 27  ke_arg[3] = {'-'
b4c0: 2c 20 30 2c 20 30 7d 3b 0a 0a 09 2f 2a 0a 09 20  , 0, 0};.../*.. 
b4d0: 2a 20 44 65 66 61 75 6c 74 20 76 61 6c 75 65 73  * Default values
b4e0: 0a 09 20 2a 2f 0a 23 69 66 64 65 66 20 54 43 4c  .. */.#ifdef TCL
b4f0: 5f 54 48 52 45 41 44 53 0a 09 61 70 70 66 73 5f  _THREADS..appfs_
b500: 74 68 72 65 61 64 65 64 5f 74 63 6c 20 3d 20 31  threaded_tcl = 1
b510: 3b 0a 23 65 6c 73 65 0a 09 61 70 70 66 73 5f 74  ;.#else..appfs_t
b520: 68 72 65 61 64 65 64 5f 74 63 6c 20 3d 20 30 3b  hreaded_tcl = 0;
b530: 0a 23 65 6e 64 69 66 0a 0a 09 2f 2a 2a 0a 09 20  .#endif.../**.. 
b540: 2a 2a 20 41 64 64 20 46 55 53 45 20 61 72 67 75  ** Add FUSE argu
b550: 6d 65 6e 74 73 20 77 68 69 63 68 20 77 65 20 61  ments which we a
b560: 6c 77 61 79 73 20 73 75 70 70 6c 79 0a 09 20 2a  lways supply.. *
b570: 2a 2f 0a 09 66 75 73 65 5f 6f 70 74 5f 61 64 64  */..fuse_opt_add
b580: 5f 61 72 67 28 61 72 67 73 2c 20 22 2d 6f 64 65  _arg(args, "-ode
b590: 66 61 75 6c 74 5f 70 65 72 6d 69 73 73 69 6f 6e  fault_permission
b5a0: 73 2c 66 73 6e 61 6d 65 3d 61 70 70 66 73 2c 73  s,fsname=appfs,s
b5b0: 75 62 74 79 70 65 3d 61 70 70 66 73 64 2c 75 73  ubtype=appfsd,us
b5c0: 65 5f 69 6e 6f 2c 6b 65 72 6e 65 6c 5f 63 61 63  e_ino,kernel_cac
b5d0: 68 65 2c 65 6e 74 72 79 5f 74 69 6d 65 6f 75 74  he,entry_timeout
b5e0: 3d 30 2c 61 74 74 72 5f 74 69 6d 65 6f 75 74 3d  =0,attr_timeout=
b5f0: 30 2c 62 69 67 5f 77 72 69 74 65 73 2c 69 6e 74  0,big_writes,int
b600: 72 2c 68 61 72 64 5f 72 65 6d 6f 76 65 22 29 3b  r,hard_remove");
b610: 0a 0a 09 69 66 20 28 67 65 74 75 69 64 28 29 20  ...if (getuid() 
b620: 3d 3d 20 30 29 20 7b 0a 09 09 66 75 73 65 5f 6f  == 0) {...fuse_o
b630: 70 74 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e  pt_parse(args, N
b640: 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29  ULL, NULL, NULL)
b650: 3b 0a 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64  ;...fuse_opt_add
b660: 5f 61 72 67 28 61 72 67 73 2c 20 22 2d 6f 61 6c  _arg(args, "-oal
b670: 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 0a 09 09  low_other");....
b680: 2f 2a 0a 09 09 20 2a 20 54 68 69 73 20 73 68 6f  /*... * This sho
b690: 75 6c 64 20 67 65 6e 65 72 61 6c 6c 79 20 62 65  uld generally be
b6a0: 20 61 76 6f 69 64 65 64 2c 20 62 75 74 20 69 66   avoided, but if
b6b0: 20 74 68 65 72 65 20 61 72 65 20 73 65 63 75 72   there are secur
b6c0: 69 74 79 0a 09 09 20 2a 20 63 6f 6e 63 65 72 6e  ity... * concern
b6d0: 73 20 73 75 69 64 20 63 61 6e 20 62 65 20 64 69  s suid can be di
b6e0: 73 61 62 6c 65 64 20 63 6f 6d 70 6c 65 74 65 6c  sabled completel
b6f0: 79 20 6f 6e 20 74 68 65 20 63 6f 6d 6d 61 6e 64  y on the command
b700: 6c 69 6e 65 0a 09 09 20 2a 2f 0a 09 09 66 75 73  line... */...fus
b710: 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67 73  e_opt_parse(args
b720: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55  , NULL, NULL, NU
b730: 4c 4c 29 3b 0a 09 09 66 75 73 65 5f 6f 70 74 5f  LL);...fuse_opt_
b740: 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20 22 2d  add_arg(args, "-
b750: 6f 73 75 69 64 22 29 3b 0a 09 7d 0a 0a 09 77 68  osuid");..}...wh
b760: 69 6c 65 20 28 28 63 68 20 3d 20 67 65 74 6f 70  ile ((ch = getop
b770: 74 28 61 72 67 63 2c 20 61 72 67 76 2c 20 22 64  t(argc, argv, "d
b780: 66 73 68 76 6f 3a 22 29 29 20 21 3d 20 2d 31 29  fshvo:")) != -1)
b790: 20 7b 0a 09 09 73 77 69 74 63 68 20 28 63 68 29   {...switch (ch)
b7a0: 20 7b 0a 09 09 09 63 61 73 65 20 27 76 27 3a 0a   {....case 'v':.
b7b0: 09 09 09 09 2f 2a 20 49 67 6e 6f 72 65 64 20 2a  ..../* Ignored *
b7c0: 2f 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09  /.....break;....
b7d0: 63 61 73 65 20 27 6f 27 3a 0a 09 09 09 09 6f 70  case 'o':.....op
b7e0: 74 73 74 72 5f 6e 65 78 74 20 3d 20 6f 70 74 73  tstr_next = opts
b7f0: 74 72 20 3d 20 6f 70 74 73 74 72 5f 73 20 3d 20  tr = optstr_s = 
b800: 73 74 72 64 75 70 28 6f 70 74 61 72 67 29 3b 0a  strdup(optarg);.
b810: 0a 09 09 09 09 77 68 69 6c 65 20 28 31 29 20 7b  .....while (1) {
b820: 0a 09 09 09 09 09 6f 70 74 73 74 72 20 3d 20 6f  ......optstr = o
b830: 70 74 73 74 72 5f 6e 65 78 74 3b 0a 0a 09 09 09  ptstr_next;.....
b840: 09 09 69 66 20 28 21 6f 70 74 73 74 72 29 20 7b  ..if (!optstr) {
b850: 0a 09 09 09 09 09 09 62 72 65 61 6b 3b 0a 09 09  .......break;...
b860: 09 09 09 7d 0a 0a 09 09 09 09 09 6f 70 74 73 74  ...}.......optst
b870: 72 5f 6e 65 78 74 20 3d 20 73 74 72 63 68 72 28  r_next = strchr(
b880: 6f 70 74 73 74 72 2c 20 27 2c 27 29 3b 0a 09 09  optstr, ',');...
b890: 09 09 09 69 66 20 28 6f 70 74 73 74 72 5f 6e 65  ...if (optstr_ne
b8a0: 78 74 29 20 7b 0a 09 09 09 09 09 09 2a 6f 70 74  xt) {.......*opt
b8b0: 73 74 72 5f 6e 65 78 74 20 3d 20 27 5c 30 27 3b  str_next = '\0';
b8c0: 0a 09 09 09 09 09 09 6f 70 74 73 74 72 5f 6e 65  .......optstr_ne
b8d0: 78 74 2b 2b 3b 0a 09 09 09 09 09 7d 0a 0a 09 09  xt++;......}....
b8e0: 09 09 09 69 66 20 28 73 74 72 63 6d 70 28 6f 70  ...if (strcmp(op
b8f0: 74 73 74 72 2c 20 22 6e 6f 74 68 72 65 61 64 73  tstr, "nothreads
b900: 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09  ") == 0) {......
b910: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 50 61  .APPFS_DEBUG("Pa
b920: 73 73 69 6e 67 20 6f 70 74 69 6f 6e 20 74 6f 20  ssing option to 
b930: 46 55 53 45 3a 20 2d 73 22 29 3b 0a 0a 09 09 09  FUSE: -s");.....
b940: 09 09 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73  ...fuse_opt_pars
b950: 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55  e(args, NULL, NU
b960: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09 09 09 09  LL, NULL);......
b970: 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72  .fuse_opt_add_ar
b980: 67 28 61 72 67 73 2c 20 22 2d 73 22 29 3b 0a 0a  g(args, "-s");..
b990: 09 09 09 09 09 09 61 70 70 66 73 5f 74 68 72 65  ......appfs_thre
b9a0: 61 64 65 64 5f 74 63 6c 20 3d 20 30 3b 0a 09 09  aded_tcl = 0;...
b9b0: 09 09 09 7d 20 65 6c 73 65 20 69 66 20 28 73 74  ...} else if (st
b9c0: 72 63 6d 70 28 6f 70 74 73 74 72 2c 20 22 61 6c  rcmp(optstr, "al
b9d0: 6c 6f 77 5f 6f 74 68 65 72 22 29 20 3d 3d 20 30  low_other") == 0
b9e0: 29 20 7b 0a 09 09 09 09 09 09 41 50 50 46 53 5f  ) {.......APPFS_
b9f0: 44 45 42 55 47 28 22 50 61 73 73 69 6e 67 20 6f  DEBUG("Passing o
ba00: 70 74 69 6f 6e 20 74 6f 20 46 55 53 45 3a 20 2d  ption to FUSE: -
ba10: 6f 20 61 6c 6c 6f 77 5f 4f 74 68 65 72 22 29 3b  o allow_Other");
ba20: 0a 0a 09 09 09 09 09 09 66 75 73 65 5f 6f 70 74  ........fuse_opt
ba30: 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c  _parse(args, NUL
ba40: 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  L, NULL, NULL);.
ba50: 09 09 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 61  ......fuse_opt_a
ba60: 64 64 5f 61 72 67 28 61 72 67 73 2c 20 22 2d 6f  dd_arg(args, "-o
ba70: 61 6c 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 09  allow_other");..
ba80: 09 09 09 09 7d 20 65 6c 73 65 20 69 66 20 28 73  ....} else if (s
ba90: 74 72 63 6d 70 28 6f 70 74 73 74 72 2c 20 22 72  trcmp(optstr, "r
baa0: 77 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09  w") == 0) {.....
bab0: 09 09 2f 2a 20 49 67 6e 6f 72 65 64 20 2a 2f 0a  ../* Ignored */.
bac0: 09 09 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09  .....} else {...
bad0: 09 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ....fprintf(stde
bae0: 72 72 2c 20 22 61 70 70 66 73 64 3a 20 69 6e 76  rr, "appfsd: inv
baf0: 61 6c 69 64 20 6f 70 74 69 6f 6e 3a 20 5c 22 2d  alid option: \"-
bb00: 6f 20 25 73 5c 22 5c 6e 22 2c 20 6f 70 74 73 74  o %s\"\n", optst
bb10: 72 29 3b 0a 0a 09 09 09 09 09 09 66 72 65 65 28  r);........free(
bb20: 6f 70 74 73 74 72 5f 73 29 3b 0a 0a 09 09 09 09  optstr_s);......
bb30: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 09 09  ..return(1);....
bb40: 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66  ..}.....}......f
bb50: 72 65 65 28 6f 70 74 73 74 72 5f 73 29 3b 0a 0a  ree(optstr_s);..
bb60: 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61  ....break;....ca
bb70: 73 65 20 27 64 27 3a 0a 09 09 09 63 61 73 65 20  se 'd':....case 
bb80: 27 66 27 3a 0a 09 09 09 63 61 73 65 20 27 73 27  'f':....case 's'
bb90: 3a 0a 09 09 09 09 69 66 20 28 63 68 20 3d 3d 20  :.....if (ch == 
bba0: 27 73 27 29 20 7b 0a 09 09 09 09 09 61 70 70 66  's') {......appf
bbb0: 73 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 20 3d  s_threaded_tcl =
bbc0: 20 30 3b 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66   0;.....}......f
bbd0: 61 6b 65 5f 61 72 67 5b 31 5d 20 3d 20 63 68 3b  ake_arg[1] = ch;
bbe0: 0a 0a 09 09 09 09 41 50 50 46 53 5f 44 45 42 55  ......APPFS_DEBU
bbf0: 47 28 22 50 61 73 73 69 6e 67 20 6f 70 74 69 6f  G("Passing optio
bc00: 6e 20 74 6f 20 46 55 53 45 3a 20 25 73 22 2c 20  n to FUSE: %s", 
bc10: 66 61 6b 65 5f 61 72 67 29 3b 0a 0a 09 09 09 09  fake_arg);......
bc20: 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61  fuse_opt_parse(a
bc30: 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c  rgs, NULL, NULL,
bc40: 20 4e 55 4c 4c 29 3b 0a 09 09 09 09 66 75 73 65   NULL);.....fuse
bc50: 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72 67  _opt_add_arg(arg
bc60: 73 2c 20 66 61 6b 65 5f 61 72 67 29 3b 0a 09 09  s, fake_arg);...
bc70: 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65  ..break;....case
bc80: 20 27 68 27 3a 0a 09 09 09 09 61 70 70 66 73 5f   'h':.....appfs_
bc90: 70 72 69 6e 74 5f 68 65 6c 70 28 73 74 64 6f 75  print_help(stdou
bca0: 74 29 3b 0a 0a 09 09 09 09 72 65 74 75 72 6e 28  t);......return(
bcb0: 2d 31 29 3b 0a 09 09 09 63 61 73 65 20 27 3a 27  -1);....case ':'
bcc0: 3a 0a 09 09 09 63 61 73 65 20 27 3f 27 3a 0a 09  :....case '?':..
bcd0: 09 09 64 65 66 61 75 6c 74 3a 0a 09 09 09 09 61  ..default:.....a
bce0: 70 70 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28  ppfs_print_help(
bcf0: 73 74 64 65 72 72 29 3b 0a 0a 09 09 09 09 72 65  stderr);......re
bd00: 74 75 72 6e 28 31 29 3b 0a 09 09 7d 0a 09 7d 0a  turn(1);...}..}.
bd10: 0a 09 69 66 20 28 28 6f 70 74 69 6e 64 20 2b 20  ..if ((optind + 
bd20: 32 29 20 21 3d 20 61 72 67 63 29 20 7b 0a 09 09  2) != argc) {...
bd30: 69 66 20 28 28 6f 70 74 69 6e 64 20 2b 20 32 29  if ((optind + 2)
bd40: 20 3c 20 61 72 67 63 29 20 7b 0a 09 09 09 66 70   < argc) {....fp
bd50: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54  rintf(stderr, "T
bd60: 6f 6f 20 6d 61 6e 79 20 61 72 67 75 6d 65 6e 74  oo many argument
bd70: 73 5c 6e 22 29 3b 0a 09 09 7d 20 65 6c 73 65 20  s\n");...} else 
bd80: 7b 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64  {....fprintf(std
bd90: 65 72 72 2c 20 22 4d 69 73 73 69 6e 67 20 63 61  err, "Missing ca
bda0: 63 68 65 64 69 72 20 6f 72 20 6d 6f 75 6e 74 70  chedir or mountp
bdb0: 6f 69 6e 74 5c 6e 22 29 3b 0a 09 09 7d 0a 0a 09  oint\n");...}...
bdc0: 09 61 70 70 66 73 5f 70 72 69 6e 74 5f 68 65 6c  .appfs_print_hel
bdd0: 70 28 73 74 64 65 72 72 29 3b 0a 0a 09 09 72 65  p(stderr);....re
bde0: 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a  turn(1);..}.../*
bdf0: 0a 09 20 2a 20 53 65 74 20 63 61 63 68 65 20 64  .. * Set cache d
be00: 69 72 20 61 73 20 66 69 72 73 74 20 61 72 67 75  ir as first argu
be10: 6d 65 6e 74 20 28 74 68 65 20 22 64 65 76 69 63  ment (the "devic
be20: 65 22 2c 20 65 73 73 65 6e 74 69 61 6c 6c 79 29  e", essentially)
be30: 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63  .. */..appfs_cac
be40: 68 65 64 69 72 20 3d 20 61 72 67 76 5b 6f 70 74  hedir = argv[opt
be50: 69 6e 64 5d 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 50  ind];.../*.. * P
be60: 61 73 73 20 74 68 65 20 72 65 6d 61 69 6e 69 6e  ass the remainin
be70: 67 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 46 55  g argument to FU
be80: 53 45 20 61 73 20 74 68 65 20 64 69 72 65 63 74  SE as the direct
be90: 6f 72 79 0a 09 20 2a 2f 0a 09 66 75 73 65 5f 6f  ory.. */..fuse_o
bea0: 70 74 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e  pt_parse(args, N
beb0: 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29  ULL, NULL, NULL)
bec0: 3b 0a 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f  ;..fuse_opt_add_
bed0: 61 72 67 28 61 72 67 73 2c 20 61 72 67 76 5b 6f  arg(args, argv[o
bee0: 70 74 69 6e 64 20 2b 20 31 5d 29 3b 0a 0a 09 72  ptind + 1]);...r
bef0: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 0a 2f 2a  eturn(0);.}.../*
bf00: 0a 20 2a 20 46 55 53 45 20 6f 70 65 72 61 74 69  . * FUSE operati
bf10: 6f 6e 73 20 73 74 72 75 63 74 75 72 65 0a 20 2a  ons structure. *
bf20: 2f 0a 73 74 61 74 69 63 20 73 74 72 75 63 74 20  /.static struct 
bf30: 66 75 73 65 5f 6f 70 65 72 61 74 69 6f 6e 73 20  fuse_operations 
bf40: 61 70 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73  appfs_operations
bf50: 20 3d 20 7b 0a 09 2e 67 65 74 61 74 74 72 20 20   = {...getattr  
bf60: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 67 65   = appfs_fuse_ge
bf70: 74 61 74 74 72 2c 0a 09 2e 72 65 61 64 64 69 72  tattr,...readdir
bf80: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
bf90: 72 65 61 64 64 69 72 2c 0a 09 2e 72 65 61 64 6c  readdir,...readl
bfa0: 69 6e 6b 20 20 3d 20 61 70 70 66 73 5f 66 75 73  ink  = appfs_fus
bfb0: 65 5f 72 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f 70  e_readlink,...op
bfc0: 65 6e 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f  en      = appfs_
bfd0: 66 75 73 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65 6c  fuse_open,...rel
bfe0: 65 61 73 65 20 20 20 3d 20 61 70 70 66 73 5f 66  ease   = appfs_f
bff0: 75 73 65 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65 61  use_close,...rea
c000: 64 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66  d      = appfs_f
c010: 75 73 65 5f 72 65 61 64 2c 0a 09 2e 77 72 69 74  use_read,...writ
c020: 65 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  e     = appfs_fu
c030: 73 65 5f 77 72 69 74 65 2c 0a 09 2e 6d 6b 6e 6f  se_write,...mkno
c040: 64 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  d     = appfs_fu
c050: 73 65 5f 6d 6b 6e 6f 64 2c 0a 09 2e 63 72 65 61  se_mknod,...crea
c060: 74 65 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  te    = appfs_fu
c070: 73 65 5f 63 72 65 61 74 65 2c 0a 09 2e 74 72 75  se_create,...tru
c080: 6e 63 61 74 65 20 20 3d 20 61 70 70 66 73 5f 66  ncate  = appfs_f
c090: 75 73 65 5f 74 72 75 6e 63 61 74 65 2c 0a 09 2e  use_truncate,...
c0a0: 75 6e 6c 69 6e 6b 20 20 20 20 3d 20 61 70 70 66  unlink    = appf
c0b0: 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d  s_fuse_unlink_rm
c0c0: 64 69 72 2c 0a 09 2e 72 6d 64 69 72 20 20 20 20  dir,...rmdir    
c0d0: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e   = appfs_fuse_un
c0e0: 6c 69 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 6d 6b  link_rmdir,...mk
c0f0: 64 69 72 20 20 20 20 20 3d 20 61 70 70 66 73 5f  dir     = appfs_
c100: 66 75 73 65 5f 6d 6b 64 69 72 2c 0a 09 2e 63 68  fuse_mkdir,...ch
c110: 6d 6f 64 20 20 20 20 20 3d 20 61 70 70 66 73 5f  mod     = appfs_
c120: 66 75 73 65 5f 63 68 6d 6f 64 2c 0a 09 2e 73 79  fuse_chmod,...sy
c130: 6d 6c 69 6e 6b 20 20 20 3d 20 61 70 70 66 73 5f  mlink   = appfs_
c140: 66 75 73 65 5f 73 79 6d 6c 69 6e 6b 2c 0a 7d 3b  fuse_symlink,.};
c150: 0a 0a 2f 2a 0a 20 2a 20 45 6e 74 72 79 20 70 6f  ../*. * Entry po
c160: 69 6e 74 20 69 6e 74 6f 20 74 68 69 73 20 70 72  int into this pr
c170: 6f 67 72 61 6d 2e 0a 20 2a 2f 0a 69 6e 74 20 6d  ogram.. */.int m
c180: 61 69 6e 28 69 6e 74 20 61 72 67 63 2c 20 63 68  ain(int argc, ch
c190: 61 72 20 2a 2a 61 72 67 76 29 20 7b 0a 09 54 63  ar **argv) {..Tc
c1a0: 6c 5f 49 6e 74 65 72 70 20 2a 74 65 73 74 5f 69  l_Interp *test_i
c1b0: 6e 74 65 72 70 3b 0a 09 63 68 61 72 20 2a 74 65  nterp;..char *te
c1c0: 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 3b  st_interp_error;
c1d0: 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f 61 72  ..struct fuse_ar
c1e0: 67 73 20 61 72 67 73 20 3d 20 46 55 53 45 5f 41  gs args = FUSE_A
c1f0: 52 47 53 5f 49 4e 49 54 28 30 2c 20 4e 55 4c 4c  RGS_INIT(0, NULL
c200: 29 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f  );..int pthread_
c210: 72 65 74 2c 20 61 6f 70 5f 72 65 74 3b 0a 09 76  ret, aop_ret;..v
c220: 6f 69 64 20 2a 73 69 67 6e 61 6c 5f 72 65 74 3b  oid *signal_ret;
c230: 0a 09 63 68 61 72 20 2a 61 72 67 76 30 3b 0a 0a  ..char *argv0;..
c240: 09 2f 2a 0a 09 20 2a 20 53 6b 69 70 20 70 61 73  ./*.. * Skip pas
c250: 73 65 64 20 70 72 6f 67 72 61 6d 20 6e 61 6d 65  sed program name
c260: 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20  .. */..if (argc 
c270: 3d 3d 20 30 20 7c 7c 20 61 72 67 76 20 3d 3d 20  == 0 || argv == 
c280: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
c290: 28 31 29 3b 0a 09 7d 0a 0a 09 61 72 67 76 30 20  (1);..}...argv0 
c2a0: 3d 20 61 72 67 76 5b 30 5d 3b 0a 0a 09 61 72 67  = argv[0];...arg
c2b0: 63 2d 2d 3b 0a 09 61 72 67 76 2b 2b 3b 0a 0a 09  c--;..argv++;...
c2c0: 2f 2a 0a 09 20 2a 20 53 65 74 20 61 70 70 72 6f  /*.. * Set appro
c2d0: 70 72 69 61 74 65 20 75 6d 61 73 6b 0a 09 20 2a  priate umask.. *
c2e0: 2f 0a 09 75 6d 61 73 6b 28 30 32 32 29 3b 0a 0a  /..umask(022);..
c2f0: 09 2f 2a 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62  ./*.. * Set glob
c300: 61 6c 20 76 61 72 69 61 62 6c 65 73 2c 20 74 68  al variables, th
c310: 65 73 65 20 73 68 6f 75 6c 64 20 62 65 20 63 6f  ese should be co
c320: 6e 66 69 67 75 72 61 74 69 6f 6e 20 6f 70 74 69  nfiguration opti
c330: 6f 6e 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73  ons... */..appfs
c340: 5f 63 61 63 68 65 64 69 72 20 3d 20 41 50 50 46  _cachedir = APPF
c350: 53 5f 43 41 43 48 45 44 49 52 3b 0a 0a 09 2f 2a  S_CACHEDIR;.../*
c360: 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20  .. * Set global 
c370: 76 61 72 69 61 62 6c 65 20 66 6f 72 20 22 62 6f  variable for "bo
c380: 6f 74 20 74 69 6d 65 22 20 74 6f 20 73 65 74 20  ot time" to set 
c390: 61 20 74 69 6d 65 20 6f 6e 20 64 69 72 65 63 74  a time on direct
c3a0: 6f 72 69 65 73 0a 09 20 2a 20 74 68 61 74 20 77  ories.. * that w
c3b0: 65 20 66 61 6b 65 2e 0a 09 20 2a 2f 0a 09 61 70  e fake... */..ap
c3c0: 70 66 73 5f 62 6f 6f 74 74 69 6d 65 20 3d 20 74  pfs_boottime = t
c3d0: 69 6d 65 28 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a  ime(NULL);.../*.
c3e0: 09 20 2a 20 52 65 67 69 73 74 65 72 20 22 73 68  . * Register "sh
c3f0: 61 31 22 20 61 6e 64 20 22 61 70 70 66 73 64 22  a1" and "appfsd"
c400: 20 70 61 63 6b 61 67 65 20 77 69 74 68 20 6c 69   package with li
c410: 62 74 63 6c 20 73 6f 20 74 68 61 74 20 61 6e 79  btcl so that any
c420: 20 6e 65 77 0a 09 20 2a 20 69 6e 74 65 72 70 72   new.. * interpr
c430: 65 74 65 72 73 20 63 72 65 61 74 65 64 20 28 77  eters created (w
c440: 68 69 63 68 20 61 72 65 20 64 6f 6e 65 20 64 79  hich are done dy
c450: 6e 61 6d 69 63 61 6c 6c 79 20 62 79 20 46 55 53  namically by FUS
c460: 45 29 20 63 61 6e 20 68 61 76 65 0a 09 20 2a 20  E) can have.. * 
c470: 74 68 65 20 61 70 70 72 6f 70 72 69 61 74 65 20  the appropriate 
c480: 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 64 6f  configuration do
c490: 6e 65 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79  ne automatically
c4a0: 2e 0a 09 20 2a 2f 0a 09 54 63 6c 5f 53 74 61 74  ... */..Tcl_Stat
c4b0: 69 63 50 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20  icPackage(NULL, 
c4c0: 22 73 68 61 31 22 2c 20 53 68 61 31 5f 49 6e 69  "sha1", Sha1_Ini
c4d0: 74 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 53  t, NULL);..Tcl_S
c4e0: 74 61 74 69 63 50 61 63 6b 61 67 65 28 4e 55 4c  taticPackage(NUL
c4f0: 4c 2c 20 22 61 70 70 66 73 64 22 2c 20 41 70 70  L, "appfsd", App
c500: 66 73 64 5f 49 6e 69 74 2c 20 4e 55 4c 4c 29 3b  fsd_Init, NULL);
c510: 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72 65 61 74 65  .../*.. * Create
c520: 20 61 20 74 68 72 65 61 64 2d 73 70 65 63 69 66   a thread-specif
c530: 69 63 2d 64 61 74 61 20 28 54 53 44 29 20 6b 65  ic-data (TSD) ke
c540: 79 20 66 6f 72 20 65 61 63 68 20 74 68 72 65 61  y for each threa
c550: 64 20 74 6f 20 72 65 66 65 72 0a 09 20 2a 20 74  d to refer.. * t
c560: 6f 20 69 74 73 20 6f 77 6e 20 54 63 6c 20 69 6e  o its own Tcl in
c570: 74 65 72 70 72 65 74 65 72 2e 20 20 54 63 6c 20  terpreter.  Tcl 
c580: 69 6e 74 65 72 70 72 65 74 65 72 73 20 6d 75 73  interpreters mus
c590: 74 20 62 65 20 75 6e 69 71 75 65 20 70 65 72 0a  t be unique per.
c5a0: 09 20 2a 20 74 68 72 65 61 64 20 61 6e 64 20 6e  . * thread and n
c5b0: 65 77 20 74 68 72 65 61 64 73 20 61 72 65 20 64  ew threads are d
c5c0: 79 6e 61 6d 69 63 61 6c 6c 79 20 63 72 65 61 74  ynamically creat
c5d0: 65 64 20 62 79 20 46 55 53 45 2e 0a 09 20 2a 2f  ed by FUSE... */
c5e0: 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20  ..pthread_ret = 
c5f0: 70 74 68 72 65 61 64 5f 6b 65 79 5f 63 72 65 61  pthread_key_crea
c600: 74 65 28 26 69 6e 74 65 72 70 4b 65 79 2c 20 61  te(&interpKey, a
c610: 70 70 66 73 5f 74 65 72 6d 69 6e 61 74 65 5f 69  ppfs_terminate_i
c620: 6e 74 65 72 70 5f 61 6e 64 5f 74 68 72 65 61 64  nterp_and_thread
c630: 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f  );..if (pthread_
c640: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 66 70  ret != 0) {...fp
c650: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55  rintf(stderr, "U
c660: 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20  nable to create 
c670: 54 53 44 20 6b 65 79 20 66 6f 72 20 54 63 6c 2e  TSD key for Tcl.
c680: 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b    Aborting.\n");
c690: 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  ....return(1);..
c6a0: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61  }.../*.. * Manua
c6b0: 6c 6c 79 20 73 70 65 63 69 66 79 20 63 61 63 68  lly specify cach
c6c0: 65 20 64 69 72 65 63 74 6f 72 79 2c 20 77 69 74  e directory, wit
c6d0: 68 6f 75 74 20 46 55 53 45 20 63 61 6c 6c 62 61  hout FUSE callba
c6e0: 63 6b 0a 09 20 2a 20 54 68 69 73 20 6f 70 74 69  ck.. * This opti
c6f0: 6f 6e 20 6f 6e 6c 79 20 77 6f 72 6b 73 20 77 68  on only works wh
c700: 65 6e 20 6e 6f 74 20 75 73 69 6e 67 20 46 55 53  en not using FUS
c710: 45 2c 20 73 69 6e 63 65 20 77 65 0a 09 20 2a 20  E, since we.. * 
c720: 64 6f 20 6e 6f 74 20 70 72 6f 63 65 73 73 20 69  do not process i
c730: 74 20 77 69 74 68 20 46 55 53 45 73 20 6f 70 74  t with FUSEs opt
c740: 69 6f 6e 20 70 72 6f 63 65 73 73 69 6e 67 2e 0a  ion processing..
c750: 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3e  . */..if (argc >
c760: 3d 20 32 29 20 7b 0a 09 09 69 66 20 28 73 74 72  = 2) {...if (str
c770: 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d  cmp(argv[0], "--
c780: 63 61 63 68 65 64 69 72 22 29 20 3d 3d 20 30 29  cachedir") == 0)
c790: 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 63 68   {....appfs_cach
c7a0: 65 64 69 72 20 3d 20 73 74 72 64 75 70 28 61 72  edir = strdup(ar
c7b0: 67 76 5b 31 5d 29 3b 0a 0a 09 09 09 61 72 67 63  gv[1]);.....argc
c7c0: 20 2d 3d 20 32 3b 0a 09 09 09 61 72 67 76 20 2b   -= 2;....argv +
c7d0: 3d 20 32 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a  = 2;...}..}.../*
c7e0: 0a 09 20 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64  .. * SQLite3 mod
c7f0: 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72  e, for running r
c800: 61 77 20 53 51 4c 20 61 67 61 69 6e 73 74 20 74  aw SQL against t
c810: 68 65 20 63 61 63 68 65 20 64 61 74 61 62 61 73  he cache databas
c820: 65 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63  e.. */..if (argc
c830: 20 3d 3d 20 32 20 26 26 20 73 74 72 63 6d 70 28   == 2 && strcmp(
c840: 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69  argv[0], "--sqli
c850: 74 65 33 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09  te3") == 0) {...
c860: 72 65 74 75 72 6e 28 61 70 70 66 73 5f 73 71 6c  return(appfs_sql
c870: 69 74 65 33 28 61 72 67 76 5b 31 5d 29 29 3b 0a  ite3(argv[1]));.
c880: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 54 63 6c 20  .}.../*.. * Tcl 
c890: 6d 6f 64 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e  mode, for runnin
c8a0: 67 20 72 61 77 20 54 63 6c 20 69 6e 20 74 68 65  g raw Tcl in the
c8b0: 20 73 61 6d 65 20 65 6e 76 69 72 6f 6e 6d 65 6e   same environmen
c8c0: 74 20 41 70 70 46 53 64 20 77 6f 75 6c 64 0a 09  t AppFSd would..
c8d0: 20 2a 20 72 75 6e 20 63 6f 64 65 2e 0a 09 20 2a   * run code... *
c8e0: 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20 32  /..if (argc == 2
c8f0: 20 26 26 20 73 74 72 63 6d 70 28 61 72 67 76 5b   && strcmp(argv[
c900: 30 5d 2c 20 22 2d 2d 74 63 6c 22 29 20 3d 3d 20  0], "--tcl") == 
c910: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 61 70  0) {...return(ap
c920: 70 66 73 5f 74 63 6c 28 61 72 67 76 5b 31 5d 29  pfs_tcl(argv[1])
c930: 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 52  );..}.../*.. * R
c940: 65 67 69 73 74 65 72 20 61 20 73 69 67 6e 61 6c  egister a signal
c950: 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 68 6f 74   handler for hot
c960: 2d 72 65 73 74 61 72 74 20 72 65 71 75 65 73 74  -restart request
c970: 73 0a 09 20 2a 2f 0a 09 73 69 67 6e 61 6c 5f 72  s.. */..signal_r
c980: 65 74 20 3d 20 73 69 67 6e 61 6c 28 53 49 47 48  et = signal(SIGH
c990: 55 50 2c 20 61 70 70 66 73 5f 73 69 67 6e 61 6c  UP, appfs_signal
c9a0: 5f 68 61 6e 64 6c 65 72 29 3b 0a 09 69 66 20 28  _handler);..if (
c9b0: 73 69 67 6e 61 6c 5f 72 65 74 20 3d 3d 20 53 49  signal_ret == SI
c9c0: 47 5f 45 52 52 29 20 7b 0a 09 09 66 70 72 69 6e  G_ERR) {...fprin
c9d0: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
c9e0: 6c 65 20 74 6f 20 69 6e 73 74 61 6c 6c 20 73 69  le to install si
c9f0: 67 6e 61 6c 20 68 61 6e 64 6c 65 72 20 66 6f 72  gnal handler for
ca00: 20 68 6f 74 2d 72 65 73 74 61 72 74 5c 6e 22 29   hot-restart\n")
ca10: 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ;...fprintf(stde
ca20: 72 72 2c 20 22 48 6f 74 2d 72 65 73 74 61 72 74  rr, "Hot-restart
ca30: 20 77 69 6c 6c 20 6e 6f 74 20 62 65 20 61 76 61   will not be ava
ca40: 69 6c 61 62 6c 65 2e 5c 6e 22 29 3b 0a 09 7d 0a  ilable.\n");..}.
ca50: 0a 09 2f 2a 0a 09 20 2a 20 50 61 72 73 65 20 63  ../*.. * Parse c
ca60: 6f 6d 6d 61 6e 64 20 6c 69 6e 65 20 61 72 67 75  ommand line argu
ca70: 6d 65 6e 74 73 0a 09 20 2a 2f 0a 09 2f 2a 2a 0a  ments.. */../**.
ca80: 09 20 2a 2a 20 52 65 73 74 6f 72 65 20 61 72 67  . ** Restore arg
ca90: 63 2f 61 72 67 76 20 74 6f 20 6f 72 69 67 69 6e  c/argv to origin
caa0: 61 6c 20 76 61 6c 75 65 73 2c 20 72 65 70 6c 61  al values, repla
cab0: 63 69 6e 67 20 61 72 67 76 5b 30 5d 20 69 6e 20  cing argv[0] in 
cac0: 63 61 73 65 0a 09 20 2a 2a 20 69 74 20 77 61 73  case.. ** it was
cad0: 20 6d 6f 69 66 69 65 64 20 62 79 20 2d 2d 63 61   moified by --ca
cae0: 63 68 65 64 69 72 20 6f 70 74 69 6f 6e 2e 0a 09  chedir option...
caf0: 20 2a 2a 2f 0a 09 61 72 67 63 2b 2b 3b 0a 09 61   **/..argc++;..a
cb00: 72 67 76 2d 2d 3b 0a 09 61 72 67 76 5b 30 5d 20  rgv--;..argv[0] 
cb10: 3d 20 61 72 67 76 30 3b 0a 0a 09 2f 2a 2a 0a 09  = argv0;.../**..
cb20: 20 2a 2a 20 50 65 72 66 6f 72 6d 20 74 68 65 20   ** Perform the 
cb30: 61 72 67 75 6d 65 6e 74 20 70 61 72 73 69 6e 67  argument parsing
cb40: 0a 09 20 2a 2a 2f 0a 09 61 6f 70 5f 72 65 74 20  .. **/..aop_ret 
cb50: 3d 20 61 70 70 66 73 5f 6f 70 74 5f 70 61 72 73  = appfs_opt_pars
cb60: 65 28 61 72 67 63 2c 20 61 72 67 76 2c 20 26 61  e(argc, argv, &a
cb70: 72 67 73 29 3b 0a 09 69 66 20 28 61 6f 70 5f 72  rgs);..if (aop_r
cb80: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 69 66 20  et != 0) {...if 
cb90: 28 61 6f 70 5f 72 65 74 20 3c 20 30 29 20 7b 0a  (aop_ret < 0) {.
cba0: 09 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 09  ...return(0);...
cbb0: 7d 0a 0a 09 09 72 65 74 75 72 6e 28 61 6f 70 5f  }....return(aop_
cbc0: 72 65 74 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  ret);..}.../*.. 
cbd0: 2a 20 43 72 65 61 74 65 20 61 20 54 63 6c 20 69  * Create a Tcl i
cbe0: 6e 74 65 72 70 72 65 74 65 72 20 6a 75 73 74 20  nterpreter just 
cbf0: 74 6f 20 76 65 72 69 66 79 20 74 68 61 74 20 74  to verify that t
cc00: 68 69 6e 67 73 20 61 72 65 20 69 6e 20 77 6f 72  hings are in wor
cc10: 6b 69 6e 67 20 0a 09 20 2a 20 6f 72 64 65 72 20  king .. * order 
cc20: 62 65 66 6f 72 65 20 77 65 20 62 65 63 6f 6d 65  before we become
cc30: 20 61 20 64 61 65 6d 6f 6e 2e 0a 09 20 2a 2f 0a   a daemon... */.
cc40: 09 74 65 73 74 5f 69 6e 74 65 72 70 20 3d 20 61  .test_interp = a
cc50: 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49  ppfs_create_TclI
cc60: 6e 74 65 72 70 28 26 74 65 73 74 5f 69 6e 74 65  nterp(&test_inte
cc70: 72 70 5f 65 72 72 6f 72 29 3b 0a 09 69 66 20 28  rp_error);..if (
cc80: 74 65 73 74 5f 69 6e 74 65 72 70 20 3d 3d 20 4e  test_interp == N
cc90: 55 4c 4c 29 20 7b 0a 09 09 69 66 20 28 74 65 73  ULL) {...if (tes
cca0: 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 20 3d  t_interp_error =
ccb0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 74 65 73  = NULL) {....tes
ccc0: 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 20 3d  t_interp_error =
ccd0: 20 22 55 6e 6b 6e 6f 77 6e 20 65 72 72 6f 72 22   "Unknown error"
cce0: 3b 0a 09 09 7d 0a 0a 09 09 66 70 72 69 6e 74 66  ;...}....fprintf
ccf0: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
cd00: 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54   to initialize T
cd10: 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 20 66  cl interpreter f
cd20: 6f 72 20 41 70 70 46 53 64 3a 5c 6e 22 29 3b 0a  or AppFSd:\n");.
cd30: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
cd40: 2c 20 22 25 73 5c 6e 22 2c 20 74 65 73 74 5f 69  , "%s\n", test_i
cd50: 6e 74 65 72 70 5f 65 72 72 6f 72 29 3b 0a 0a 09  nterp_error);...
cd60: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a  .return(1);..}..
cd70: 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72  .Tcl_DeleteInter
cd80: 70 28 74 65 73 74 5f 69 6e 74 65 72 70 29 3b 0a  p(test_interp);.
cd90: 0a 09 69 66 20 28 61 70 70 66 73 5f 74 68 72 65  ..if (appfs_thre
cda0: 61 64 65 64 5f 74 63 6c 29 20 7b 0a 09 09 54 63  aded_tcl) {...Tc
cdb0: 6c 5f 46 69 6e 61 6c 69 7a 65 4e 6f 74 69 66 69  l_FinalizeNotifi
cdc0: 65 72 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f  er(NULL);..}.../
cdd0: 2a 0a 09 20 2a 20 45 6e 74 65 72 20 74 68 65 20  *.. * Enter the 
cde0: 46 55 53 45 20 6d 61 69 6e 20 6c 6f 6f 70 20 2d  FUSE main loop -
cdf0: 2d 20 74 68 69 73 20 77 69 6c 6c 20 70 72 6f 63  - this will proc
ce00: 65 73 73 20 61 6e 79 20 61 72 67 75 6d 65 6e 74  ess any argument
ce10: 73 0a 09 20 2a 20 61 6e 64 20 73 74 61 72 74 20  s.. * and start 
ce20: 73 65 72 76 69 63 69 6e 67 20 72 65 71 75 65 73  servicing reques
ce30: 74 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f  ts... */..appfs_
ce40: 66 75 73 65 5f 73 74 61 72 74 65 64 20 3d 20 31  fuse_started = 1
ce50: 3b 0a 09 72 65 74 75 72 6e 28 66 75 73 65 5f 6d  ;..return(fuse_m
ce60: 61 69 6e 28 61 72 67 73 2e 61 72 67 63 2c 20 61  ain(args.argc, a
ce70: 72 67 73 2e 61 72 67 76 2c 20 26 61 70 70 66 73  rgs.argv, &appfs
ce80: 5f 6f 70 65 72 61 74 69 6f 6e 73 2c 20 4e 55 4c  _operations, NUL
ce90: 4c 29 29 3b 0a 7d 0a                             L));.}.