Hex Artifact Content

Artifact 4ff2357fbba766fe8ec0519afccc5c25036a49ae:


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 2c 20 32 30 31 35 20 20  (c) 2014, 2015  
0020: 52 6f 79 20 4b 65 65 6e 65 0a 20 2a 0a 20 2a 20  Roy Keene. *. * 
0030: 50 65 72 6d 69 73 73 69 6f 6e 20 69 73 20 68 65  Permission is he
0040: 72 65 62 79 20 67 72 61 6e 74 65 64 2c 20 66 72  reby granted, fr
0050: 65 65 20 6f 66 20 63 68 61 72 67 65 2c 20 74 6f  ee of charge, to
0060: 20 61 6e 79 20 70 65 72 73 6f 6e 20 6f 62 74 61   any person obta
0070: 69 6e 69 6e 67 20 61 20 63 6f 70 79 0a 20 2a 20  ining a copy. * 
0080: 6f 66 20 74 68 69 73 20 73 6f 66 74 77 61 72 65  of this software
0090: 20 61 6e 64 20 61 73 73 6f 63 69 61 74 65 64 20   and associated 
00a0: 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e 20 66 69  documentation fi
00b0: 6c 65 73 20 28 74 68 65 20 22 53 6f 66 74 77 61  les (the "Softwa
00c0: 72 65 22 29 2c 20 74 6f 20 64 65 61 6c 0a 20 2a  re"), to deal. *
00d0: 20 69 6e 20 74 68 65 20 53 6f 66 74 77 61 72 65   in the Software
00e0: 20 77 69 74 68 6f 75 74 20 72 65 73 74 72 69 63   without restric
00f0: 74 69 6f 6e 2c 20 69 6e 63 6c 75 64 69 6e 67 20  tion, including 
0100: 77 69 74 68 6f 75 74 20 6c 69 6d 69 74 61 74 69  without limitati
0110: 6f 6e 20 74 68 65 20 72 69 67 68 74 73 0a 20 2a  on the rights. *
0120: 20 74 6f 20 75 73 65 2c 20 63 6f 70 79 2c 20 6d   to use, copy, m
0130: 6f 64 69 66 79 2c 20 6d 65 72 67 65 2c 20 70 75  odify, merge, pu
0140: 62 6c 69 73 68 2c 20 64 69 73 74 72 69 62 75 74  blish, distribut
0150: 65 2c 20 73 75 62 6c 69 63 65 6e 73 65 2c 20 61  e, sublicense, a
0160: 6e 64 2f 6f 72 20 73 65 6c 6c 0a 20 2a 20 63 6f  nd/or sell. * co
0170: 70 69 65 73 20 6f 66 20 74 68 65 20 53 6f 66 74  pies of the Soft
0180: 77 61 72 65 2c 20 61 6e 64 20 74 6f 20 70 65 72  ware, and to per
0190: 6d 69 74 20 70 65 72 73 6f 6e 73 20 74 6f 20 77  mit persons to w
01a0: 68 6f 6d 20 74 68 65 20 53 6f 66 74 77 61 72 65  hom the Software
01b0: 20 69 73 0a 20 2a 20 66 75 72 6e 69 73 68 65 64   is. * furnished
01c0: 20 74 6f 20 64 6f 20 73 6f 2c 20 73 75 62 6a 65   to do so, subje
01d0: 63 74 20 74 6f 20 74 68 65 20 66 6f 6c 6c 6f 77  ct to the follow
01e0: 69 6e 67 20 63 6f 6e 64 69 74 69 6f 6e 73 3a 0a  ing conditions:.
01f0: 20 2a 0a 20 2a 20 54 68 65 20 61 62 6f 76 65 20   *. * The above 
0200: 63 6f 70 79 72 69 67 68 74 20 6e 6f 74 69 63 65  copyright notice
0210: 20 61 6e 64 20 74 68 69 73 20 70 65 72 6d 69 73   and this permis
0220: 73 69 6f 6e 20 6e 6f 74 69 63 65 20 73 68 61 6c  sion notice shal
0230: 6c 20 62 65 20 69 6e 63 6c 75 64 65 64 20 69 6e  l be included in
0240: 0a 20 2a 20 61 6c 6c 20 63 6f 70 69 65 73 20 6f  . * all copies o
0250: 72 20 73 75 62 73 74 61 6e 74 69 61 6c 20 70 6f  r substantial po
0260: 72 74 69 6f 6e 73 20 6f 66 20 74 68 65 20 53 6f  rtions of the So
0270: 66 74 77 61 72 65 2e 0a 20 2a 0a 20 2a 20 54 48  ftware.. *. * TH
0280: 45 20 53 4f 46 54 57 41 52 45 20 49 53 20 50 52  E SOFTWARE IS PR
0290: 4f 56 49 44 45 44 20 22 41 53 20 49 53 22 2c 20  OVIDED "AS IS", 
02a0: 57 49 54 48 4f 55 54 20 57 41 52 52 41 4e 54 59  WITHOUT WARRANTY
02b0: 20 4f 46 20 41 4e 59 20 4b 49 4e 44 2c 20 45 58   OF ANY KIND, EX
02c0: 50 52 45 53 53 20 4f 52 0a 20 2a 20 49 4d 50 4c  PRESS OR. * IMPL
02d0: 49 45 44 2c 20 49 4e 43 4c 55 44 49 4e 47 20 42  IED, INCLUDING B
02e0: 55 54 20 4e 4f 54 20 4c 49 4d 49 54 45 44 20 54  UT NOT LIMITED T
02f0: 4f 20 54 48 45 20 57 41 52 52 41 4e 54 49 45 53  O THE WARRANTIES
0300: 20 4f 46 20 4d 45 52 43 48 41 4e 54 41 42 49 4c   OF MERCHANTABIL
0310: 49 54 59 2c 0a 20 2a 20 46 49 54 4e 45 53 53 20  ITY,. * FITNESS 
0320: 46 4f 52 20 41 20 50 41 52 54 49 43 55 4c 41 52  FOR A PARTICULAR
0330: 20 50 55 52 50 4f 53 45 20 41 4e 44 20 4e 4f 4e   PURPOSE AND NON
0340: 49 4e 46 52 49 4e 47 45 4d 45 4e 54 2e 20 49 4e  INFRINGEMENT. IN
0350: 20 4e 4f 20 45 56 45 4e 54 20 53 48 41 4c 4c 20   NO EVENT SHALL 
0360: 54 48 45 0a 20 2a 20 41 55 54 48 4f 52 53 20 4f  THE. * AUTHORS O
0370: 52 20 43 4f 50 59 52 49 47 48 54 20 48 4f 4c 44  R COPYRIGHT HOLD
0380: 45 52 53 20 42 45 20 4c 49 41 42 4c 45 20 46 4f  ERS BE LIABLE FO
0390: 52 20 41 4e 59 20 43 4c 41 49 4d 2c 20 44 41 4d  R ANY CLAIM, DAM
03a0: 41 47 45 53 20 4f 52 20 4f 54 48 45 52 0a 20 2a  AGES OR OTHER. *
03b0: 20 4c 49 41 42 49 4c 49 54 59 2c 20 57 48 45 54   LIABILITY, WHET
03c0: 48 45 52 20 49 4e 20 41 4e 20 41 43 54 49 4f 4e  HER IN AN ACTION
03d0: 20 4f 46 20 43 4f 4e 54 52 41 43 54 2c 20 54 4f   OF CONTRACT, TO
03e0: 52 54 20 4f 52 20 4f 54 48 45 52 57 49 53 45 2c  RT OR OTHERWISE,
03f0: 20 41 52 49 53 49 4e 47 20 46 52 4f 4d 2c 0a 20   ARISING FROM,. 
0400: 2a 20 4f 55 54 20 4f 46 20 4f 52 20 49 4e 20 43  * OUT OF OR IN C
0410: 4f 4e 4e 45 43 54 49 4f 4e 20 57 49 54 48 20 54  ONNECTION WITH T
0420: 48 45 20 53 4f 46 54 57 41 52 45 20 4f 52 20 54  HE SOFTWARE OR T
0430: 48 45 20 55 53 45 20 4f 52 20 4f 54 48 45 52 20  HE USE OR OTHER 
0440: 44 45 41 4c 49 4e 47 53 20 49 4e 0a 20 2a 20 54  DEALINGS IN. * T
0450: 48 45 20 53 4f 46 54 57 41 52 45 2e 0a 20 2a 2f  HE SOFTWARE.. */
0460: 0a 23 64 65 66 69 6e 65 20 46 55 53 45 5f 55 53  .#define FUSE_US
0470: 45 5f 56 45 52 53 49 4f 4e 20 32 36 0a 0a 23 69  E_VERSION 26..#i
0480: 6e 63 6c 75 64 65 20 3c 73 79 73 2f 66 73 75 69  nclude <sys/fsui
0490: 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73  d.h>.#include <s
04a0: 79 73 2f 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63  ys/types.h>.#inc
04b0: 6c 75 64 65 20 3c 73 79 73 2f 74 69 6d 65 2e 68  lude <sys/time.h
04c0: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 70 74 68 72  >.#include <pthr
04d0: 65 61 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  ead.h>.#include 
04e0: 3c 6c 69 6d 69 74 73 2e 68 3e 0a 23 69 6e 63 6c  <limits.h>.#incl
04f0: 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23  ude <string.h>.#
0500: 69 6e 63 6c 75 64 65 20 3c 73 74 64 61 72 67 2e  include <stdarg.
0510: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64  h>.#include <std
0520: 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  lib.h>.#include 
0530: 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c  <unistd.h>.#incl
0540: 75 64 65 20 3c 65 72 72 6e 6f 2e 68 3e 0a 23 69  ude <errno.h>.#i
0550: 6e 63 6c 75 64 65 20 3c 66 63 6e 74 6c 2e 68 3e  nclude <fcntl.h>
0560: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f  .#include <stdio
0570: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 66 75  .h>.#include <fu
0580: 73 65 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  se.h>.#include <
0590: 70 77 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  pwd.h>.#include 
05a0: 3c 74 63 6c 2e 68 3e 0a 0a 2f 2a 0a 20 2a 20 44  <tcl.h>../*. * D
05b0: 65 66 61 75 6c 74 20 63 61 63 68 65 20 64 69 72  efault cache dir
05c0: 65 63 74 6f 72 79 0a 20 2a 2f 0a 23 69 66 6e 64  ectory. */.#ifnd
05d0: 65 66 20 41 50 50 46 53 5f 43 41 43 48 45 44 49  ef APPFS_CACHEDI
05e0: 52 0a 23 64 65 66 69 6e 65 20 41 50 50 46 53 5f  R.#define APPFS_
05f0: 43 41 43 48 45 44 49 52 20 22 2f 76 61 72 2f 63  CACHEDIR "/var/c
0600: 61 63 68 65 2f 61 70 70 66 73 22 0a 23 65 6e 64  ache/appfs".#end
0610: 69 66 0a 0a 2f 2a 20 44 65 62 75 67 67 69 6e 67  if../* Debugging
0620: 20 6d 61 63 72 6f 73 20 2a 2f 0a 23 69 66 64 65   macros */.#ifde
0630: 66 20 44 45 42 55 47 0a 46 49 4c 45 20 2a 61 70  f DEBUG.FILE *ap
0640: 70 66 73 5f 64 65 62 75 67 5f 66 64 20 3d 20 4e  pfs_debug_fd = N
0650: 55 4c 4c 3b 0a 23 64 65 66 69 6e 65 20 41 50 50  ULL;.#define APP
0660: 46 53 5f 44 45 42 55 47 28 78 2e 2e 2e 29 20 7b  FS_DEBUG(x...) {
0670: 20 5c 0a 09 63 68 61 72 20 62 75 66 5b 38 31 39   \..char buf[819
0680: 32 5d 3b 20 5c 0a 09 69 6e 74 20 62 75 66 6f 66  2]; \..int bufof
0690: 66 20 3d 20 30 3b 20 5c 0a 09 63 68 61 72 20 2a  f = 0; \..char *
06a0: 61 70 70 66 73 5f 64 65 62 75 67 5f 66 69 6c 65  appfs_debug_file
06b0: 20 3d 20 4e 55 4c 4c 3b 20 5c 0a 09 69 66 20 28   = NULL; \..if (
06c0: 61 70 70 66 73 5f 64 65 62 75 67 5f 66 64 20 3d  appfs_debug_fd =
06d0: 3d 20 4e 55 4c 4c 29 20 7b 20 5c 0a 09 09 61 70  = NULL) { \...ap
06e0: 70 66 73 5f 64 65 62 75 67 5f 66 69 6c 65 20 3d  pfs_debug_file =
06f0: 20 67 65 74 65 6e 76 28 22 41 50 50 46 53 5f 44   getenv("APPFS_D
0700: 45 42 55 47 5f 46 49 4c 45 22 29 3b 20 5c 0a 09  EBUG_FILE"); \..
0710: 09 69 66 20 28 61 70 70 66 73 5f 64 65 62 75 67  .if (appfs_debug
0720: 5f 66 69 6c 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _file == NULL) {
0730: 20 5c 0a 09 09 09 61 70 70 66 73 5f 64 65 62 75   \....appfs_debu
0740: 67 5f 66 69 6c 65 20 3d 20 22 73 74 64 65 72 72  g_file = "stderr
0750: 22 3b 20 5c 0a 09 09 7d 3b 20 5c 0a 09 09 69 66  "; \...}; \...if
0760: 20 28 73 74 72 63 6d 70 28 61 70 70 66 73 5f 64   (strcmp(appfs_d
0770: 65 62 75 67 5f 66 69 6c 65 2c 20 22 73 74 64 65  ebug_file, "stde
0780: 72 72 22 29 20 3d 3d 20 30 29 20 7b 20 5c 0a 09  rr") == 0) { \..
0790: 09 09 61 70 70 66 73 5f 64 65 62 75 67 5f 66 64  ..appfs_debug_fd
07a0: 20 3d 20 73 74 64 65 72 72 3b 20 5c 0a 09 09 7d   = stderr; \...}
07b0: 20 65 6c 73 65 20 7b 20 5c 0a 09 09 09 61 70 70   else { \....app
07c0: 66 73 5f 64 65 62 75 67 5f 66 64 20 3d 20 66 6f  fs_debug_fd = fo
07d0: 70 65 6e 28 61 70 70 66 73 5f 64 65 62 75 67 5f  pen(appfs_debug_
07e0: 66 69 6c 65 2c 20 22 61 22 29 3b 20 5c 0a 09 09  file, "a"); \...
07f0: 7d 3b 20 5c 0a 09 7d 3b 20 5c 0a 09 69 66 20 28  }; \..}; \..if (
0800: 61 70 70 66 73 5f 64 65 62 75 67 5f 66 64 20 3d  appfs_debug_fd =
0810: 3d 20 4e 55 4c 4c 29 20 7b 20 61 70 70 66 73 5f  = NULL) { appfs_
0820: 64 65 62 75 67 5f 66 64 20 3d 20 73 74 64 65 72  debug_fd = stder
0830: 72 3b 20 7d 20 5c 0a 09 62 75 66 6f 66 66 20 3d  r; } \..bufoff =
0840: 20 73 6e 70 72 69 6e 74 66 28 62 75 66 2c 20 73   snprintf(buf, s
0850: 69 7a 65 6f 66 28 62 75 66 29 2c 20 22 5b 64 65  izeof(buf), "[de
0860: 62 75 67 5d 20 5b 74 3d 25 6c 6c 78 5d 20 25 73  bug] [t=%llx] %s
0870: 3a 25 69 3a 25 73 3a 20 22 2c 20 28 75 6e 73 69  :%i:%s: ", (unsi
0880: 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20  gned long long) 
0890: 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29 2c 20  pthread_self(), 
08a0: 5f 5f 46 49 4c 45 5f 5f 2c 20 5f 5f 4c 49 4e 45  __FILE__, __LINE
08b0: 5f 5f 2c 20 5f 5f 66 75 6e 63 5f 5f 29 3b 20 5c  __, __func__); \
08c0: 0a 09 69 66 20 28 62 75 66 6f 66 66 20 3c 20 73  ..if (bufoff < s
08d0: 69 7a 65 6f 66 28 62 75 66 29 29 20 7b 20 5c 0a  izeof(buf)) { \.
08e0: 09 09 62 75 66 6f 66 66 20 2b 3d 20 73 6e 70 72  ..bufoff += snpr
08f0: 69 6e 74 66 28 62 75 66 20 2b 20 62 75 66 6f 66  intf(buf + bufof
0900: 66 2c 20 73 69 7a 65 6f 66 28 62 75 66 29 20 2d  f, sizeof(buf) -
0910: 20 62 75 66 6f 66 66 2c 20 78 29 3b 20 5c 0a 09   bufoff, x); \..
0920: 7d 3b 20 5c 0a 09 69 66 20 28 62 75 66 6f 66 66  }; \..if (bufoff
0930: 20 3c 20 73 69 7a 65 6f 66 28 62 75 66 29 29 20   < sizeof(buf)) 
0940: 7b 20 5c 0a 09 09 62 75 66 6f 66 66 20 2b 3d 20  { \...bufoff += 
0950: 73 6e 70 72 69 6e 74 66 28 62 75 66 20 2b 20 62  snprintf(buf + b
0960: 75 66 6f 66 66 2c 20 73 69 7a 65 6f 66 28 62 75  ufoff, sizeof(bu
0970: 66 29 20 2d 20 62 75 66 6f 66 66 2c 20 22 5c 6e  f) - bufoff, "\n
0980: 22 29 3b 5c 0a 09 7d 20 5c 0a 09 69 66 20 28 62  ");\..} \..if (b
0990: 75 66 6f 66 66 20 3e 20 73 69 7a 65 6f 66 28 62  ufoff > sizeof(b
09a0: 75 66 29 29 20 7b 20 5c 0a 09 09 62 75 66 6f 66  uf)) { \...bufof
09b0: 66 20 3d 20 73 69 7a 65 6f 66 28 62 75 66 29 3b  f = sizeof(buf);
09c0: 20 5c 0a 09 7d 3b 20 5c 0a 09 66 70 72 69 6e 74   \..}; \..fprint
09d0: 66 28 61 70 70 66 73 5f 64 65 62 75 67 5f 66 64  f(appfs_debug_fd
09e0: 2c 20 22 25 2e 2a 73 22 2c 20 62 75 66 6f 66 66  , "%.*s", bufoff
09f0: 2c 20 62 75 66 29 3b 20 5c 0a 09 66 66 6c 75 73  , buf); \..fflus
0a00: 68 28 61 70 70 66 73 5f 64 65 62 75 67 5f 66 64  h(appfs_debug_fd
0a10: 29 3b 20 5c 0a 7d 0a 23 64 65 66 69 6e 65 20 41  ); \.}.#define A
0a20: 50 50 46 53 5f 45 52 52 4f 52 28 78 2e 2e 2e 29  PPFS_ERROR(x...)
0a30: 20 41 50 50 46 53 5f 44 45 42 55 47 28 78 29 0a   APPFS_DEBUG(x).
0a40: 23 65 6c 73 65 0a 23 64 65 66 69 6e 65 20 41 50  #else.#define AP
0a50: 50 46 53 5f 44 45 42 55 47 28 78 2e 2e 2e 29 20  PFS_DEBUG(x...) 
0a60: 2f 2a 2a 2f 0a 23 64 65 66 69 6e 65 20 41 50 50  /**/.#define APP
0a70: 46 53 5f 45 52 52 4f 52 28 78 2e 2e 2e 29 20 66  FS_ERROR(x...) f
0a80: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 78  printf(stderr, x
0a90: 29 3b 20 66 70 72 69 6e 74 66 28 73 74 64 65 72  ); fprintf(stder
0aa0: 72 2c 20 22 5c 6e 22 29 3b 0a 23 65 6e 64 69 66  r, "\n");.#endif
0ab0: 0a 0a 2f 2a 0a 20 2a 20 53 48 41 31 20 54 63 6c  ../*. * SHA1 Tcl
0ac0: 20 50 61 63 6b 61 67 65 20 69 6e 69 74 69 61 6c   Package initial
0ad0: 69 7a 65 72 2c 20 66 72 6f 6d 20 73 68 61 31 2e  izer, from sha1.
0ae0: 6f 0a 20 2a 2f 0a 69 6e 74 20 53 68 61 31 5f 49  o. */.int Sha1_I
0af0: 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a  nit(Tcl_Interp *
0b00: 69 6e 74 65 72 70 29 3b 0a 0a 2f 2a 0a 20 2a 20  interp);../*. * 
0b10: 54 68 72 65 61 64 20 53 70 65 63 69 66 69 63 20  Thread Specific 
0b20: 44 61 74 61 20 28 54 53 44 29 20 66 6f 72 20 54  Data (TSD) for T
0b30: 63 6c 20 49 6e 74 65 72 70 72 65 74 65 72 20 66  cl Interpreter f
0b40: 6f 72 20 74 68 65 20 63 75 72 72 65 6e 74 20 74  or the current t
0b50: 68 72 65 61 64 0a 20 2a 2f 0a 73 74 61 74 69 63  hread. */.static
0b60: 20 70 74 68 72 65 61 64 5f 6b 65 79 5f 74 20 69   pthread_key_t i
0b70: 6e 74 65 72 70 4b 65 79 3b 0a 0a 2f 2a 0a 20 2a  nterpKey;../*. *
0b80: 20 47 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65   Global variable
0b90: 73 2c 20 6e 65 65 64 65 64 20 66 6f 72 20 61 6c  s, needed for al
0ba0: 6c 20 74 68 72 65 61 64 73 20 62 75 74 20 6f 6e  l threads but on
0bb0: 6c 79 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 62  ly initialized b
0bc0: 65 66 6f 72 65 20 61 6e 79 0a 20 2a 20 46 55 53  efore any. * FUS
0bd0: 45 20 74 68 72 65 61 64 73 20 61 72 65 20 63 72  E threads are cr
0be0: 65 61 74 65 64 0a 20 2a 2f 0a 63 6f 6e 73 74 20  eated. */.const 
0bf0: 63 68 61 72 20 2a 61 70 70 66 73 5f 63 61 63 68  char *appfs_cach
0c00: 65 64 69 72 3b 0a 74 69 6d 65 5f 74 20 61 70 70  edir;.time_t app
0c10: 66 73 5f 62 6f 6f 74 74 69 6d 65 3b 0a 69 6e 74  fs_boottime;.int
0c20: 20 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72   appfs_fuse_star
0c30: 74 65 64 20 3d 20 30 3b 0a 69 6e 74 20 61 70 70  ted = 0;.int app
0c40: 66 73 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 3b  fs_threaded_tcl;
0c50: 0a 0a 2f 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20 76  ../*. * Global v
0c60: 61 72 69 61 62 6c 65 73 20 66 6f 72 20 41 70 70  ariables for App
0c70: 46 53 20 63 61 63 68 69 6e 67 0a 20 2a 2f 0a 70  FS caching. */.p
0c80: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 61  thread_mutex_t a
0c90: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
0ca0: 61 63 68 65 5f 6d 75 74 65 78 20 3d 20 50 54 48  ache_mutex = PTH
0cb0: 52 45 41 44 5f 4d 55 54 45 58 5f 49 4e 49 54 49  READ_MUTEX_INITI
0cc0: 41 4c 49 5a 45 52 3b 0a 69 6e 74 20 61 70 70 66  ALIZER;.int appf
0cd0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
0ce0: 65 5f 73 69 7a 65 20 3d 20 38 32 30 39 3b 0a 73  e_size = 8209;.s
0cf0: 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68  truct appfs_path
0d00: 69 6e 66 6f 20 2a 61 70 70 66 73 5f 70 61 74 68  info *appfs_path
0d10: 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20 4e 55  _info_cache = NU
0d20: 4c 4c 3b 0a 0a 23 69 66 20 21 64 65 66 69 6e 65  LL;..#if !define
0d30: 64 28 54 43 4c 5f 54 48 52 45 41 44 53 29 20 7c  d(TCL_THREADS) |
0d40: 7c 20 54 43 4c 5f 54 48 52 45 41 44 53 20 21 3d  | TCL_THREADS !=
0d50: 20 31 0a 2f 2a 0a 20 2a 20 48 61 6e 64 6c 65 20   1./*. * Handle 
0d60: 75 6e 74 68 72 65 61 64 65 64 20 54 63 6c 0a 20  unthreaded Tcl. 
0d70: 2a 2f 0a 70 74 68 72 65 61 64 5f 6d 75 74 65 78  */.pthread_mutex
0d80: 5f 74 20 61 70 70 66 73 5f 74 63 6c 5f 62 69 67  _t appfs_tcl_big
0d90: 5f 67 6c 6f 62 61 6c 5f 6c 6f 63 6b 20 3d 20 50  _global_lock = P
0da0: 54 48 52 45 41 44 5f 4d 55 54 45 58 5f 49 4e 49  THREAD_MUTEX_INI
0db0: 54 49 41 4c 49 5a 45 52 3b 0a 23 64 65 66 69 6e  TIALIZER;.#defin
0dc0: 65 20 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  e appfs_call_lib
0dd0: 74 63 6c 5f 65 6e 74 65 72 20 70 74 68 72 65 61  tcl_enter pthrea
0de0: 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70  d_mutex_lock(&ap
0df0: 70 66 73 5f 74 63 6c 5f 62 69 67 5f 67 6c 6f 62  pfs_tcl_big_glob
0e00: 61 6c 5f 6c 6f 63 6b 29 3b 0a 23 64 65 66 69 6e  al_lock);.#defin
0e10: 65 20 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  e appfs_call_lib
0e20: 74 63 6c 5f 65 78 69 74 20 70 74 68 72 65 61 64  tcl_exit pthread
0e30: 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61  _mutex_unlock(&a
0e40: 70 70 66 73 5f 74 63 6c 5f 62 69 67 5f 67 6c 6f  ppfs_tcl_big_glo
0e50: 62 61 6c 5f 6c 6f 63 6b 29 3b 0a 23 65 6c 73 65  bal_lock);.#else
0e60: 0a 23 64 65 66 69 6e 65 20 61 70 70 66 73 5f 63  .#define appfs_c
0e70: 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 6e 74 65 72  all_libtcl_enter
0e80: 20 2f 2a 2a 2f 0a 23 64 65 66 69 6e 65 20 61 70   /**/.#define ap
0e90: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f  pfs_call_libtcl_
0ea0: 65 78 69 74 20 2f 2a 2a 2f 0a 23 65 6e 64 69 66  exit /**/.#endif
0eb0: 0a 23 64 65 66 69 6e 65 20 61 70 70 66 73 5f 63  .#define appfs_c
0ec0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 78 2e 2e 2e 29  all_libtcl(x...)
0ed0: 20 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74   appfs_call_libt
0ee0: 63 6c 5f 65 6e 74 65 72 20 78 20 61 70 70 66 73  cl_enter x appfs
0ef0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69  _call_libtcl_exi
0f00: 74 0a 0a 2f 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20  t../*. * Global 
0f10: 76 61 72 69 61 62 6c 65 73 20 66 6f 72 20 41 70  variables for Ap
0f20: 70 46 53 20 54 63 6c 20 49 6e 74 65 72 70 72 65  pFS Tcl Interpre
0f30: 74 65 72 20 72 65 73 74 61 72 74 69 6e 67 0a 20  ter restarting. 
0f40: 2a 2f 0a 69 6e 74 20 69 6e 74 65 72 70 5f 72 65  */.int interp_re
0f50: 73 65 74 5f 6b 65 79 20 3d 20 30 3b 0a 0a 2f 2a  set_key = 0;../*
0f60: 0a 20 2a 20 41 70 70 46 53 20 50 61 74 68 20 54  . * AppFS Path T
0f70: 79 70 65 3a 20 20 44 65 73 63 72 69 62 65 73 20  ype:  Describes 
0f80: 74 68 65 20 74 79 70 65 20 6f 66 20 70 61 74 68  the type of path
0f90: 20 61 20 67 69 76 65 6e 20 66 69 6c 65 20 69 73   a given file is
0fa0: 0a 20 2a 2f 0a 74 79 70 65 64 65 66 20 65 6e 75  . */.typedef enu
0fb0: 6d 20 7b 0a 09 41 50 50 46 53 5f 50 41 54 48 54  m {..APPFS_PATHT
0fc0: 59 50 45 5f 49 4e 56 41 4c 49 44 2c 0a 09 41 50  YPE_INVALID,..AP
0fd0: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 4f 45  PFS_PATHTYPE_DOE
0fe0: 53 5f 4e 4f 54 5f 45 58 49 53 54 2c 0a 09 41 50  S_NOT_EXIST,..AP
0ff0: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49 4c  PFS_PATHTYPE_FIL
1000: 45 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59  E,..APPFS_PATHTY
1010: 50 45 5f 44 49 52 45 43 54 4f 52 59 2c 0a 09 41  PE_DIRECTORY,..A
1020: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59  PPFS_PATHTYPE_SY
1030: 4d 4c 49 4e 4b 2c 0a 09 41 50 50 46 53 5f 50 41  MLINK,..APPFS_PA
1040: 54 48 54 59 50 45 5f 53 4f 43 4b 45 54 2c 0a 09  THTYPE_SOCKET,..
1050: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46  APPFS_PATHTYPE_F
1060: 49 46 4f 2c 0a 7d 20 61 70 70 66 73 5f 70 61 74  IFO,.} appfs_pat
1070: 68 74 79 70 65 5f 74 3b 0a 0a 2f 2a 0a 20 2a 20  htype_t;../*. * 
1080: 41 70 70 46 53 20 50 61 74 68 20 49 6e 66 6f 72  AppFS Path Infor
1090: 6d 61 74 69 6f 6e 3a 0a 20 2a 20 20 20 20 20 20  mation:. *      
10a0: 20 20 20 43 6f 6d 70 6c 65 74 65 6c 79 20 64 65     Completely de
10b0: 73 63 72 69 62 65 73 20 61 20 73 70 65 63 69 66  scribes a specif
10c0: 69 63 20 70 61 74 68 2c 20 68 6f 77 20 69 74 20  ic path, how it 
10d0: 73 68 6f 75 6c 64 20 62 65 20 72 65 74 75 72 6e  should be return
10e0: 65 64 20 74 6f 0a 20 2a 20 20 20 20 20 20 20 20  ed to. *        
10f0: 20 74 6f 20 74 68 65 20 6b 65 72 6e 65 6c 0a 20   to the kernel. 
1100: 2a 2f 0a 73 74 72 75 63 74 20 61 70 70 66 73 5f  */.struct appfs_
1110: 70 61 74 68 69 6e 66 6f 20 7b 0a 09 61 70 70 66  pathinfo {..appf
1120: 73 5f 70 61 74 68 74 79 70 65 5f 74 20 74 79 70  s_pathtype_t typ
1130: 65 3b 0a 09 74 69 6d 65 5f 74 20 74 69 6d 65 3b  e;..time_t time;
1140: 0a 09 63 68 61 72 20 68 6f 73 74 6e 61 6d 65 5b  ..char hostname[
1150: 32 35 36 5d 3b 0a 09 69 6e 74 20 70 61 63 6b 61  256];..int packa
1160: 67 65 64 3b 0a 09 75 6e 73 69 67 6e 65 64 20 6c  ged;..unsigned l
1170: 6f 6e 67 20 6c 6f 6e 67 20 69 6e 6f 64 65 3b 0a  ong long inode;.
1180: 09 75 6e 69 6f 6e 20 7b 0a 09 09 73 74 72 75 63  .union {...struc
1190: 74 20 7b 0a 09 09 09 69 6e 74 20 63 68 69 6c 64  t {....int child
11a0: 63 6f 75 6e 74 3b 0a 09 09 7d 20 64 69 72 3b 0a  count;...} dir;.
11b0: 09 09 73 74 72 75 63 74 20 7b 0a 09 09 09 69 6e  ..struct {....in
11c0: 74 20 65 78 65 63 75 74 61 62 6c 65 3b 0a 09 09  t executable;...
11d0: 09 69 6e 74 20 73 75 69 64 52 6f 6f 74 3b 0a 09  .int suidRoot;..
11e0: 09 09 69 6e 74 20 77 6f 72 6c 64 61 63 63 65 73  ..int worldacces
11f0: 73 69 62 6c 65 3b 0a 09 09 09 6f 66 66 5f 74 20  sible;....off_t 
1200: 73 69 7a 65 3b 0a 09 09 7d 20 66 69 6c 65 3b 0a  size;...} file;.
1210: 09 09 73 74 72 75 63 74 20 7b 0a 09 09 09 6f 66  ..struct {....of
1220: 66 5f 74 20 73 69 7a 65 3b 0a 09 09 09 63 68 61  f_t size;....cha
1230: 72 20 73 6f 75 72 63 65 5b 32 35 36 5d 3b 0a 09  r source[256];..
1240: 09 7d 20 73 79 6d 6c 69 6e 6b 3b 0a 09 7d 20 74  .} symlink;..} t
1250: 79 70 65 69 6e 66 6f 3b 0a 0a 09 2f 2a 20 41 74  ypeinfo;.../* At
1260: 74 72 69 62 75 74 65 73 20 75 73 65 64 20 6f 6e  tributes used on
1270: 6c 79 20 66 6f 72 20 63 61 63 68 69 6e 67 20 65  ly for caching e
1280: 6e 74 72 69 65 73 20 2a 2f 0a 09 63 68 61 72 20  ntries */..char 
1290: 2a 5f 63 61 63 68 65 5f 70 61 74 68 3b 0a 09 75  *_cache_path;..u
12a0: 69 64 5f 74 20 5f 63 61 63 68 65 5f 75 69 64 3b  id_t _cache_uid;
12b0: 0a 7d 3b 0a 0a 2f 2a 0a 20 2a 20 43 72 65 61 74  .};../*. * Creat
12c0: 65 20 61 20 6e 65 77 20 54 63 6c 20 69 6e 74 65  e a new Tcl inte
12d0: 72 70 72 65 74 65 72 20 61 6e 64 20 63 6f 6d 70  rpreter and comp
12e0: 6c 65 74 65 6c 79 20 69 6e 69 74 69 61 6c 69 7a  letely initializ
12f0: 65 20 69 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20  e it. */.static 
1300: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70 66  Tcl_Interp *appf
1310: 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65  s_create_TclInte
1320: 72 70 28 63 68 61 72 20 2a 2a 65 72 72 6f 72 5f  rp(char **error_
1330: 73 74 72 69 6e 67 29 20 7b 0a 09 54 63 6c 5f 49  string) {..Tcl_I
1340: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09  nterp *interp;..
1350: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 09 63 6f  int tcl_ret;..co
1360: 6e 73 74 20 63 68 61 72 20 2a 74 63 6c 5f 73 65  nst char *tcl_se
1370: 74 76 61 72 5f 72 65 74 3b 0a 0a 09 41 50 50 46  tvar_ret;...APPF
1380: 53 5f 44 45 42 55 47 28 22 43 72 65 61 74 69 6e  S_DEBUG("Creatin
1390: 67 20 6e 65 77 20 54 63 6c 20 69 6e 74 65 72 70  g new Tcl interp
13a0: 72 65 74 65 72 20 66 6f 72 20 54 49 44 20 3d 20  reter for TID = 
13b0: 30 78 25 6c 6c 78 22 2c 20 28 75 6e 73 69 67 6e  0x%llx", (unsign
13c0: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 70 74  ed long long) pt
13d0: 68 72 65 61 64 5f 73 65 6c 66 28 29 29 3b 0a 0a  hread_self());..
13e0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
13f0: 63 6c 28 0a 09 09 69 6e 74 65 72 70 20 3d 20 54  cl(...interp = T
1400: 63 6c 5f 43 72 65 61 74 65 49 6e 74 65 72 70 28  cl_CreateInterp(
1410: 29 3b 0a 09 29 0a 09 69 66 20 28 69 6e 74 65 72  );..)..if (inter
1420: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41  p == NULL) {...A
1430: 50 50 46 53 5f 45 52 52 4f 52 28 22 55 6e 61 62  PPFS_ERROR("Unab
1440: 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54 63 6c  le to create Tcl
1450: 20 49 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41   Interpreter.  A
1460: 62 6f 72 74 69 6e 67 2e 22 29 3b 0a 0a 09 09 69  borting.");....i
1470: 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29  f (error_string)
1480: 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73 74 72   {....*error_str
1490: 69 6e 67 20 3d 20 73 74 72 64 75 70 28 22 55 6e  ing = strdup("Un
14a0: 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54  able to create T
14b0: 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22  cl interpreter."
14c0: 29 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 75 72 6e  );...}....return
14d0: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70  (NULL);..}...app
14e0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
14f0: 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65  cl_Preserve(inte
1500: 72 70 29 3b 29 0a 0a 09 61 70 70 66 73 5f 63 61  rp);)...appfs_ca
1510: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c  ll_libtcl(...tcl
1520: 5f 72 65 74 20 3d 20 54 63 6c 5f 49 6e 69 74 28  _ret = Tcl_Init(
1530: 69 6e 74 65 72 70 29 3b 0a 09 29 0a 09 69 66 20  interp);..)..if 
1540: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
1550: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 45 52  OK) {...APPFS_ER
1560: 52 4f 52 28 22 55 6e 61 62 6c 65 20 74 6f 20 69  ROR("Unable to i
1570: 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 2e 20 20  nitialize Tcl.  
1580: 41 62 6f 72 74 69 6e 67 2e 22 29 3b 0a 09 09 61  Aborting.");...a
1590: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
15a0: 28 0a 09 09 09 41 50 50 46 53 5f 45 52 52 4f 52  (....APPFS_ERROR
15b0: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20  ("Tcl Error is: 
15c0: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  %s", Tcl_GetStri
15d0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
15e0: 29 3b 0a 09 09 29 0a 0a 09 09 69 66 20 28 65 72  );...)....if (er
15f0: 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09  ror_string) {...
1600: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
1610: 63 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73  cl(.....*error_s
1620: 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54  tring = strdup(T
1630: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
1640: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09  lt(interp));....
1650: 29 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63  )...}....appfs_c
1660: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
1670: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
1680: 0a 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
1690: 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c  "Terminating Tcl
16a0: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b   interpreter.");
16b0: 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
16c0: 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65  ibtcl(Tcl_Delete
16d0: 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29  Interp(interp);)
16e0: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
16f0: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
1700: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f  l_libtcl(...tcl_
1710: 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69  ret = Tcl_Eval(i
1720: 6e 74 65 72 70 2c 20 22 70 61 63 6b 61 67 65 20  nterp, "package 
1730: 69 66 6e 65 65 64 65 64 20 73 68 61 31 20 31 2e  ifneeded sha1 1.
1740: 30 20 5b 6c 69 73 74 20 6c 6f 61 64 20 7b 7d 20  0 [list load {} 
1750: 73 68 61 31 5d 22 29 3b 0a 09 29 0a 09 69 66 20  sha1]");..)..if 
1760: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
1770: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 45 52  OK) {...APPFS_ER
1780: 52 4f 52 28 22 55 6e 61 62 6c 65 20 74 6f 20 69  ROR("Unable to i
1790: 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 53 48  nitialize Tcl SH
17a0: 41 31 2e 20 20 41 62 6f 72 74 69 6e 67 2e 22 29  A1.  Aborting.")
17b0: 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ;...appfs_call_l
17c0: 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f  ibtcl(....APPFS_
17d0: 45 52 52 4f 52 28 22 54 63 6c 20 45 72 72 6f 72  ERROR("Tcl Error
17e0: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
17f0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
1800: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69  terp));...)....i
1810: 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29  f (error_string)
1820: 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c   {....appfs_call
1830: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72  _libtcl(.....*er
1840: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
1850: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
1860: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
1870: 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70  ;....)...}....ap
1880: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
1890: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
18a0: 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44  rp);)....APPFS_D
18b0: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
18c0: 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  g Tcl interprete
18d0: 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63  r.");....appfs_c
18e0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44  all_libtcl(Tcl_D
18f0: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65  eleteInterp(inte
1900: 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28  rp);)....return(
1910: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  NULL);..}...appf
1920: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
1930: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45  .tcl_ret = Tcl_E
1940: 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 70 61 63  val(interp, "pac
1950: 6b 61 67 65 20 69 66 6e 65 65 64 65 64 20 61 70  kage ifneeded ap
1960: 70 66 73 64 20 31 2e 30 20 5b 6c 69 73 74 20 6c  pfsd 1.0 [list l
1970: 6f 61 64 20 7b 7d 20 61 70 70 66 73 64 5d 22 29  oad {} appfsd]")
1980: 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65  ;..)..if (tcl_re
1990: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
19a0: 09 41 50 50 46 53 5f 45 52 52 4f 52 28 22 55 6e  .APPFS_ERROR("Un
19b0: 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69  able to initiali
19c0: 7a 65 20 54 63 6c 20 41 70 70 46 53 20 50 61 63  ze Tcl AppFS Pac
19d0: 6b 61 67 65 2e 20 20 41 62 6f 72 74 69 6e 67 2e  kage.  Aborting.
19e0: 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  ");...appfs_call
19f0: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46  _libtcl(....APPF
1a00: 53 5f 45 52 52 4f 52 28 22 54 63 6c 20 45 72 72  S_ERROR("Tcl Err
1a10: 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f  or is: %s", Tcl_
1a20: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
1a30: 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09  interp));...)...
1a40: 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e  .if (error_strin
1a50: 67 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61  g) {....appfs_ca
1a60: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a  ll_libtcl(.....*
1a70: 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73  error_string = s
1a80: 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72  trdup(Tcl_GetStr
1a90: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
1aa0: 29 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09  ));....)...}....
1ab0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
1ac0: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
1ad0: 74 65 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53  terp);)....APPFS
1ae0: 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74  _DEBUG("Terminat
1af0: 69 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65  ing Tcl interpre
1b00: 74 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73  ter.");....appfs
1b10: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
1b20: 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e  _DeleteInterp(in
1b30: 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72  terp);)....retur
1b40: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a  n(NULL);..}.../*
1b50: 0a 09 20 2a 20 4c 6f 61 64 20 22 70 6b 69 2e 74  .. * Load "pki.t
1b60: 63 6c 22 20 69 6e 20 74 68 65 20 73 61 6d 65 20  cl" in the same 
1b70: 77 61 79 20 61 73 20 61 70 70 66 73 64 2e 74 63  way as appfsd.tc
1b80: 6c 20 28 73 65 65 20 62 65 6c 6f 77 29 0a 09 20  l (see below).. 
1b90: 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  */..appfs_call_l
1ba0: 69 62 74 63 6c 5f 65 6e 74 65 72 0a 09 09 74 63  ibtcl_enter...tc
1bb0: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c  l_ret = Tcl_Eval
1bc0: 28 69 6e 74 65 72 70 2c 20 22 22 0a 23 69 6e 63  (interp, "".#inc
1bd0: 6c 75 64 65 20 22 70 6b 69 2e 74 63 6c 2e 68 22  lude "pki.tcl.h"
1be0: 0a 09 09 22 22 29 3b 0a 09 61 70 70 66 73 5f 63  ..."");..appfs_c
1bf0: 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74 0a  all_libtcl_exit.
1c00: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
1c10: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
1c20: 53 5f 45 52 52 4f 52 28 22 55 6e 61 62 6c 65 20  S_ERROR("Unable 
1c30: 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63  to initialize Tc
1c40: 6c 20 50 4b 49 2e 20 20 41 62 6f 72 74 69 6e 67  l PKI.  Aborting
1c50: 2e 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c  .");...appfs_cal
1c60: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50  l_libtcl(....APP
1c70: 46 53 5f 45 52 52 4f 52 28 22 54 63 6c 20 45 72  FS_ERROR("Tcl Er
1c80: 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c  ror is: %s", Tcl
1c90: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
1ca0: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a  (interp));...)..
1cb0: 09 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69  ..if (error_stri
1cc0: 6e 67 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63  ng) {....appfs_c
1cd0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09  all_libtcl(.....
1ce0: 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20  *error_string = 
1cf0: 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74  strdup(Tcl_GetSt
1d00: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
1d10: 70 29 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09  p));....)...}...
1d20: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
1d30: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
1d40: 6e 74 65 72 70 29 3b 29 0a 0a 09 09 41 50 50 46  nterp);)....APPF
1d50: 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61  S_DEBUG("Termina
1d60: 74 69 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72  ting Tcl interpr
1d70: 65 74 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66  eter.");....appf
1d80: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
1d90: 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69  l_DeleteInterp(i
1da0: 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75  nterp);)....retu
1db0: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f  rn(NULL);..}.../
1dc0: 2a 0a 09 20 2a 20 4c 6f 61 64 20 74 68 65 20 22  *.. * Load the "
1dd0: 61 70 70 66 73 64 2e 74 63 6c 22 20 73 63 72 69  appfsd.tcl" scri
1de0: 70 74 2c 20 77 68 69 63 68 20 69 73 20 22 63 6f  pt, which is "co
1df0: 6d 70 69 6c 65 64 22 20 69 6e 74 6f 20 61 20 43  mpiled" into a C
1e00: 20 68 65 61 64 65 72 0a 09 20 2a 20 73 6f 20 74   header.. * so t
1e10: 68 61 74 20 69 74 20 64 6f 65 73 20 6e 6f 74 20  hat it does not 
1e20: 6e 65 65 64 20 74 6f 20 65 78 69 73 74 20 6f 6e  need to exist on
1e30: 20 74 68 65 20 66 69 6c 65 73 79 73 74 65 6d 20   the filesystem 
1e40: 61 6e 64 20 63 61 6e 20 62 65 0a 09 20 2a 20 64  and can be.. * d
1e50: 69 72 65 63 74 6c 79 20 65 76 61 6c 75 61 74 65  irectly evaluate
1e60: 64 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63  d... */..appfs_c
1e70: 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 6e 74 65 72  all_libtcl_enter
1e80: 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
1e90: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 22  _Eval(interp, ""
1ea0: 0a 23 69 6e 63 6c 75 64 65 20 22 61 70 70 66 73  .#include "appfs
1eb0: 64 2e 74 63 6c 2e 68 22 0a 09 09 22 22 29 3b 0a  d.tcl.h"..."");.
1ec0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
1ed0: 63 6c 5f 65 78 69 74 0a 09 69 66 20 28 74 63 6c  cl_exit..if (tcl
1ee0: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  _ret != TCL_OK) 
1ef0: 7b 0a 09 09 41 50 50 46 53 5f 45 52 52 4f 52 28  {...APPFS_ERROR(
1f00: 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69  "Unable to initi
1f10: 61 6c 69 7a 65 20 54 63 6c 20 41 70 70 46 53 20  alize Tcl AppFS 
1f20: 73 63 72 69 70 74 2e 20 20 41 62 6f 72 74 69 6e  script.  Abortin
1f30: 67 2e 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61  g.");...appfs_ca
1f40: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50  ll_libtcl(....AP
1f50: 50 46 53 5f 45 52 52 4f 52 28 22 54 63 6c 20 45  PFS_ERROR("Tcl E
1f60: 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63  rror is: %s", Tc
1f70: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
1f80: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a  t(interp));...).
1f90: 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72  ...if (error_str
1fa0: 69 6e 67 29 20 7b 0a 09 09 09 61 70 70 66 73 5f  ing) {....appfs_
1fb0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
1fc0: 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d  .*error_string =
1fd0: 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53   strdup(Tcl_GetS
1fe0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
1ff0: 72 70 29 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a  rp));....)...}..
2000: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
2010: 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28  tcl(Tcl_Release(
2020: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 41 50 50  interp);)....APP
2030: 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e  FS_DEBUG("Termin
2040: 61 74 69 6e 67 20 54 63 6c 20 69 6e 74 65 72 70  ating Tcl interp
2050: 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70  reter.");....app
2060: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
2070: 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28  cl_DeleteInterp(
2080: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74  interp);)....ret
2090: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
20a0: 2f 2a 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62 61  /*.. * Set globa
20b0: 6c 20 76 61 72 69 61 62 6c 65 73 20 66 72 6f 6d  l variables from
20c0: 20 43 20 74 6f 20 54 63 6c 0a 09 20 2a 2f 0a 09   C to Tcl.. */..
20d0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
20e0: 6c 28 0a 09 09 74 63 6c 5f 73 65 74 76 61 72 5f  l(...tcl_setvar_
20f0: 72 65 74 20 3d 20 54 63 6c 5f 53 65 74 56 61 72  ret = Tcl_SetVar
2100: 28 69 6e 74 65 72 70 2c 20 22 3a 3a 61 70 70 66  (interp, "::appf
2110: 73 3a 3a 63 61 63 68 65 64 69 72 22 2c 20 61 70  s::cachedir", ap
2120: 70 66 73 5f 63 61 63 68 65 64 69 72 2c 20 54 43  pfs_cachedir, TC
2130: 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 3b 0a  L_GLOBAL_ONLY);.
2140: 09 29 0a 09 69 66 20 28 74 63 6c 5f 73 65 74 76  .)..if (tcl_setv
2150: 61 72 5f 72 65 74 20 3d 3d 20 4e 55 4c 4c 29 20  ar_ret == NULL) 
2160: 7b 0a 09 09 41 50 50 46 53 5f 45 52 52 4f 52 28  {...APPFS_ERROR(
2170: 22 55 6e 61 62 6c 65 20 74 6f 20 73 65 74 20 63  "Unable to set c
2180: 61 63 68 65 20 64 69 72 65 63 74 6f 72 79 2e 20  ache directory. 
2190: 20 54 68 69 73 20 73 68 6f 75 6c 64 20 6e 65 76   This should nev
21a0: 65 72 20 66 61 69 6c 2e 22 29 3b 0a 0a 09 09 69  er fail.");....i
21b0: 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29  f (error_string)
21c0: 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c   {....appfs_call
21d0: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72  _libtcl(.....*er
21e0: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
21f0: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
2200: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
2210: 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70  ;....)...}....ap
2220: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
2230: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
2240: 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44  rp);)....APPFS_D
2250: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
2260: 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  g Tcl interprete
2270: 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63  r.");....appfs_c
2280: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44  all_libtcl(Tcl_D
2290: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65  eleteInterp(inte
22a0: 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28  rp);)....return(
22b0: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  NULL);..}.../*..
22c0: 20 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68   * Initialize th
22d0: 65 20 22 61 70 70 66 73 64 2e 74 63 6c 22 20 65  e "appfsd.tcl" e
22e0: 6e 76 69 72 6f 6e 6d 65 6e 74 2c 20 77 68 69 63  nvironment, whic
22f0: 68 20 6d 75 73 74 20 62 65 20 64 6f 6e 65 20 61  h must be done a
2300: 66 74 65 72 0a 09 20 2a 20 67 6c 6f 62 61 6c 20  fter.. * global 
2310: 76 61 72 69 61 62 6c 65 73 20 61 72 65 20 73 65  variables are se
2320: 74 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63  t... */..appfs_c
2330: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63  all_libtcl(...tc
2340: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c  l_ret = Tcl_Eval
2350: 28 69 6e 74 65 72 70 2c 20 22 3a 3a 61 70 70 66  (interp, "::appf
2360: 73 3a 3a 69 6e 69 74 22 29 3b 0a 09 29 0a 09 69  s::init");..)..i
2370: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
2380: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
2390: 45 52 52 4f 52 28 22 55 6e 61 62 6c 65 20 74 6f  ERROR("Unable to
23a0: 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20   initialize Tcl 
23b0: 41 70 70 46 53 20 73 63 72 69 70 74 20 28 3a 3a  AppFS script (::
23c0: 61 70 70 66 73 3a 3a 69 6e 69 74 29 2e 20 20 41  appfs::init).  A
23d0: 62 6f 72 74 69 6e 67 2e 22 29 3b 0a 09 09 61 70  borting.");...ap
23e0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
23f0: 0a 09 09 09 41 50 50 46 53 5f 45 52 52 4f 52 28  ....APPFS_ERROR(
2400: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
2410: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
2420: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
2430: 3b 0a 09 09 29 0a 0a 09 09 69 66 20 28 65 72 72  ;...)....if (err
2440: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09  or_string) {....
2450: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
2460: 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74  l(.....*error_st
2470: 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63  ring = strdup(Tc
2480: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
2490: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29  t(interp));....)
24a0: 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61  ...}....appfs_ca
24b0: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
24c0: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
24d0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
24e0: 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20  Terminating Tcl 
24f0: 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a  interpreter.");.
2500: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
2510: 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49  btcl(Tcl_DeleteI
2520: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a  nterp(interp);).
2530: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
2540: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 48 69 64  ..}.../*.. * Hid
2550: 65 20 73 6f 6d 65 20 54 63 6c 20 63 6f 6d 6d 61  e some Tcl comma
2560: 6e 64 73 20 74 68 61 74 20 77 65 20 64 6f 20 6e  nds that we do n
2570: 6f 74 20 63 61 72 65 20 74 6f 20 75 73 65 20 61  ot care to use a
2580: 6e 64 20 77 68 69 63 68 20 6d 61 79 0a 09 20 2a  nd which may.. *
2590: 20 73 6c 6f 77 20 64 6f 77 6e 20 72 75 6e 2d 74   slow down run-t
25a0: 69 6d 65 20 6f 70 65 72 61 74 69 6f 6e 73 2e 0a  ime operations..
25b0: 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c  . */..appfs_call
25c0: 5f 6c 69 62 74 63 6c 28 0a 09 09 54 63 6c 5f 48  _libtcl(...Tcl_H
25d0: 69 64 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ideCommand(inter
25e0: 70 2c 20 22 61 75 74 6f 5f 6c 6f 61 64 5f 69 6e  p, "auto_load_in
25f0: 64 65 78 22 2c 20 22 61 75 74 6f 5f 6c 6f 61 64  dex", "auto_load
2600: 5f 69 6e 64 65 78 22 29 3b 0a 09 09 54 63 6c 5f  _index");...Tcl_
2610: 48 69 64 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  HideCommand(inte
2620: 72 70 2c 20 22 75 6e 6b 6e 6f 77 6e 22 2c 20 22  rp, "unknown", "
2630: 75 6e 6b 6e 6f 77 6e 22 29 3b 0a 09 09 54 63 6c  unknown");...Tcl
2640: 5f 48 69 64 65 43 6f 6d 6d 61 6e 64 28 69 6e 74  _HideCommand(int
2650: 65 72 70 2c 20 22 65 78 69 74 22 2c 20 22 65 78  erp, "exit", "ex
2660: 69 74 22 29 3b 0a 09 29 0a 0a 09 2f 2a 0a 09 20  it");..).../*.. 
2670: 2a 20 52 65 6c 65 61 73 65 20 74 68 65 20 68 6f  * Release the ho
2680: 6c 64 20 77 65 20 68 61 76 65 20 6f 6e 20 74 68  ld we have on th
2690: 65 20 69 6e 74 65 72 70 72 65 74 65 72 20 73 6f  e interpreter so
26a0: 20 74 68 61 74 20 69 74 20 6d 61 79 20 62 65 0a   that it may be.
26b0: 09 20 2a 20 64 65 6c 65 74 65 64 20 69 66 20 6e  . * deleted if n
26c0: 65 65 64 65 64 0a 09 20 2a 2f 0a 09 61 70 70 66  eeded.. */..appf
26d0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
26e0: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
26f0: 29 3b 29 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 74  );).../*.. * Ret
2700: 75 72 6e 20 74 68 65 20 63 6f 6d 70 6c 65 74 65  urn the complete
2710: 6c 79 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 69  ly initialized i
2720: 6e 74 65 72 70 72 65 74 65 72 0a 09 20 2a 2f 0a  nterpreter.. */.
2730: 09 72 65 74 75 72 6e 28 69 6e 74 65 72 70 29 3b  .return(interp);
2740: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 52 65 74 75 72 6e  .}../*. * Return
2750: 20 74 68 65 20 74 68 72 65 61 64 2d 73 70 65 63   the thread-spec
2760: 69 66 69 63 20 54 63 6c 20 69 6e 74 65 72 70 72  ific Tcl interpr
2770: 65 74 65 72 2c 20 63 72 65 61 74 69 6e 67 20 69  eter, creating i
2780: 74 20 69 66 20 6e 65 65 64 65 64 0a 20 2a 2f 0a  t if needed. */.
2790: 73 74 61 74 69 63 20 54 63 6c 5f 49 6e 74 65 72  static Tcl_Inter
27a0: 70 20 2a 61 70 70 66 73 5f 54 63 6c 49 6e 74 65  p *appfs_TclInte
27b0: 72 70 28 76 6f 69 64 29 20 7b 0a 09 54 63 6c 5f  rp(void) {..Tcl_
27c0: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
27d0: 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74  .int pthread_ret
27e0: 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65  ;..static __thre
27f0: 61 64 20 69 6e 74 20 74 68 72 65 61 64 5f 69 6e  ad int thread_in
2800: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d  terp_reset_key =
2810: 20 30 3b 0a 09 69 6e 74 20 67 6c 6f 62 61 6c 5f   0;..int global_
2820: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
2830: 3b 0a 0a 09 67 6c 6f 62 61 6c 5f 69 6e 74 65 72  ;...global_inter
2840: 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 5f 5f  p_reset_key = __
2850: 73 79 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 61  sync_fetch_and_a
2860: 64 64 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74  dd(&interp_reset
2870: 5f 6b 65 79 2c 20 30 29 3b 0a 0a 09 69 6e 74 65  _key, 0);...inte
2880: 72 70 20 3d 20 70 74 68 72 65 61 64 5f 67 65 74  rp = pthread_get
2890: 73 70 65 63 69 66 69 63 28 69 6e 74 65 72 70 4b  specific(interpK
28a0: 65 79 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  ey);..if (interp
28b0: 20 21 3d 20 4e 55 4c 4c 20 26 26 20 74 68 72 65   != NULL && thre
28c0: 61 64 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  ad_interp_reset_
28d0: 6b 65 79 20 21 3d 20 67 6c 6f 62 61 6c 5f 69 6e  key != global_in
28e0: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 29 20  terp_reset_key) 
28f0: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
2900: 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 6f 6c 64  "Terminating old
2910: 20 69 6e 74 65 72 70 72 65 74 65 72 20 61 6e 64   interpreter and
2920: 20 72 65 73 74 61 72 74 69 6e 67 20 64 75 65 20   restarting due 
2930: 74 6f 20 72 65 73 65 74 20 72 65 71 75 65 73 74  to reset request
2940: 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61  .");....appfs_ca
2950: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65  ll_libtcl(Tcl_De
2960: 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72  leteInterp(inter
2970: 70 29 3b 29 0a 0a 09 09 69 6e 74 65 72 70 20 3d  p);)....interp =
2980: 20 4e 55 4c 4c 3b 0a 0a 09 09 70 74 68 72 65 61   NULL;....pthrea
2990: 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f  d_ret = pthread_
29a0: 73 65 74 73 70 65 63 69 66 69 63 28 69 6e 74 65  setspecific(inte
29b0: 72 70 4b 65 79 2c 20 69 6e 74 65 72 70 29 3b 0a  rpKey, interp);.
29c0: 09 7d 0a 0a 09 69 66 20 28 67 6c 6f 62 61 6c 5f  .}...if (global_
29d0: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
29e0: 20 3d 3d 20 2d 31 29 20 7b 0a 09 09 41 50 50 46   == -1) {...APPF
29f0: 53 5f 44 45 42 55 47 28 22 52 65 74 75 72 6e 69  S_DEBUG("Returni
2a00: 6e 67 20 4e 55 4c 4c 20 73 69 6e 63 65 20 77 65  ng NULL since we
2a10: 20 61 72 65 20 69 6e 20 74 68 65 20 70 72 6f 63   are in the proc
2a20: 65 73 73 20 6f 66 20 74 65 72 6d 69 6e 61 74 69  ess of terminati
2a30: 6e 67 20 61 6c 6c 20 74 68 72 65 61 64 73 2e 22  ng all threads."
2a40: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  );....return(NUL
2a50: 4c 29 3b 0a 09 7d 0a 0a 09 74 68 72 65 61 64 5f  L);..}...thread_
2a60: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
2a70: 20 3d 20 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70   = global_interp
2a80: 5f 72 65 73 65 74 5f 6b 65 79 3b 0a 0a 09 69 66  _reset_key;...if
2a90: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
2aa0: 29 20 7b 0a 09 09 69 6e 74 65 72 70 20 3d 20 61  ) {...interp = a
2ab0: 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49  ppfs_create_TclI
2ac0: 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 0a 09 09  nterp(NULL);....
2ad0: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
2ae0: 4c 4c 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44  LL) {....APPFS_D
2af0: 45 42 55 47 28 22 43 72 65 61 74 65 20 69 6e 74  EBUG("Create int
2b00: 65 72 70 20 66 61 69 6c 65 64 2c 20 72 65 74 75  erp failed, retu
2b10: 72 6e 69 6e 67 20 69 6e 20 66 61 69 6c 75 72 65  rning in failure
2b20: 2e 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28  .");.....return(
2b30: 4e 55 4c 4c 29 3b 0a 09 09 7d 0a 0a 09 09 70 74  NULL);...}....pt
2b40: 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72  hread_ret = pthr
2b50: 65 61 64 5f 73 65 74 73 70 65 63 69 66 69 63 28  ead_setspecific(
2b60: 69 6e 74 65 72 70 4b 65 79 2c 20 69 6e 74 65 72  interpKey, inter
2b70: 70 29 3b 0a 09 09 69 66 20 28 70 74 68 72 65 61  p);...if (pthrea
2b80: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
2b90: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 70 74  .APPFS_DEBUG("pt
2ba0: 68 72 65 61 64 5f 73 65 74 73 70 65 63 69 66 69  hread_setspecifi
2bb0: 63 28 29 20 66 61 69 6c 65 64 2e 20 20 54 65 72  c() failed.  Ter
2bc0: 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e 74  minating Tcl int
2bd0: 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09  erpreter.");....
2be0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
2bf0: 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74  cl(Tcl_DeleteInt
2c00: 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  erp(interp);)...
2c10: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
2c20: 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  ..}..}...return(
2c30: 69 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20  interp);.}../*. 
2c40: 2a 20 45 76 61 6c 75 61 74 65 20 61 20 54 63 6c  * Evaluate a Tcl
2c50: 20 73 63 72 69 70 74 20 63 6f 6e 73 74 72 75 63   script construc
2c60: 74 65 64 20 62 79 20 63 6f 6e 63 61 74 65 6e 61  ted by concatena
2c70: 74 69 6e 67 20 61 20 62 75 6e 63 68 20 6f 66 20  ting a bunch of 
2c80: 43 20 73 74 72 69 6e 67 73 0a 20 2a 20 74 6f 67  C strings. * tog
2c90: 65 74 68 65 72 2e 0a 20 2a 2f 0a 73 74 61 74 69  ether.. */.stati
2ca0: 63 20 69 6e 74 20 61 70 70 66 73 5f 54 63 6c 5f  c int appfs_Tcl_
2cb0: 45 76 61 6c 28 54 63 6c 5f 49 6e 74 65 72 70 20  Eval(Tcl_Interp 
2cc0: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a  *interp, int obj
2cd0: 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63  c, const char *c
2ce0: 6d 64 2c 20 2e 2e 2e 29 20 7b 0a 09 54 63 6c 5f  md, ...) {..Tcl_
2cf0: 4f 62 6a 20 2a 2a 6f 62 6a 76 3b 0a 09 63 6f 6e  Obj **objv;..con
2d00: 73 74 20 63 68 61 72 20 2a 61 72 67 3b 0a 09 76  st char *arg;..v
2d10: 61 5f 6c 69 73 74 20 61 72 67 70 3b 0a 09 69 6e  a_list argp;..in
2d20: 74 20 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20 69  t retval;..int i
2d30: 3b 0a 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  ;...if (interp =
2d40: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46  = NULL) {...APPF
2d50: 53 5f 44 45 42 55 47 28 22 49 6e 76 61 6c 69 64  S_DEBUG("Invalid
2d60: 20 69 6e 74 65 72 70 72 65 74 65 72 20 70 61 73   interpreter pas
2d70: 73 65 64 20 69 6e 2c 20 72 65 74 75 72 6e 69 6e  sed in, returnin
2d80: 67 20 69 6e 20 66 61 69 6c 75 72 65 2e 22 29 3b  g in failure.");
2d90: 0a 0a 09 09 72 65 74 75 72 6e 28 54 43 4c 5f 45  ....return(TCL_E
2da0: 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09 6f 62 6a 76  RROR);..}...objv
2db0: 20 3d 20 28 76 6f 69 64 20 2a 29 20 63 6b 61 6c   = (void *) ckal
2dc0: 6c 6f 63 28 73 69 7a 65 6f 66 28 2a 6f 62 6a 76  loc(sizeof(*objv
2dd0: 29 20 2a 20 6f 62 6a 63 29 3b 0a 0a 09 61 70 70  ) * objc);...app
2de0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
2df0: 09 09 6f 62 6a 76 5b 30 5d 20 3d 20 54 63 6c 5f  ..objv[0] = Tcl_
2e00: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 63 6d 64  NewStringObj(cmd
2e10: 2c 20 2d 31 29 3b 0a 0a 09 09 54 63 6c 5f 49 6e  , -1);....Tcl_In
2e20: 63 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76 5b  crRefCount(objv[
2e30: 30 5d 29 3b 0a 0a 09 09 76 61 5f 73 74 61 72 74  0]);....va_start
2e40: 28 61 72 67 70 2c 20 63 6d 64 29 3b 0a 09 09 66  (argp, cmd);...f
2e50: 6f 72 20 28 69 20 3d 20 31 3b 20 69 20 3c 20 6f  or (i = 1; i < o
2e60: 62 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09 09 09 61  bjc; i++) {....a
2e70: 72 67 20 3d 20 76 61 5f 61 72 67 28 61 72 67 70  rg = va_arg(argp
2e80: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 29 3b  , const char *);
2e90: 0a 0a 09 09 09 6f 62 6a 76 5b 69 5d 20 3d 20 54  .....objv[i] = T
2ea0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
2eb0: 61 72 67 2c 20 2d 31 29 3b 0a 0a 09 09 09 54 63  arg, -1);.....Tc
2ec0: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 6f  l_IncrRefCount(o
2ed0: 62 6a 76 5b 69 5d 29 3b 0a 09 09 7d 0a 09 09 76  bjv[i]);...}...v
2ee0: 61 5f 65 6e 64 28 61 72 67 70 29 3b 0a 09 29 0a  a_end(argp);..).
2ef0: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
2f00: 74 63 6c 28 0a 09 09 72 65 74 76 61 6c 20 3d 20  tcl(...retval = 
2f10: 54 63 6c 5f 45 76 61 6c 4f 62 6a 76 28 69 6e 74  Tcl_EvalObjv(int
2f20: 65 72 70 2c 20 6f 62 6a 63 2c 20 6f 62 6a 76 2c  erp, objc, objv,
2f30: 20 30 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f   0);..)...appfs_
2f40: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 66  call_libtcl(...f
2f50: 6f 72 20 28 69 20 3d 20 30 3b 20 69 20 3c 20 6f  or (i = 0; i < o
2f60: 62 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09 09 09 54  bjc; i++) {....T
2f70: 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28  cl_DecrRefCount(
2f80: 6f 62 6a 76 5b 69 5d 29 3b 0a 09 09 7d 0a 09 29  objv[i]);...}..)
2f90: 0a 0a 09 63 6b 66 72 65 65 28 28 76 6f 69 64 20  ...ckfree((void 
2fa0: 2a 29 20 6f 62 6a 76 29 3b 0a 0a 09 69 66 20 28  *) objv);...if (
2fb0: 72 65 74 76 61 6c 20 21 3d 20 54 43 4c 5f 4f 4b  retval != TCL_OK
2fc0: 29 20 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  ) {...appfs_call
2fd0: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46  _libtcl(....APPF
2fe0: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 63 6f 6d  S_DEBUG("Tcl com
2ff0: 6d 61 6e 64 20 66 61 69 6c 65 64 2c 20 3a 3a 65  mand failed, ::e
3000: 72 72 6f 72 49 6e 66 6f 20 63 6f 6e 74 61 69 6e  rrorInfo contain
3010: 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65  s: %s\n", Tcl_Ge
3020: 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 3a 3a  tVar(interp, "::
3030: 65 72 72 6f 72 49 6e 66 6f 22 2c 20 30 29 29 3b  errorInfo", 0));
3040: 0a 09 09 29 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  ...)..}...return
3050: 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a  (retval);.}../*.
3060: 20 2a 20 52 65 71 75 65 73 74 20 61 6c 6c 20 54   * Request all T
3070: 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 73 20  cl interpreters 
3080: 72 65 73 74 61 72 74 0a 20 2a 2f 0a 73 74 61 74  restart. */.stat
3090: 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 74 63  ic void appfs_tc
30a0: 6c 5f 52 65 73 65 74 49 6e 74 65 72 70 73 28 76  l_ResetInterps(v
30b0: 6f 69 64 29 20 7b 0a 09 41 50 50 46 53 5f 44 45  oid) {..APPFS_DE
30c0: 42 55 47 28 22 52 65 71 75 65 73 74 69 6e 67 20  BUG("Requesting 
30d0: 72 65 73 65 74 20 6f 66 20 61 6c 6c 20 69 6e 74  reset of all int
30e0: 65 72 70 72 65 74 65 72 73 2e 22 29 3b 0a 0a 09  erpreters.");...
30f0: 5f 5f 73 79 6e 63 5f 61 64 64 5f 61 6e 64 5f 66  __sync_add_and_f
3100: 65 74 63 68 28 26 69 6e 74 65 72 70 5f 72 65 73  etch(&interp_res
3110: 65 74 5f 6b 65 79 2c 20 31 29 3b 0a 0a 09 72 65  et_key, 1);...re
3120: 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44  turn;.}../*. * D
3130: 65 74 65 72 6d 69 6e 65 20 74 68 65 20 55 49 44  etermine the UID
3140: 20 66 6f 72 20 74 68 65 20 75 73 65 72 20 6d 61   for the user ma
3150: 6b 69 6e 67 20 74 68 65 20 63 75 72 72 65 6e 74  king the current
3160: 20 46 55 53 45 20 66 69 6c 65 73 79 73 74 65 6d   FUSE filesystem
3170: 20 72 65 71 75 65 73 74 2e 0a 20 2a 20 54 68 69   request.. * Thi
3180: 73 20 77 69 6c 6c 20 62 65 20 75 73 65 64 20 74  s will be used t
3190: 6f 20 6c 6f 6f 6b 75 70 20 74 68 65 20 75 73 65  o lookup the use
31a0: 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  r's home directo
31b0: 72 79 20 73 6f 20 77 65 20 63 61 6e 20 73 65 61  ry so we can sea
31c0: 72 63 68 20 66 6f 72 0a 20 2a 20 6c 6f 63 61 6c  rch for. * local
31d0: 6c 79 20 6d 6f 64 69 66 69 65 64 20 66 69 6c 65  ly modified file
31e0: 73 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 75 69  s.. */.static ui
31f0: 64 5f 74 20 61 70 70 66 73 5f 67 65 74 5f 66 73  d_t appfs_get_fs
3200: 75 69 64 28 76 6f 69 64 29 20 7b 0a 09 73 74 72  uid(void) {..str
3210: 75 63 74 20 66 75 73 65 5f 63 6f 6e 74 65 78 74  uct fuse_context
3220: 20 2a 63 74 78 3b 0a 0a 09 69 66 20 28 21 61 70   *ctx;...if (!ap
3230: 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64  pfs_fuse_started
3240: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 67 65 74  ) {...return(get
3250: 75 69 64 28 29 29 3b 0a 09 7d 0a 0a 09 63 74 78  uid());..}...ctx
3260: 20 3d 20 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74   = fuse_get_cont
3270: 65 78 74 28 29 3b 0a 09 69 66 20 28 63 74 78 20  ext();..if (ctx 
3280: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20  == NULL) {.../* 
3290: 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70  Unable to lookup
32a0: 20 75 73 65 72 20 66 6f 72 20 73 6f 6d 65 20 72   user for some r
32b0: 65 61 73 6f 6e 20 2a 2f 0a 09 09 2f 2a 20 52 65  eason */.../* Re
32c0: 74 75 72 6e 20 61 6e 20 75 6e 70 72 69 76 69 6c  turn an unprivil
32d0: 65 67 65 64 20 75 73 65 72 20 49 44 20 2a 2f 0a  eged user ID */.
32e0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55  ..APPFS_DEBUG("U
32f0: 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20  nable to lookup 
3300: 75 73 65 72 20 66 6f 72 20 73 6f 6d 65 20 72 65  user for some re
3310: 61 73 6f 6e 2c 20 72 65 74 75 72 6e 69 6e 6e 67  ason, returninng
3320: 20 75 73 65 72 20 49 44 20 6f 66 20 31 22 29 3b   user ID of 1");
3330: 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  ....return(1);..
3340: 7d 0a 0a 09 72 65 74 75 72 6e 28 63 74 78 2d 3e  }...return(ctx->
3350: 75 69 64 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44  uid);.}../*. * D
3360: 65 74 65 72 6d 69 6e 65 20 74 68 65 20 47 49 44  etermine the GID
3370: 20 66 6f 72 20 74 68 65 20 75 73 65 72 20 6d 61   for the user ma
3380: 6b 69 6e 67 20 74 68 65 20 63 75 72 72 65 6e 74  king the current
3390: 20 46 55 53 45 20 66 69 6c 65 73 79 73 74 65 6d   FUSE filesystem
33a0: 20 72 65 71 75 65 73 74 2e 0a 20 2a 2f 0a 73 74   request.. */.st
33b0: 61 74 69 63 20 67 69 64 5f 74 20 61 70 70 66 73  atic gid_t appfs
33c0: 5f 67 65 74 5f 66 73 67 69 64 28 76 6f 69 64 29  _get_fsgid(void)
33d0: 20 7b 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f   {..struct fuse_
33e0: 63 6f 6e 74 65 78 74 20 2a 63 74 78 3b 0a 0a 09  context *ctx;...
33f0: 69 66 20 28 21 61 70 70 66 73 5f 66 75 73 65 5f  if (!appfs_fuse_
3400: 73 74 61 72 74 65 64 29 20 7b 0a 09 09 72 65 74  started) {...ret
3410: 75 72 6e 28 67 65 74 67 69 64 28 29 29 3b 0a 09  urn(getgid());..
3420: 7d 0a 0a 09 63 74 78 20 3d 20 66 75 73 65 5f 67  }...ctx = fuse_g
3430: 65 74 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09 69  et_context();..i
3440: 66 20 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 20  f (ctx == NULL) 
3450: 7b 0a 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74 6f  {.../* Unable to
3460: 20 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72   lookup user for
3470: 20 73 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f 0a   some reason */.
3480: 09 09 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20 75  ../* Return an u
3490: 6e 70 72 69 76 69 6c 65 67 65 64 20 75 73 65 72  nprivileged user
34a0: 20 49 44 20 2a 2f 0a 09 09 41 50 50 46 53 5f 44   ID */...APPFS_D
34b0: 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20  EBUG("Unable to 
34c0: 6c 6f 6f 6b 75 70 20 67 72 6f 75 70 20 66 6f 72  lookup group for
34d0: 20 73 6f 6d 65 20 72 65 61 73 6f 6e 2c 20 72 65   some reason, re
34e0: 74 75 72 6e 69 6e 6e 67 20 67 72 6f 75 70 20 49  turninng group I
34f0: 44 20 6f 66 20 31 22 29 3b 0a 0a 09 09 72 65 74  D of 1");....ret
3500: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74  urn(1);..}...ret
3510: 75 72 6e 28 63 74 78 2d 3e 67 69 64 29 3b 0a 7d  urn(ctx->gid);.}
3520: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  ..static void ap
3530: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
3540: 72 5f 66 73 5f 65 6e 74 65 72 28 76 6f 69 64 29  r_fs_enter(void)
3550: 20 7b 0a 09 73 65 74 66 73 75 69 64 28 61 70 70   {..setfsuid(app
3560: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b  fs_get_fsuid());
3570: 0a 09 73 65 74 66 73 67 69 64 28 61 70 70 66 73  ..setfsgid(appfs
3580: 5f 67 65 74 5f 66 73 67 69 64 28 29 29 3b 0a 7d  _get_fsgid());.}
3590: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  ..static void ap
35a0: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
35b0: 72 5f 66 73 5f 6c 65 61 76 65 28 76 6f 69 64 29  r_fs_leave(void)
35c0: 20 7b 0a 09 73 65 74 66 73 75 69 64 28 30 29 3b   {..setfsuid(0);
35d0: 0a 09 73 65 74 66 73 67 69 64 28 30 29 3b 0a 7d  ..setfsgid(0);.}
35e0: 0a 0a 23 69 66 64 65 66 20 41 50 50 46 53 5f 4e  ..#ifdef APPFS_N
35f0: 4f 5f 47 45 54 50 57 55 49 44 0a 73 74 61 74 69  O_GETPWUID.stati
3600: 63 20 63 68 61 72 20 2a 61 70 70 66 73 5f 67 65  c char *appfs_ge
3610: 74 5f 68 6f 6d 65 64 69 72 28 75 69 64 5f 74 20  t_homedir(uid_t 
3620: 66 73 75 69 64 29 20 7b 0a 09 72 65 74 75 72 6e  fsuid) {..return
3630: 28 4e 55 4c 4c 29 3b 0a 7d 0a 23 65 6c 73 65 0a  (NULL);.}.#else.
3640: 2f 2a 0a 20 2a 20 4c 6f 6f 6b 20 75 70 20 74 68  /*. * Look up th
3650: 65 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79  e home directory
3660: 20 66 6f 72 20 61 20 67 69 76 65 6e 20 55 49 44   for a given UID
3670: 0a 20 2a 20 20 20 20 20 20 20 20 52 65 74 75 72  . *        Retur
3680: 6e 73 20 61 20 43 20 73 74 72 69 6e 67 20 63 6f  ns a C string co
3690: 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 75 73 65  ntaining the use
36a0: 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  r's home directo
36b0: 72 79 20 6f 72 20 4e 55 4c 4c 20 69 66 0a 20 2a  ry or NULL if. *
36c0: 20 20 20 20 20 20 20 20 74 68 65 20 75 73 65 72          the user
36d0: 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  's home director
36e0: 79 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74  y does not exist
36f0: 20 6f 72 20 69 73 20 6e 6f 74 20 63 6f 72 72 65   or is not corre
3700: 63 74 6c 79 0a 20 2a 20 20 20 20 20 20 20 20 63  ctly. *        c
3710: 6f 6e 66 69 67 75 72 65 64 0a 20 2a 2f 0a 73 74  onfigured. */.st
3720: 61 74 69 63 20 63 68 61 72 20 2a 61 70 70 66 73  atic char *appfs
3730: 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 75 69 64  _get_homedir(uid
3740: 5f 74 20 66 73 75 69 64 29 20 7b 0a 09 73 74 72  _t fsuid) {..str
3750: 75 63 74 20 70 61 73 73 77 64 20 65 6e 74 72 79  uct passwd entry
3760: 2c 20 2a 72 65 73 75 6c 74 3b 0a 09 73 74 72 75  , *result;..stru
3770: 63 74 20 73 74 61 74 20 73 74 62 75 66 3b 0a 09  ct stat stbuf;..
3780: 63 68 61 72 20 62 75 66 5b 31 30 32 34 5d 2c 20  char buf[1024], 
3790: 2a 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20 67 70  *retval;..int gp
37a0: 75 5f 72 65 74 2c 20 73 74 61 74 5f 72 65 74 3b  u_ret, stat_ret;
37b0: 0a 0a 09 67 70 75 5f 72 65 74 20 3d 20 67 65 74  ...gpu_ret = get
37c0: 70 77 75 69 64 5f 72 28 66 73 75 69 64 2c 20 26  pwuid_r(fsuid, &
37d0: 65 6e 74 72 79 2c 20 62 75 66 2c 20 73 69 7a 65  entry, buf, size
37e0: 6f 66 28 62 75 66 29 2c 20 26 72 65 73 75 6c 74  of(buf), &result
37f0: 29 3b 0a 09 69 66 20 28 67 70 75 5f 72 65 74 20  );..if (gpu_ret 
3800: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
3810: 44 45 42 55 47 28 22 67 65 74 70 77 75 69 64 5f  DEBUG("getpwuid_
3820: 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 74  r(%llu, ...) ret
3830: 75 72 6e 65 64 20 69 6e 20 66 61 69 6c 75 72 65  urned in failure
3840: 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e  ", (unsigned lon
3850: 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b 0a  g long) fsuid);.
3860: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
3870: 0a 09 7d 0a 0a 09 69 66 20 28 72 65 73 75 6c 74  ..}...if (result
3880: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50   == NULL) {...AP
3890: 50 46 53 5f 44 45 42 55 47 28 22 67 65 74 70 77  PFS_DEBUG("getpw
38a0: 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29  uid_r(%llu, ...)
38b0: 20 72 65 74 75 72 6e 65 64 20 4e 55 4c 4c 20 72   returned NULL r
38c0: 65 73 75 6c 74 22 2c 20 28 75 6e 73 69 67 6e 65  esult", (unsigne
38d0: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75  d long long) fsu
38e0: 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e  id);....return(N
38f0: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 72  ULL);..}...if (r
3900: 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 20 3d 3d  esult->pw_dir ==
3910: 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53   NULL) {...APPFS
3920: 5f 44 45 42 55 47 28 22 67 65 74 70 77 75 69 64  _DEBUG("getpwuid
3930: 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65  _r(%llu, ...) re
3940: 74 75 72 6e 65 64 20 4e 55 4c 4c 20 68 6f 6d 65  turned NULL home
3950: 20 64 69 72 65 63 74 6f 72 79 22 2c 20 28 75 6e   directory", (un
3960: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
3970: 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72 65 74  ) fsuid);....ret
3980: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
3990: 73 74 61 74 5f 72 65 74 20 3d 20 73 74 61 74 28  stat_ret = stat(
39a0: 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 2c 20  result->pw_dir, 
39b0: 26 73 74 62 75 66 29 3b 0a 09 69 66 20 28 73 74  &stbuf);..if (st
39c0: 61 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  at_ret != 0) {..
39d0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 73 74  .APPFS_DEBUG("st
39e0: 61 74 28 25 73 29 20 72 65 74 75 72 6e 65 64 20  at(%s) returned 
39f0: 69 6e 20 66 61 69 6c 75 72 65 22 2c 20 72 65 73  in failure", res
3a00: 75 6c 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09  ult->pw_dir);...
3a10: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
3a20: 7d 0a 0a 09 69 66 20 28 73 74 62 75 66 2e 73 74  }...if (stbuf.st
3a30: 5f 75 69 64 20 21 3d 20 66 73 75 69 64 29 20 7b  _uid != fsuid) {
3a40: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
3a50: 55 49 44 20 6d 69 73 2d 6d 61 74 63 68 20 6f 6e  UID mis-match on
3a60: 20 75 73 65 72 20 25 6c 6c 75 27 73 20 68 6f 6d   user %llu's hom
3a70: 65 20 64 69 72 65 63 74 6f 72 79 20 28 25 73 29  e directory (%s)
3a80: 2e 20 20 49 74 27 73 20 6f 77 6e 65 64 20 62 79  .  It's owned by
3a90: 20 25 6c 6c 75 2e 22 2c 0a 09 09 20 20 20 20 28   %llu.",...    (
3aa0: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
3ab0: 6e 67 29 20 66 73 75 69 64 2c 0a 09 09 20 20 20  ng) fsuid,...   
3ac0: 20 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 2c   result->pw_dir,
3ad0: 0a 09 09 20 20 20 20 28 75 6e 73 69 67 6e 65 64  ...    (unsigned
3ae0: 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 74 62 75   long long) stbu
3af0: 66 2e 73 74 5f 75 69 64 0a 09 09 29 3b 0a 0a 09  f.st_uid...);...
3b00: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
3b10: 7d 0a 0a 09 72 65 74 76 61 6c 20 3d 20 73 74 72  }...retval = str
3b20: 64 75 70 28 72 65 73 75 6c 74 2d 3e 70 77 5f 64  dup(result->pw_d
3b30: 69 72 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65  ir);...return(re
3b40: 74 76 61 6c 29 3b 0a 7d 0a 23 65 6e 64 69 66 0a  tval);.}.#endif.
3b50: 0a 2f 2a 0a 20 2a 20 47 65 6e 65 72 61 74 65 20  ./*. * Generate 
3b60: 61 6e 20 69 6e 6f 64 65 20 66 6f 72 20 61 20 67  an inode for a g
3b70: 69 76 65 6e 20 70 61 74 68 2e 20 20 54 68 65 20  iven path.  The 
3b80: 69 6e 6f 64 65 20 73 68 6f 75 6c 64 20 62 65 20  inode should be 
3b90: 63 6f 6d 70 75 74 65 64 20 69 6e 20 73 75 63 68  computed in such
3ba0: 0a 20 2a 20 61 20 77 61 79 20 74 68 61 74 20 69  . * a way that i
3bb0: 74 20 69 73 20 75 6e 6c 69 6b 65 6c 79 20 74 6f  t is unlikely to
3bc0: 20 62 65 20 64 75 70 6c 69 63 61 74 65 64 20 61   be duplicated a
3bd0: 6e 64 20 72 65 6d 61 69 6e 73 20 74 68 65 20 73  nd remains the s
3be0: 61 6d 65 20 66 6f 72 20 61 20 67 69 76 65 6e 0a  ame for a given.
3bf0: 20 2a 20 66 69 6c 65 0a 20 2a 0a 20 2a 20 43 75   * file. *. * Cu
3c00: 72 72 65 6e 74 20 69 6d 70 6c 65 6d 65 6e 74 61  rrent implementa
3c10: 74 69 6f 6e 20 69 73 20 61 6e 20 46 4e 56 2d 31  tion is an FNV-1
3c20: 61 20 33 32 2d 62 69 74 0a 20 2a 2f 0a 23 69 66  a 32-bit. */.#if
3c30: 20 55 49 4e 54 5f 4d 41 58 20 3c 20 34 32 39 34   UINT_MAX < 4294
3c40: 39 36 37 32 39 35 0a 23 65 72 72 6f 72 20 49 6e  967295.#error In
3c50: 74 65 67 65 72 20 73 69 7a 65 20 69 73 20 74 6f  teger size is to
3c60: 6f 20 73 6d 61 6c 6c 20 0a 23 65 6e 64 69 66 0a  o small .#endif.
3c70: 73 74 61 74 69 63 20 75 6e 73 69 67 6e 65 64 20  static unsigned 
3c80: 6c 6f 6e 67 20 6c 6f 6e 67 20 61 70 70 66 73 5f  long long appfs_
3c90: 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 63  get_path_inode(c
3ca0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
3cb0: 20 69 6e 74 20 75 69 64 29 20 7b 0a 09 75 6e 73   int uid) {..uns
3cc0: 69 67 6e 65 64 20 69 6e 74 20 72 65 74 76 61 6c  igned int retval
3cd0: 3b 0a 09 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65  ;..const unsigne
3ce0: 64 20 63 68 61 72 20 2a 70 3b 0a 0a 09 72 65 74  d char *p;...ret
3cf0: 76 61 6c 20 3d 20 32 31 36 36 31 33 36 32 36 31  val = 2166136261
3d00: 55 3b 20 2f 2a 20 46 4e 56 2d 31 61 20 33 32 2d  U; /* FNV-1a 32-
3d10: 62 69 74 20 6f 66 66 73 65 74 5f 62 61 73 69 73  bit offset_basis
3d20: 20 2a 2f 0a 0a 09 66 6f 72 20 28 70 20 3d 20 28   */...for (p = (
3d30: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 29  unsigned char *)
3d40: 20 70 61 74 68 3b 20 2a 70 3b 20 70 2b 2b 29 20   path; *p; p++) 
3d50: 7b 0a 09 09 72 65 74 76 61 6c 20 5e 3d 20 28 69  {...retval ^= (i
3d60: 6e 74 29 20 2a 70 3b 0a 23 69 66 20 30 0a 09 09  nt) *p;.#if 0...
3d70: 72 65 74 76 61 6c 20 2a 3d 20 31 36 37 37 37 36  retval *= 167776
3d80: 31 39 3b 20 2f 2a 20 46 4e 56 2d 31 61 20 33 32  19; /* FNV-1a 32
3d90: 2d 62 69 74 20 70 72 69 6d 65 20 2a 2f 0a 23 65  -bit prime */.#e
3da0: 6c 73 65 0a 09 09 2f 2a 20 47 43 43 20 4f 70 74  lse.../* GCC Opt
3db0: 69 6d 69 7a 65 64 20 72 65 70 6c 61 63 65 6d 65  imized replaceme
3dc0: 6e 74 20 2a 2f 0a 09 09 72 65 74 76 61 6c 20 2b  nt */...retval +
3dd0: 3d 20 28 72 65 74 76 61 6c 20 3c 3c 20 31 29 20  = (retval << 1) 
3de0: 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 34 29 20  + (retval << 4) 
3df0: 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 37 29 20  + (retval << 7) 
3e00: 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 38 29 20  + (retval << 8) 
3e10: 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 32 34 29  + (retval << 24)
3e20: 3b 0a 23 65 6e 64 69 66 0a 09 7d 0a 0a 09 69 66  ;.#endif..}...if
3e30: 20 28 75 69 64 20 3e 3d 20 30 29 20 7b 0a 09 09   (uid >= 0) {...
3e40: 72 65 74 76 61 6c 20 2b 3d 20 75 69 64 3b 0a 09  retval += uid;..
3e50: 09 72 65 74 76 61 6c 2b 2b 3b 0a 09 7d 0a 0a 09  .retval++;..}...
3e60: 41 50 50 46 53 5f 44 45 42 55 47 28 22 4c 6f 6f  APPFS_DEBUG("Loo
3e70: 6b 65 64 20 75 70 20 69 6e 6f 64 65 20 6e 75 6d  ked up inode num
3e80: 62 65 72 20 66 6f 72 20 70 61 74 68 3d 25 73 2c  ber for path=%s,
3e90: 75 69 64 3d 25 69 3a 20 25 75 22 2c 20 70 61 74  uid=%i: %u", pat
3ea0: 68 2c 20 75 69 64 2c 20 72 65 74 76 61 6c 29 3b  h, uid, retval);
3eb0: 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
3ec0: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 61 63 68  );.}../*. * Cach
3ed0: 65 20 47 65 74 20 50 61 74 68 20 49 6e 66 6f 20  e Get Path Info 
3ee0: 6c 6f 6f 6b 75 70 73 20 66 6f 72 20 73 70 65 65  lookups for spee
3ef0: 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d. */.static int
3f00: 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f   appfs_get_path_
3f10: 69 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28 63  info_cache_get(c
3f20: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
3f30: 20 75 69 64 5f 74 20 75 69 64 2c 20 73 74 72 75   uid_t uid, stru
3f40: 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66  ct appfs_pathinf
3f50: 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09  o *pathinfo) {..
3f60: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73  unsigned int has
3f70: 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72  h_idx;..int pthr
3f80: 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65  ead_ret;..int re
3f90: 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 3d  tval;...retval =
3fa0: 20 31 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65   1;...pthread_re
3fb0: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65  t = pthread_mute
3fc0: 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61  x_lock(&appfs_pa
3fd0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75  th_info_cache_mu
3fe0: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65  tex);..if (pthre
3ff0: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
4000: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
4010: 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74  able to lock pat
4020: 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74  h_info cache mut
4030: 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72  ex !");....retur
4040: 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 41 50 50 46  n(-1);..}...APPF
4050: 53 5f 44 45 42 55 47 28 22 4c 6f 6f 6b 69 6e 67  S_DEBUG("Looking
4060: 20 75 70 20 63 61 63 68 65 20 65 6e 74 72 79 20   up cache entry 
4070: 66 6f 72 20 70 61 74 68 3d 25 73 2c 75 69 64 3d  for path=%s,uid=
4080: 25 6c 6c 69 2e 2e 2e 22 2c 20 70 61 74 68 2c 20  %lli...", path, 
4090: 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69 64 29  (long long) uid)
40a0: 3b 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70 61  ;...if (appfs_pa
40b0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 21 3d  th_info_cache !=
40c0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 61 73 68 5f   NULL) {...hash_
40d0: 69 64 78 20 3d 20 28 61 70 70 66 73 5f 67 65 74  idx = (appfs_get
40e0: 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74 68  _path_inode(path
40f0: 2c 20 75 69 64 29 29 20 25 20 61 70 70 66 73 5f  , uid)) % appfs_
4100: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
4110: 73 69 7a 65 3b 0a 0a 09 09 69 66 20 28 61 70 70  size;....if (app
4120: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4130: 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61  he[hash_idx]._ca
4140: 63 68 65 5f 70 61 74 68 20 21 3d 20 4e 55 4c 4c  che_path != NULL
4150: 29 20 7b 0a 09 09 09 69 66 20 28 73 74 72 63 6d  ) {....if (strcm
4160: 70 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  p(appfs_path_inf
4170: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78  o_cache[hash_idx
4180: 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 2c 20 70  ]._cache_path, p
4190: 61 74 68 29 20 3d 3d 20 30 20 26 26 20 61 70 70  ath) == 0 && app
41a0: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
41b0: 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61  he[hash_idx]._ca
41c0: 63 68 65 5f 75 69 64 20 3d 3d 20 75 69 64 29 20  che_uid == uid) 
41d0: 7b 0a 09 09 09 09 72 65 74 76 61 6c 20 3d 20 30  {.....retval = 0
41e0: 3b 0a 0a 09 09 09 09 6d 65 6d 63 70 79 28 70 61  ;......memcpy(pa
41f0: 74 68 69 6e 66 6f 2c 20 26 61 70 70 66 73 5f 70  thinfo, &appfs_p
4200: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68  ath_info_cache[h
4210: 61 73 68 5f 69 64 78 5d 2c 20 73 69 7a 65 6f 66  ash_idx], sizeof
4220: 28 2a 70 61 74 68 69 6e 66 6f 29 29 3b 0a 09 09  (*pathinfo));...
4230: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 5f 63 61 63  ..pathinfo->_cac
4240: 68 65 5f 70 61 74 68 20 3d 20 4e 55 4c 4c 3b 0a  he_path = NULL;.
4250: 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a 0a 09 70 74  ...}...}..}...pt
4260: 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72  hread_ret = pthr
4270: 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b  ead_mutex_unlock
4280: 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  (&appfs_path_inf
4290: 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a  o_cache_mutex);.
42a0: 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74  .if (pthread_ret
42b0: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53   != 0) {...APPFS
42c0: 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74  _DEBUG("Unable t
42d0: 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 6e  o unlock path_in
42e0: 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 21  fo cache mutex !
42f0: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 31  ");....return(-1
4300: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65 74 76  );..}...if (retv
4310: 61 6c 20 3d 3d 20 30 29 20 7b 0a 09 09 41 50 50  al == 0) {...APP
4320: 46 53 5f 44 45 42 55 47 28 22 43 61 63 68 65 20  FS_DEBUG("Cache 
4330: 68 69 74 20 6f 6e 20 70 61 74 68 3d 25 73 2c 75  hit on path=%s,u
4340: 69 64 3d 25 6c 6c 69 22 2c 20 70 61 74 68 2c 20  id=%lli", path, 
4350: 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69 64 29  (long long) uid)
4360: 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 41 50  ;..} else {...AP
4370: 50 46 53 5f 44 45 42 55 47 28 22 43 61 63 68 65  PFS_DEBUG("Cache
4380: 20 6d 69 73 73 20 6f 6e 20 70 61 74 68 3d 25 73   miss on path=%s
4390: 2c 75 69 64 3d 25 6c 6c 69 22 2c 20 70 61 74 68  ,uid=%lli", path
43a0: 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69  , (long long) ui
43b0: 64 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  d);..}...return(
43c0: 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74  retval);.}..stat
43d0: 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 67 65  ic void appfs_ge
43e0: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
43f0: 65 5f 61 64 64 28 63 6f 6e 73 74 20 63 68 61 72  e_add(const char
4400: 20 2a 70 61 74 68 2c 20 75 69 64 5f 74 20 75 69   *path, uid_t ui
4410: 64 2c 20 73 74 72 75 63 74 20 61 70 70 66 73 5f  d, struct appfs_
4420: 70 61 74 68 69 6e 66 6f 20 2a 70 61 74 68 69 6e  pathinfo *pathin
4430: 66 6f 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20  fo) {..unsigned 
4440: 69 6e 74 20 68 61 73 68 5f 69 64 78 3b 0a 09 69  int hash_idx;..i
4450: 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a  nt pthread_ret;.
4460: 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20  ..pthread_ret = 
4470: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f  pthread_mutex_lo
4480: 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69  ck(&appfs_path_i
4490: 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29  nfo_cache_mutex)
44a0: 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72  ;..if (pthread_r
44b0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50  et != 0) {...APP
44c0: 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65  FS_DEBUG("Unable
44d0: 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69 6e   to lock path_in
44e0: 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 21  fo cache mutex !
44f0: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09  ");....return;..
4500: 7d 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70 61  }...if (appfs_pa
4510: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d 3d  th_info_cache ==
4520: 20 4e 55 4c 4c 29 20 7b 0a 09 09 61 70 70 66 73   NULL) {...appfs
4530: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4540: 20 3d 20 63 61 6c 6c 6f 63 28 61 70 70 66 73 5f   = calloc(appfs_
4550: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
4560: 73 69 7a 65 2c 20 73 69 7a 65 6f 66 28 2a 61 70  size, sizeof(*ap
4570: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4580: 63 68 65 29 29 3b 0a 09 7d 0a 0a 09 68 61 73 68  che));..}...hash
4590: 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f 67 65  _idx = (appfs_ge
45a0: 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74  t_path_inode(pat
45b0: 68 2c 20 75 69 64 29 29 20 25 20 61 70 70 66 73  h, uid)) % appfs
45c0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
45d0: 5f 73 69 7a 65 3b 0a 0a 09 69 66 20 28 61 70 70  _size;...if (app
45e0: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
45f0: 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61  he[hash_idx]._ca
4600: 63 68 65 5f 70 61 74 68 20 21 3d 20 4e 55 4c 4c  che_path != NULL
4610: 29 20 7b 0a 09 09 66 72 65 65 28 61 70 70 66 73  ) {...free(appfs
4620: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4630: 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68  [hash_idx]._cach
4640: 65 5f 70 61 74 68 29 3b 0a 09 7d 0a 0a 09 6d 65  e_path);..}...me
4650: 6d 63 70 79 28 26 61 70 70 66 73 5f 70 61 74 68  mcpy(&appfs_path
4660: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
4670: 5f 69 64 78 5d 2c 20 70 61 74 68 69 6e 66 6f 2c  _idx], pathinfo,
4680: 20 73 69 7a 65 6f 66 28 2a 70 61 74 68 69 6e 66   sizeof(*pathinf
4690: 6f 29 29 3b 0a 0a 09 61 70 70 66 73 5f 70 61 74  o));...appfs_pat
46a0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73  h_info_cache[has
46b0: 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61  h_idx]._cache_pa
46c0: 74 68 20 3d 20 73 74 72 64 75 70 28 70 61 74 68  th = strdup(path
46d0: 29 3b 0a 09 61 70 70 66 73 5f 70 61 74 68 5f 69  );..appfs_path_i
46e0: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69  nfo_cache[hash_i
46f0: 64 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64 20 20  dx]._cache_uid  
4700: 3d 20 75 69 64 3b 0a 0a 09 70 74 68 72 65 61 64  = uid;...pthread
4710: 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d  _ret = pthread_m
4720: 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70  utex_unlock(&app
4730: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4740: 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28  he_mutex);..if (
4750: 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30  pthread_ret != 0
4760: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
4770: 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c  G("Unable to unl
4780: 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61  ock path_info ca
4790: 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a  che mutex !");..
47a0: 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72  ..return;..}...r
47b0: 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63  eturn;.}..static
47c0: 20 76 6f 69 64 20 61 70 70 66 73 5f 67 65 74 5f   void appfs_get_
47d0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
47e0: 72 6d 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  rm(const char *p
47f0: 61 74 68 2c 20 75 69 64 5f 74 20 75 69 64 29 20  ath, uid_t uid) 
4800: 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  {..unsigned int 
4810: 68 61 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70  hash_idx;..int p
4820: 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 70 74  thread_ret;...pt
4830: 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72  hread_ret = pthr
4840: 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26  ead_mutex_lock(&
4850: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4860: 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69  cache_mutex);..i
4870: 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21  f (pthread_ret !
4880: 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  = 0) {...APPFS_D
4890: 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20  EBUG("Unable to 
48a0: 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63  lock path_info c
48b0: 61 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a  ache mutex !");.
48c0: 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09  ...return;..}...
48d0: 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69  if (appfs_path_i
48e0: 6e 66 6f 5f 63 61 63 68 65 20 21 3d 20 4e 55 4c  nfo_cache != NUL
48f0: 4c 29 20 7b 0a 09 09 68 61 73 68 5f 69 64 78 20  L) {...hash_idx 
4900: 3d 20 28 61 70 70 66 73 5f 67 65 74 5f 70 61 74  = (appfs_get_pat
4910: 68 5f 69 6e 6f 64 65 28 70 61 74 68 2c 20 75 69  h_inode(path, ui
4920: 64 29 29 20 25 20 61 70 70 66 73 5f 70 61 74 68  d)) % appfs_path
4930: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65  _info_cache_size
4940: 3b 0a 0a 09 09 69 66 20 28 61 70 70 66 73 5f 70  ;....if (appfs_p
4950: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68  ath_info_cache[h
4960: 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f  ash_idx]._cache_
4970: 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  path != NULL) {.
4980: 09 09 09 66 72 65 65 28 61 70 70 66 73 5f 70 61  ...free(appfs_pa
4990: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61  th_info_cache[ha
49a0: 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70  sh_idx]._cache_p
49b0: 61 74 68 29 3b 0a 0a 09 09 09 61 70 70 66 73 5f  ath);.....appfs_
49c0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
49d0: 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65  hash_idx]._cache
49e0: 5f 70 61 74 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09  _path = NULL;...
49f0: 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72  }..}...pthread_r
4a00: 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74  et = pthread_mut
4a10: 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73  ex_unlock(&appfs
4a20: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4a30: 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74  _mutex);..if (pt
4a40: 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20  hread_ret != 0) 
4a50: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
4a60: 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63  "Unable to unloc
4a70: 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68  k path_info cach
4a80: 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09  e mutex !");....
4a90: 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65 74  return;..}...ret
4aa0: 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  urn;.}..static v
4ab0: 6f 69 64 20 61 70 70 66 73 5f 67 65 74 5f 70 61  oid appfs_get_pa
4ac0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c  th_info_cache_fl
4ad0: 75 73 68 28 75 69 64 5f 74 20 75 69 64 2c 20 69  ush(uid_t uid, i
4ae0: 6e 74 20 6e 65 77 5f 73 69 7a 65 29 20 7b 0a 09  nt new_size) {..
4af0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 64 78  unsigned int idx
4b00: 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72  ;..int pthread_r
4b10: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  et;...APPFS_DEBU
4b20: 47 28 22 46 6c 75 73 68 69 6e 67 20 41 70 70 46  G("Flushing AppF
4b30: 53 20 63 61 63 68 65 20 28 75 69 64 20 3d 20 25  S cache (uid = %
4b40: 6c 6c 69 2c 20 6e 65 77 5f 73 69 7a 65 20 3d 20  lli, new_size = 
4b50: 25 69 29 22 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67  %i)", (long long
4b60: 29 20 75 69 64 2c 20 6e 65 77 5f 73 69 7a 65 29  ) uid, new_size)
4b70: 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20  ;...pthread_ret 
4b80: 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  = pthread_mutex_
4b90: 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68  lock(&appfs_path
4ba0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65  _info_cache_mute
4bb0: 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64  x);..if (pthread
4bc0: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41  _ret != 0) {...A
4bd0: 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62  PPFS_DEBUG("Unab
4be0: 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f  le to lock path_
4bf0: 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78  info cache mutex
4c00: 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b   !");....return;
4c10: 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73 5f  ..}...if (appfs_
4c20: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20  path_info_cache 
4c30: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 6f 72  != NULL) {...for
4c40: 20 28 69 64 78 20 3d 20 30 3b 20 69 64 78 20 3c   (idx = 0; idx <
4c50: 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f   appfs_path_info
4c60: 5f 63 61 63 68 65 5f 73 69 7a 65 3b 20 69 64 78  _cache_size; idx
4c70: 2b 2b 29 20 7b 0a 09 09 09 69 66 20 28 61 70 70  ++) {....if (app
4c80: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4c90: 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70  he[idx]._cache_p
4ca0: 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ath != NULL) {..
4cb0: 09 09 09 69 66 20 28 75 69 64 20 21 3d 20 28 28  ...if (uid != ((
4cc0: 75 69 64 5f 74 29 20 2d 31 29 29 20 7b 0a 09 09  uid_t) -1)) {...
4cd0: 09 09 09 69 66 20 28 61 70 70 66 73 5f 70 61 74  ...if (appfs_pat
4ce0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78  h_info_cache[idx
4cf0: 5d 2e 5f 63 61 63 68 65 5f 75 69 64 20 21 3d 20  ]._cache_uid != 
4d00: 75 69 64 29 20 7b 0a 09 09 09 09 09 09 63 6f 6e  uid) {.......con
4d10: 74 69 6e 75 65 3b 0a 09 09 09 09 09 7d 0a 09 09  tinue;......}...
4d20: 09 09 7d 0a 0a 09 09 09 09 66 72 65 65 28 61 70  ..}......free(ap
4d30: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4d40: 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f  che[idx]._cache_
4d50: 70 61 74 68 29 3b 0a 0a 09 09 09 09 61 70 70 66  path);......appf
4d60: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4d70: 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61  e[idx]._cache_pa
4d80: 74 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 09 7d 0a  th = NULL;....}.
4d90: 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 75 69 64  ..}..}...if (uid
4da0: 20 3d 3d 20 28 28 75 69 64 5f 74 29 20 2d 31 29   == ((uid_t) -1)
4db0: 29 20 7b 0a 09 09 66 72 65 65 28 61 70 70 66 73  ) {...free(appfs
4dc0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4dd0: 29 3b 0a 0a 09 09 61 70 70 66 73 5f 70 61 74 68  );....appfs_path
4de0: 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20 4e 55  _info_cache = NU
4df0: 4c 4c 3b 0a 0a 09 09 69 66 20 28 6e 65 77 5f 73  LL;....if (new_s
4e00: 69 7a 65 20 21 3d 20 2d 31 29 20 7b 0a 09 09 09  ize != -1) {....
4e10: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4e20: 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 6e 65 77  cache_size = new
4e30: 5f 73 69 7a 65 3b 0a 09 09 7d 0a 09 7d 0a 0a 09  _size;...}..}...
4e40: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
4e50: 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f  hread_mutex_unlo
4e60: 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69  ck(&appfs_path_i
4e70: 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29  nfo_cache_mutex)
4e80: 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72  ;..if (pthread_r
4e90: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50  et != 0) {...APP
4ea0: 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65  FS_DEBUG("Unable
4eb0: 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f   to unlock path_
4ec0: 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78  info cache mutex
4ed0: 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b   !");....return;
4ee0: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a  ..}...return;.}.
4ef0: 0a 2f 2a 20 47 65 74 20 69 6e 66 6f 72 6d 61 74  ./* Get informat
4f00: 69 6f 6e 20 61 62 6f 75 74 20 61 20 70 61 74 68  ion about a path
4f10: 2c 20 61 6e 64 20 6f 70 74 69 6f 6e 61 6c 6c 79  , and optionally
4f20: 20 6c 69 73 74 20 63 68 69 6c 64 72 65 6e 20 2a   list children *
4f30: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  /.static int app
4f40: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
4f50: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
4f60: 68 2c 20 73 74 72 75 63 74 20 61 70 70 66 73 5f  h, struct appfs_
4f70: 70 61 74 68 69 6e 66 6f 20 2a 70 61 74 68 69 6e  pathinfo *pathin
4f80: 66 6f 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  fo) {..Tcl_Inter
4f90: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c 5f  p *interp;..Tcl_
4fa0: 4f 62 6a 20 2a 61 74 74 72 73 5f 64 69 63 74 2c  Obj *attrs_dict,
4fb0: 20 2a 61 74 74 72 5f 76 61 6c 75 65 3b 0a 09 63   *attr_value;..c
4fc0: 6f 6e 73 74 20 63 68 61 72 20 2a 61 74 74 72 5f  onst char *attr_
4fd0: 76 61 6c 75 65 5f 73 74 72 2c 20 2a 61 74 74 72  value_str, *attr
4fe0: 5f 76 61 6c 75 65 5f 73 74 72 5f 69 3b 0a 09 54  _value_str_i;..T
4ff0: 63 6c 5f 57 69 64 65 49 6e 74 20 61 74 74 72 5f  cl_WideInt attr_
5000: 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 69 6e 74  value_wide;..int
5010: 20 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b   attr_value_int;
5020: 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61  ..static __threa
5030: 64 20 54 63 6c 5f 4f 62 6a 20 2a 61 74 74 72 5f  d Tcl_Obj *attr_
5040: 6b 65 79 5f 74 79 70 65 20 3d 20 4e 55 4c 4c 2c  key_type = NULL,
5050: 20 2a 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73   *attr_key_perms
5060: 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b   = NULL, *attr_k
5070: 65 79 5f 73 69 7a 65 20 3d 20 4e 55 4c 4c 2c 20  ey_size = NULL, 
5080: 2a 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 20 3d  *attr_key_time =
5090: 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79   NULL, *attr_key
50a0: 5f 73 6f 75 72 63 65 20 3d 20 4e 55 4c 4c 2c 20  _source = NULL, 
50b0: 2a 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63  *attr_key_childc
50c0: 6f 75 6e 74 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74  ount = NULL, *at
50d0: 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 20  tr_key_packaged 
50e0: 3d 20 4e 55 4c 4c 3b 0a 09 69 6e 74 20 63 61 63  = NULL;..int cac
50f0: 68 65 5f 72 65 74 3b 0a 09 69 6e 74 20 74 63 6c  he_ret;..int tcl
5100: 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65 74 76 61  _ret;..int retva
5110: 6c 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b  l;..uid_t fsuid;
5120: 0a 0a 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a  ...retval = 0;..
5130: 09 66 73 75 69 64 20 3d 20 61 70 70 66 73 5f 67  .fsuid = appfs_g
5140: 65 74 5f 66 73 75 69 64 28 29 3b 0a 0a 09 63 61  et_fsuid();...ca
5150: 63 68 65 5f 72 65 74 20 3d 20 61 70 70 66 73 5f  che_ret = appfs_
5160: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
5170: 63 68 65 5f 67 65 74 28 70 61 74 68 2c 20 66 73  che_get(path, fs
5180: 75 69 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a  uid, pathinfo);.
5190: 09 69 66 20 28 63 61 63 68 65 5f 72 65 74 20 3d  .if (cache_ret =
51a0: 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 70 61 74  = 0) {...if (pat
51b0: 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d 20 41  hinfo->type == A
51c0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 4f  PPFS_PATHTYPE_DO
51d0: 45 53 5f 4e 4f 54 5f 45 58 49 53 54 29 20 7b 0a  ES_NOT_EXIST) {.
51e0: 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
51f0: 52 65 74 75 72 6e 69 6e 67 20 66 72 6f 6d 20 63  Returning from c
5200: 61 63 68 65 3a 20 64 6f 65 73 20 6e 6f 74 20 65  ache: does not e
5210: 78 69 73 74 20 5c 22 25 73 5c 22 22 2c 20 70 61  xist \"%s\"", pa
5220: 74 68 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28  th);.....return(
5230: 2d 45 4e 4f 45 4e 54 29 3b 0a 09 09 7d 0a 0a 09  -ENOENT);...}...
5240: 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2d 3e 74  .if (pathinfo->t
5250: 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50 41 54  ype == APPFS_PAT
5260: 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 29 20 7b  HTYPE_INVALID) {
5270: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
5280: 22 52 65 74 75 72 6e 69 6e 67 20 66 72 6f 6d 20  "Returning from 
5290: 63 61 63 68 65 3a 20 69 6e 76 61 6c 69 64 20 6f  cache: invalid o
52a0: 62 6a 65 63 74 20 5c 22 25 73 5c 22 22 2c 20 70  bject \"%s\"", p
52b0: 61 74 68 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e  ath);.....return
52c0: 28 2d 45 49 4f 29 3b 0a 09 09 7d 0a 0a 09 09 72  (-EIO);...}....r
52d0: 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 69  eturn(0);..}...i
52e0: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63  nterp = appfs_Tc
52f0: 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28  lInterp();..if (
5300: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
5310: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
5320: 22 65 72 72 6f 72 3a 20 55 6e 61 62 6c 65 20 74  "error: Unable t
5330: 6f 20 67 65 74 20 61 6e 20 69 6e 74 65 72 70 72  o get an interpr
5340: 65 74 65 72 22 29 3b 0a 0a 09 09 72 65 74 75 72  eter");....retur
5350: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70  n(-EIO);..}...ap
5360: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
5370: 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74  Tcl_Preserve(int
5380: 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72 65 74  erp);)...tcl_ret
5390: 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61   = appfs_Tcl_Eva
53a0: 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a  l(interp, 2, "::
53b0: 61 70 70 66 73 3a 3a 67 65 74 61 74 74 72 22 2c  appfs::getattr",
53c0: 20 70 61 74 68 29 3b 0a 09 69 66 20 28 74 63 6c   path);..if (tcl
53d0: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  _ret != TCL_OK) 
53e0: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
53f0: 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61 74 74  "::appfs::getatt
5400: 72 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20  r(%s) failed.", 
5410: 70 61 74 68 29 3b 0a 09 09 61 70 70 66 73 5f 63  path);...appfs_c
5420: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41  all_libtcl(....A
5430: 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20  PPFS_DEBUG("Tcl 
5440: 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54  Error is: %s", T
5450: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
5460: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29  lt(interp));...)
5470: 0a 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
5480: 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54  pe = APPFS_PATHT
5490: 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49  YPE_DOES_NOT_EXI
54a0: 53 54 3b 0a 0a 09 09 61 70 70 66 73 5f 67 65 74  ST;....appfs_get
54b0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
54c0: 5f 61 64 64 28 70 61 74 68 2c 20 66 73 75 69 64  _add(path, fsuid
54d0: 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a 0a 09 09  , pathinfo);....
54e0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
54f0: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
5500: 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72  terp);)....retur
5510: 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09 7d 0a 0a  n(-ENOENT);..}..
5520: 09 69 66 20 28 61 74 74 72 5f 6b 65 79 5f 74 79  .if (attr_key_ty
5530: 70 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  pe == NULL) {...
5540: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
5550: 6c 28 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 74  l(....attr_key_t
5560: 79 70 65 20 20 20 20 20 20 20 3d 20 54 63 6c 5f  ype       = Tcl_
5570: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 74 79  NewStringObj("ty
5580: 70 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74  pe", -1);....att
5590: 72 5f 6b 65 79 5f 70 65 72 6d 73 20 20 20 20 20  r_key_perms     
55a0: 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67   = Tcl_NewString
55b0: 4f 62 6a 28 22 70 65 72 6d 73 22 2c 20 2d 31 29  Obj("perms", -1)
55c0: 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 73 69  ;....attr_key_si
55d0: 7a 65 20 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e  ze       = Tcl_N
55e0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 73 69 7a  ewStringObj("siz
55f0: 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72  e", -1);....attr
5600: 5f 6b 65 79 5f 74 69 6d 65 20 20 20 20 20 20 20  _key_time       
5610: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
5620: 62 6a 28 22 74 69 6d 65 22 2c 20 2d 31 29 3b 0a  bj("time", -1);.
5630: 09 09 09 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72  ...attr_key_sour
5640: 63 65 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77  ce     = Tcl_New
5650: 53 74 72 69 6e 67 4f 62 6a 28 22 73 6f 75 72 63  StringObj("sourc
5660: 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72  e", -1);....attr
5670: 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 20  _key_childcount 
5680: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
5690: 62 6a 28 22 63 68 69 6c 64 63 6f 75 6e 74 22 2c  bj("childcount",
56a0: 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65   -1);....attr_ke
56b0: 79 5f 70 61 63 6b 61 67 65 64 20 20 20 3d 20 54  y_packaged   = T
56c0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
56d0: 22 70 61 63 6b 61 67 65 64 22 2c 20 2d 31 29 3b  "packaged", -1);
56e0: 0a 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66  .....Tcl_IncrRef
56f0: 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 74  Count(attr_key_t
5700: 79 70 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63  ype);....Tcl_Inc
5710: 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b  rRefCount(attr_k
5720: 65 79 5f 70 65 72 6d 73 29 3b 0a 09 09 09 54 63  ey_perms);....Tc
5730: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61  l_IncrRefCount(a
5740: 74 74 72 5f 6b 65 79 5f 73 69 7a 65 29 3b 0a 09  ttr_key_size);..
5750: 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75  ..Tcl_IncrRefCou
5760: 6e 74 28 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65  nt(attr_key_time
5770: 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65  );....Tcl_IncrRe
5780: 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f  fCount(attr_key_
5790: 73 6f 75 72 63 65 29 3b 0a 09 09 09 54 63 6c 5f  source);....Tcl_
57a0: 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74  IncrRefCount(att
57b0: 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74  r_key_childcount
57c0: 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65  );....Tcl_IncrRe
57d0: 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f  fCount(attr_key_
57e0: 70 61 63 6b 61 67 65 64 29 3b 0a 09 09 29 0a 09  packaged);...)..
57f0: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
5800: 69 62 74 63 6c 28 0a 09 09 61 74 74 72 73 5f 64  ibtcl(...attrs_d
5810: 69 63 74 20 3d 20 54 63 6c 5f 47 65 74 4f 62 6a  ict = Tcl_GetObj
5820: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a  Result(interp);.
5830: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
5840: 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72  DictObjGet(inter
5850: 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61  p, attrs_dict, a
5860: 74 74 72 5f 6b 65 79 5f 74 79 70 65 2c 20 26 61  ttr_key_type, &a
5870: 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 29 0a 09  ttr_value);..)..
5880: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
5890: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
58a0: 5f 44 45 42 55 47 28 22 5b 64 69 63 74 20 67 65  _DEBUG("[dict ge
58b0: 74 20 5c 22 74 79 70 65 5c 22 5d 20 66 61 69 6c  t \"type\"] fail
58c0: 65 64 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61  ed");...appfs_ca
58d0: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50  ll_libtcl(....AP
58e0: 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45  PFS_DEBUG("Tcl E
58f0: 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63  rror is: %s", Tc
5900: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
5910: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a  t(interp));...).
5920: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
5930: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
5940: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65  (interp);)....re
5950: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
5960: 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20  .if (attr_value 
5970: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50  == NULL) {...APP
5980: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
5990: 20 55 6e 61 62 6c 65 20 74 6f 20 67 65 74 20 74   Unable to get t
59a0: 79 70 65 20 66 6f 72 20 5c 22 25 73 5c 22 20 66  ype for \"%s\" f
59b0: 72 6f 6d 20 54 63 6c 22 2c 20 70 61 74 68 29 3b  rom Tcl", path);
59c0: 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
59d0: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
59e0: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72  e(interp);)....r
59f0: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
5a00: 0a 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b  ..pathinfo->pack
5a10: 61 67 65 64 20 3d 20 30 3b 0a 0a 09 61 70 70 66  aged = 0;...appf
5a20: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
5a30: 09 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 20  .attr_value_str 
5a40: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  = Tcl_GetString(
5a50: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 0a 09 09  attr_value);....
5a60: 73 77 69 74 63 68 20 28 61 74 74 72 5f 76 61 6c  switch (attr_val
5a70: 75 65 5f 73 74 72 5b 30 5d 29 20 7b 0a 09 09 09  ue_str[0]) {....
5a80: 63 61 73 65 20 27 64 27 3a 20 2f 2a 20 64 69 72  case 'd': /* dir
5a90: 65 63 74 6f 72 79 20 2a 2f 0a 09 09 09 09 70 61  ectory */.....pa
5aa0: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41  thinfo->type = A
5ab0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49  PPFS_PATHTYPE_DI
5ac0: 52 45 43 54 4f 52 59 3b 0a 09 09 09 09 70 61 74  RECTORY;.....pat
5ad0: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
5ae0: 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d  dir.childcount =
5af0: 20 30 3b 0a 0a 09 09 09 09 54 63 6c 5f 44 69 63   0;......Tcl_Dic
5b00: 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20  tObjGet(interp, 
5b10: 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72  attrs_dict, attr
5b20: 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 2c  _key_childcount,
5b30: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
5b40: 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75  ...if (attr_valu
5b50: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  e != NULL) {....
5b60: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
5b70: 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62  GetWideIntFromOb
5b80: 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c  j(NULL, attr_val
5b90: 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f  ue, &attr_value_
5ba0: 77 69 64 65 29 3b 0a 09 09 09 09 09 69 66 20 28  wide);......if (
5bb0: 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f  tcl_ret == TCL_O
5bc0: 4b 29 20 7b 0a 09 09 09 09 09 09 70 61 74 68 69  K) {.......pathi
5bd0: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64 69  nfo->typeinfo.di
5be0: 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 61  r.childcount = a
5bf0: 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a  ttr_value_wide;.
5c00: 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09  .....}.....}....
5c10: 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65  ..break;....case
5c20: 20 27 66 27 3a 20 2f 2a 20 66 69 6c 65 20 2a 2f   'f': /* file */
5c30: 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
5c40: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48  ype = APPFS_PATH
5c50: 54 59 50 45 5f 46 49 4c 45 3b 0a 09 09 09 09 70  TYPE_FILE;.....p
5c60: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
5c70: 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 3d 20 30 3b  o.file.size = 0;
5c80: 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
5c90: 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65  ypeinfo.file.exe
5ca0: 63 75 74 61 62 6c 65 20 3d 20 30 3b 0a 09 09 09  cutable = 0;....
5cb0: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  .pathinfo->typei
5cc0: 6e 66 6f 2e 66 69 6c 65 2e 73 75 69 64 52 6f 6f  nfo.file.suidRoo
5cd0: 74 20 3d 20 30 3b 0a 09 09 09 09 70 61 74 68 69  t = 0;.....pathi
5ce0: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69  nfo->typeinfo.fi
5cf0: 6c 65 2e 77 6f 72 6c 64 61 63 63 65 73 73 69 62  le.worldaccessib
5d00: 6c 65 20 3d 20 30 3b 0a 0a 09 09 09 09 54 63 6c  le = 0;......Tcl
5d10: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
5d20: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
5d30: 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 2c 20 26  attr_key_size, &
5d40: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09  attr_value);....
5d50: 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20  .if (attr_value 
5d60: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 09  != NULL) {......
5d70: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65  tcl_ret = Tcl_Ge
5d80: 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28  tWideIntFromObj(
5d90: 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65  NULL, attr_value
5da0: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69  , &attr_value_wi
5db0: 64 65 29 3b 0a 09 09 09 09 09 69 66 20 28 74 63  de);......if (tc
5dc0: 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29  l_ret == TCL_OK)
5dd0: 20 7b 0a 09 09 09 09 09 09 70 61 74 68 69 6e 66   {.......pathinf
5de0: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  o->typeinfo.file
5df0: 2e 73 69 7a 65 20 3d 20 61 74 74 72 5f 76 61 6c  .size = attr_val
5e00: 75 65 5f 77 69 64 65 3b 0a 09 09 09 09 09 7d 0a  ue_wide;......}.
5e10: 09 09 09 09 7d 0a 0a 09 09 09 09 54 63 6c 5f 44  ....}......Tcl_D
5e20: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
5e30: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
5e40: 74 72 5f 6b 65 79 5f 70 65 72 6d 73 2c 20 26 61  tr_key_perms, &a
5e50: 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09  ttr_value);.....
5e60: 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21  if (attr_value !
5e70: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 09 61  = NULL) {......a
5e80: 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20  ttr_value_str = 
5e90: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 61 74  Tcl_GetString(at
5ea0: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09 09  tr_value);......
5eb0: 66 6f 72 20 28 61 74 74 72 5f 76 61 6c 75 65 5f  for (attr_value_
5ec0: 73 74 72 5f 69 20 3d 20 26 61 74 74 72 5f 76 61  str_i = &attr_va
5ed0: 6c 75 65 5f 73 74 72 5b 30 5d 3b 20 2a 61 74 74  lue_str[0]; *att
5ee0: 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 20 21 3d  r_value_str_i !=
5ef0: 20 27 5c 30 27 3b 20 61 74 74 72 5f 76 61 6c 75   '\0'; attr_valu
5f00: 65 5f 73 74 72 5f 69 2b 2b 29 20 7b 0a 09 09 09  e_str_i++) {....
5f10: 09 09 09 73 77 69 74 63 68 20 28 2a 61 74 74 72  ...switch (*attr
5f20: 5f 76 61 6c 75 65 5f 73 74 72 5f 69 29 20 7b 0a  _value_str_i) {.
5f30: 09 09 09 09 09 09 09 63 61 73 65 20 27 78 27 3a  .......case 'x':
5f40: 0a 09 09 09 09 09 09 09 09 70 61 74 68 69 6e 66  .........pathinf
5f50: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  o->typeinfo.file
5f60: 2e 65 78 65 63 75 74 61 62 6c 65 20 3d 20 31 3b  .executable = 1;
5f70: 0a 0a 09 09 09 09 09 09 09 09 62 72 65 61 6b 3b  ..........break;
5f80: 0a 09 09 09 09 09 09 09 63 61 73 65 20 27 55 27  ........case 'U'
5f90: 3a 0a 09 09 09 09 09 09 09 09 70 61 74 68 69 6e  :.........pathin
5fa0: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  fo->typeinfo.fil
5fb0: 65 2e 73 75 69 64 52 6f 6f 74 20 3d 20 31 3b 0a  e.suidRoot = 1;.
5fc0: 0a 09 09 09 09 09 09 09 09 62 72 65 61 6b 3b 0a  .........break;.
5fd0: 09 09 09 09 09 09 09 63 61 73 65 20 27 2d 27 3a  .......case '-':
5fe0: 0a 09 09 09 09 09 09 09 09 70 61 74 68 69 6e 66  .........pathinf
5ff0: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  o->typeinfo.file
6000: 2e 77 6f 72 6c 64 61 63 63 65 73 73 69 62 6c 65  .worldaccessible
6010: 20 3d 20 31 3b 0a 0a 09 09 09 09 09 09 09 09 62   = 1;..........b
6020: 72 65 61 6b 3b 0a 09 09 09 09 09 09 7d 0a 09 09  reak;.......}...
6030: 09 09 09 7d 0a 09 09 09 09 7d 0a 09 09 09 09 62  ...}.....}.....b
6040: 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 73  reak;....case 's
6050: 27 3a 20 2f 2a 20 73 79 6d 6c 69 6e 6b 20 2a 2f  ': /* symlink */
6060: 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
6070: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48  ype = APPFS_PATH
6080: 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3b 0a 09 09  TYPE_SYMLINK;...
6090: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
60a0: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a  info.symlink.siz
60b0: 65 20 3d 20 30 3b 0a 09 09 09 09 70 61 74 68 69  e = 0;.....pathi
60c0: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79  nfo->typeinfo.sy
60d0: 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b 30 5d 20  mlink.source[0] 
60e0: 3d 20 27 5c 30 27 3b 0a 0a 09 09 09 09 54 63 6c  = '\0';......Tcl
60f0: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
6100: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
6110: 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65 2c  attr_key_source,
6120: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
6130: 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75  ...if (attr_valu
6140: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  e != NULL) {....
6150: 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72  ..attr_value_str
6160: 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67   = Tcl_GetString
6170: 46 72 6f 6d 4f 62 6a 28 61 74 74 72 5f 76 61 6c  FromObj(attr_val
6180: 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f  ue, &attr_value_
6190: 69 6e 74 29 3b 20 0a 0a 09 09 09 09 09 69 66 20  int); .......if 
61a0: 28 28 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74  ((attr_value_int
61b0: 20 2b 20 31 29 20 3c 3d 20 73 69 7a 65 6f 66 28   + 1) <= sizeof(
61c0: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
61d0: 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63  fo.symlink.sourc
61e0: 65 29 29 20 7b 0a 09 09 09 09 09 09 70 61 74 68  e)) {.......path
61f0: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73  info->typeinfo.s
6200: 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20 61 74  ymlink.size = at
6210: 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a 09 09  tr_value_int;...
6220: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
6230: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
6240: 6f 75 72 63 65 5b 61 74 74 72 5f 76 61 6c 75 65  ource[attr_value
6250: 5f 69 6e 74 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09  _int] = '\0';...
6260: 09 09 09 09 09 6d 65 6d 63 70 79 28 70 61 74 68  .....memcpy(path
6270: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73  info->typeinfo.s
6280: 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c 20 61  ymlink.source, a
6290: 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 2c 20 61  ttr_value_str, a
62a0: 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 0a  ttr_value_int);.
62b0: 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 09 09 09  .....}.....}....
62c0: 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20  .break;....case 
62d0: 27 46 27 3a 20 2f 2a 20 70 69 70 65 2f 66 69 66  'F': /* pipe/fif
62e0: 6f 20 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66  o */.....pathinf
62f0: 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f  o->type = APPFS_
6300: 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3b 0a 09  PATHTYPE_FIFO;..
6310: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73  ...break;....cas
6320: 65 20 27 53 27 3a 20 2f 2a 20 55 4e 49 58 20 64  e 'S': /* UNIX d
6330: 6f 6d 61 69 6e 20 73 6f 63 6b 65 74 20 2a 2f 0a  omain socket */.
6340: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
6350: 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54  pe = APPFS_PATHT
6360: 59 50 45 5f 53 4f 43 4b 45 54 3b 0a 09 09 09 09  YPE_SOCKET;.....
6370: 62 72 65 61 6b 3b 0a 09 09 09 64 65 66 61 75 6c  break;....defaul
6380: 74 3a 0a 09 09 09 09 72 65 74 76 61 6c 20 3d 20  t:.....retval = 
6390: 2d 45 49 4f 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c  -EIO;...}....Tcl
63a0: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
63b0: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
63c0: 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65  attr_key_package
63d0: 64 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  d, &attr_value);
63e0: 0a 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75  ...if (attr_valu
63f0: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  e != NULL) {....
6400: 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67  pathinfo->packag
6410: 65 64 20 3d 20 31 3b 0a 09 09 7d 0a 0a 09 09 54  ed = 1;...}....T
6420: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
6430: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
6440: 2c 20 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 2c  , attr_key_time,
6450: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
6460: 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20  .if (attr_value 
6470: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 74 63  != NULL) {....tc
6480: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 57  l_ret = Tcl_GetW
6490: 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e 55  ideIntFromObj(NU
64a0: 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c 20  LL, attr_value, 
64b0: 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65  &attr_value_wide
64c0: 29 3b 0a 09 09 09 69 66 20 28 74 63 6c 5f 72 65  );....if (tcl_re
64d0: 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t == TCL_OK) {..
64e0: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 69 6d  ...pathinfo->tim
64f0: 65 20 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 77  e = attr_value_w
6500: 69 64 65 3b 0a 09 09 09 7d 0a 09 09 7d 20 65 6c  ide;....}...} el
6510: 73 65 20 7b 0a 09 09 09 70 61 74 68 69 6e 66 6f  se {....pathinfo
6520: 2d 3e 74 69 6d 65 20 3d 20 61 70 70 66 73 5f 62  ->time = appfs_b
6530: 6f 6f 74 74 69 6d 65 3b 0a 09 09 7d 0a 0a 09 09  oottime;...}....
6540: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
6550: 72 70 29 3b 0a 09 29 0a 0a 09 69 66 20 28 70 61  rp);..)...if (pa
6560: 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67 65 64  thinfo->packaged
6570: 29 20 7b 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e  ) {...pathinfo->
6580: 69 6e 6f 64 65 20 3d 20 61 70 70 66 73 5f 67 65  inode = appfs_ge
6590: 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74  t_path_inode(pat
65a0: 68 2c 20 2d 31 29 3b 0a 09 7d 20 65 6c 73 65 20  h, -1);..} else 
65b0: 7b 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e 69 6e  {...pathinfo->in
65c0: 6f 64 65 20 3d 20 61 70 70 66 73 5f 67 65 74 5f  ode = appfs_get_
65d0: 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74 68 2c  path_inode(path,
65e0: 20 66 73 75 69 64 29 3b 0a 09 7d 0a 0a 09 41 50   fsuid);..}...AP
65f0: 50 46 53 5f 44 45 42 55 47 28 22 43 61 63 68 69  PFS_DEBUG("Cachi
6600: 6e 67 20 69 6e 6f 64 65 20 66 6f 72 20 70 61 74  ng inode for pat
6610: 68 3d 25 73 2c 75 69 64 3d 25 6c 6c 69 20 61 73  h=%s,uid=%lli as
6620: 20 25 6c 6c 75 20 28 70 61 63 6b 61 67 65 64 20   %llu (packaged 
6630: 3d 20 25 69 29 22 2c 20 70 61 74 68 2c 20 28 6c  = %i)", path, (l
6640: 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 2c  ong long) fsuid,
6650: 20 70 61 74 68 69 6e 66 6f 2d 3e 69 6e 6f 64 65   pathinfo->inode
6660: 2c 20 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b  , pathinfo->pack
6670: 61 67 65 64 29 3b 0a 0a 09 69 66 20 28 72 65 74  aged);...if (ret
6680: 76 61 6c 20 3d 3d 20 30 29 20 7b 0a 09 09 61 70  val == 0) {...ap
6690: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
66a0: 6f 5f 63 61 63 68 65 5f 61 64 64 28 70 61 74 68  o_cache_add(path
66b0: 2c 20 66 73 75 69 64 2c 20 70 61 74 68 69 6e 66  , fsuid, pathinf
66c0: 6f 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09  o);..} else {...
66d0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72  APPFS_DEBUG("err
66e0: 6f 72 3a 20 49 6e 76 61 6c 69 64 20 74 79 70 65  or: Invalid type
66f0: 20 66 6f 72 20 5c 22 25 73 5c 22 20 66 72 6f 6d   for \"%s\" from
6700: 20 54 63 6c 22 2c 20 70 61 74 68 29 3b 0a 09 7d   Tcl", path);..}
6710: 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
6720: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61  );.}..static cha
6730: 72 20 2a 61 70 70 66 73 5f 70 72 65 70 61 72 65  r *appfs_prepare
6740: 5f 74 6f 5f 63 72 65 61 74 65 28 63 6f 6e 73 74  _to_create(const
6750: 20 63 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09   char *path) {..
6760: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
6770: 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20  rp;..const char 
6780: 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74  *real_path;..int
6790: 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 61 70 70 66   tcl_ret;...appf
67a0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
67b0: 63 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66  cache_flush(appf
67c0: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d  s_get_fsuid(), -
67d0: 31 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61  1);...interp = a
67e0: 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29  ppfs_TclInterp()
67f0: 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ;..if (interp ==
6800: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
6810: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70  n(NULL);..}...ap
6820: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
6830: 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74  Tcl_Preserve(int
6840: 65 72 70 29 3b 29 0a 0a 09 61 70 70 66 73 5f 63  erp);)...appfs_c
6850: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63  all_libtcl(...tc
6860: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
6870: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32  l_Eval(interp, 2
6880: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65 70  , "::appfs::prep
6890: 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 22 2c 20  are_to_create", 
68a0: 70 61 74 68 29 3b 0a 09 29 0a 09 69 66 20 28 74  path);..)..if (t
68b0: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
68c0: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
68d0: 47 28 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65 70  G("::appfs::prep
68e0: 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 25 73  are_to_create(%s
68f0: 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68  ) failed.", path
6900: 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  );...appfs_call_
6910: 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53  libtcl(....APPFS
6920: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
6930: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
6940: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
6950: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
6960: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
6970: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
6980: 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72  terp);)....retur
6990: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70  n(NULL);..}...ap
69a0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
69b0: 0a 09 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54  ...real_path = T
69c0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
69d0: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a  lt(interp);..)..
69e0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
69f0: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
6a00: 6e 74 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72  nterp);)...if (r
6a10: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
6a20: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  ) {...return(NUL
6a30: 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  L);..}...return(
6a40: 73 74 72 64 75 70 28 72 65 61 6c 5f 70 61 74 68  strdup(real_path
6a50: 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68  ));.}..static ch
6a60: 61 72 20 2a 61 70 70 66 73 5f 6c 6f 63 61 6c 70  ar *appfs_localp
6a70: 61 74 68 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ath(const char *
6a80: 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74  path) {..Tcl_Int
6a90: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f  erp *interp;..co
6aa0: 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70  nst char *real_p
6ab0: 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65  ath;..int tcl_re
6ac0: 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  t;...interp = ap
6ad0: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  pfs_TclInterp();
6ae0: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
6af0: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
6b00: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70  (NULL);..}...app
6b10: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
6b20: 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65  cl_Preserve(inte
6b30: 72 70 29 3b 29 0a 0a 09 61 70 70 66 73 5f 63 61  rp);)...appfs_ca
6b40: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c  ll_libtcl(...tcl
6b50: 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c  _ret = appfs_Tcl
6b60: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c  _Eval(interp, 2,
6b70: 20 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63 61 6c   "::appfs::local
6b80: 70 61 74 68 22 2c 20 70 61 74 68 29 3b 0a 09 29  path", path);..)
6b90: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
6ba0: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
6bb0: 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66  FS_DEBUG("::appf
6bc0: 73 3a 3a 6c 6f 63 61 6c 70 61 74 68 28 25 73 29  s::localpath(%s)
6bd0: 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29   failed.", path)
6be0: 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ;...appfs_call_l
6bf0: 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f  ibtcl(....APPFS_
6c00: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72  DEBUG("Tcl Error
6c10: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
6c20: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
6c30: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 72  terp));...)....r
6c40: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
6c50: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
6c60: 74 63 6c 28 0a 09 09 72 65 61 6c 5f 70 61 74 68  tcl(...real_path
6c70: 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67   = Tcl_GetString
6c80: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a  Result(interp);.
6c90: 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .)...appfs_call_
6ca0: 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61  libtcl(Tcl_Relea
6cb0: 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 69  se(interp);)...i
6cc0: 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20  f (real_path == 
6cd0: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
6ce0: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74  (NULL);..}...ret
6cf0: 75 72 6e 28 73 74 72 64 75 70 28 72 65 61 6c 5f  urn(strdup(real_
6d00: 70 61 74 68 29 29 3b 0a 7d 0a 0a 23 69 66 20 28  path));.}..#if (
6d10: 64 65 66 69 6e 65 64 28 44 45 42 55 47 29 20 26  defined(DEBUG) &
6d20: 26 20 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f  & defined(APPFS_
6d30: 45 58 49 54 5f 50 41 54 48 29 29 20 7c 7c 20 64  EXIT_PATH)) || d
6d40: 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58 49  efined(APPFS_EXI
6d50: 54 5f 50 41 54 48 5f 45 4e 41 42 4c 45 5f 4d 41  T_PATH_ENABLE_MA
6d60: 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f 48 4f 4c  JOR_SECURITY_HOL
6d70: 45 29 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  E).static void a
6d80: 70 70 66 73 5f 65 78 69 74 28 76 6f 69 64 29 20  ppfs_exit(void) 
6d90: 7b 0a 09 69 6e 74 20 67 6c 6f 62 61 6c 5f 69 6e  {..int global_in
6da0: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 3b 0a  terp_reset_key;.
6db0: 0a 09 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f  ..global_interp_
6dc0: 72 65 73 65 74 5f 6b 65 79 20 3d 20 5f 5f 73 79  reset_key = __sy
6dd0: 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 61 64 64  nc_fetch_and_add
6de0: 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  (&interp_reset_k
6df0: 65 79 2c 20 30 29 3b 0a 09 5f 5f 73 79 6e 63 5f  ey, 0);..__sync_
6e00: 66 65 74 63 68 5f 61 6e 64 5f 73 75 62 28 26 69  fetch_and_sub(&i
6e10: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c  nterp_reset_key,
6e20: 20 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72   global_interp_r
6e30: 65 73 65 74 5f 6b 65 79 29 3b 0a 0a 09 77 68 69  eset_key);...whi
6e40: 6c 65 20 28 5f 5f 73 79 6e 63 5f 73 75 62 5f 61  le (__sync_sub_a
6e50: 6e 64 5f 66 65 74 63 68 28 26 69 6e 74 65 72 70  nd_fetch(&interp
6e60: 5f 72 65 73 65 74 5f 6b 65 79 2c 20 31 29 20 3e  _reset_key, 1) >
6e70: 3d 20 30 29 20 7b 0a 09 09 2f 2a 20 42 75 73 79  = 0) {.../* Busy
6e80: 20 4c 6f 6f 70 20 2a 2f 0a 09 7d 0a 0a 09 67 6c   Loop */..}...gl
6e90: 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65  obal_interp_rese
6ea0: 74 5f 6b 65 79 20 3d 20 5f 5f 73 79 6e 63 5f 66  t_key = __sync_f
6eb0: 65 74 63 68 5f 61 6e 64 5f 61 64 64 28 26 69 6e  etch_and_add(&in
6ec0: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20  terp_reset_key, 
6ed0: 30 29 3b 0a 09 69 66 20 28 67 6c 6f 62 61 6c 5f  0);..if (global_
6ee0: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
6ef0: 20 21 3d 20 2d 31 29 20 7b 0a 09 09 41 50 50 46   != -1) {...APPF
6f00: 53 5f 44 45 42 55 47 28 22 45 72 72 6f 72 20 73  S_DEBUG("Error s
6f10: 65 6e 64 69 6e 67 20 6b 69 6c 6c 20 73 69 67 6e  ending kill sign
6f20: 61 6c 20 74 6f 20 61 6c 6c 20 74 68 72 65 61 64  al to all thread
6f30: 73 2c 20 61 62 6f 72 74 69 6e 67 20 61 6e 79 77  s, aborting anyw
6f40: 61 79 2e 22 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  ay.");..}...appf
6f50: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
6f60: 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c 20  cache_flush(-1, 
6f70: 2d 31 29 3b 0a 0a 09 66 75 73 65 5f 65 78 69 74  -1);...fuse_exit
6f80: 28 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65 78  (fuse_get_contex
6f90: 74 28 29 2d 3e 66 75 73 65 29 3b 0a 0a 09 72 65  t()->fuse);...re
6fa0: 74 75 72 6e 3b 0a 7d 0a 0a 23 65 6e 64 69 66 0a  turn;.}..#endif.
6fb0: 0a 23 69 66 20 64 65 66 69 6e 65 64 28 41 50 50  .#if defined(APP
6fc0: 46 53 5f 45 58 45 43 5f 50 41 54 48 5f 45 4e 41  FS_EXEC_PATH_ENA
6fd0: 42 4c 45 5f 4d 41 4a 4f 52 5f 53 45 43 55 52 49  BLE_MAJOR_SECURI
6fe0: 54 59 5f 48 4f 4c 45 29 0a 73 74 61 74 69 63 20  TY_HOLE).static 
6ff0: 76 6f 69 64 20 61 70 70 66 73 5f 72 75 6e 54 63  void appfs_runTc
7000: 6c 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 63  l(const char *sc
7010: 72 69 70 74 2c 20 73 69 7a 65 5f 74 20 73 63 72  ript, size_t scr
7020: 69 70 74 4c 65 6e 29 20 7b 0a 09 54 63 6c 5f 49  iptLen) {..Tcl_I
7030: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09  nterp *interp;..
7040: 54 63 6c 5f 4f 62 6a 20 2a 73 63 72 69 70 74 4f  Tcl_Obj *scriptO
7050: 62 6a 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  bj;..int tcl_ret
7060: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  ;...interp = app
7070: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a  fs_TclInterp();.
7080: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
7090: 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  ULL) {...APPFS_D
70a0: 45 42 55 47 28 22 45 72 72 6f 72 20 63 72 65 61  EBUG("Error crea
70b0: 74 69 6e 67 20 61 6e 20 69 6e 74 65 72 70 72 65  ting an interpre
70c0: 74 65 72 2e 22 29 3b 0a 0a 09 09 72 65 74 75 72  ter.");....retur
70d0: 6e 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61  n;..}...appfs_ca
70e0: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 73 63 72  ll_libtcl(...scr
70f0: 69 70 74 4f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77  iptObj = Tcl_New
7100: 53 74 72 69 6e 67 4f 62 6a 28 73 63 72 69 70 74  StringObj(script
7110: 2c 20 73 63 72 69 70 74 4c 65 6e 29 3b 0a 0a 09  , scriptLen);...
7120: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
7130: 74 28 73 63 72 69 70 74 4f 62 6a 29 3b 0a 09 29  t(scriptObj);..)
7140: 0a 0a 09 69 66 20 28 73 63 72 69 70 74 4f 62 6a  ...if (scriptObj
7150: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50   == NULL) {...AP
7160: 50 46 53 5f 44 45 42 55 47 28 22 45 72 72 6f 72  PFS_DEBUG("Error
7170: 20 63 72 65 61 74 69 6e 67 20 61 20 73 63 72 69   creating a scri
7180: 70 74 20 6f 62 6a 65 63 74 2e 22 29 3b 0a 0a 09  pt object.");...
7190: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 61 70  .return;..}...ap
71a0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
71b0: 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
71c0: 5f 45 76 61 6c 4f 62 6a 45 78 28 69 6e 74 65 72  _EvalObjEx(inter
71d0: 70 2c 20 73 63 72 69 70 74 4f 62 6a 2c 20 54 43  p, scriptObj, TC
71e0: 4c 5f 45 56 41 4c 5f 44 49 52 45 43 54 29 3b 0a  L_EVAL_DIRECT);.
71f0: 09 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75  ..Tcl_DecrRefCou
7200: 6e 74 28 73 63 72 69 70 74 4f 62 6a 29 3b 0a 09  nt(scriptObj);..
7210: 29 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  )...if (tcl_ret 
7220: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 61  != TCL_OK) {...a
7230: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
7240: 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  (....APPFS_DEBUG
7250: 28 22 53 63 72 69 70 74 20 72 65 74 75 72 6e 65  ("Script returne
7260: 64 20 65 72 72 6f 72 20 25 69 3a 20 25 73 22 2c  d error %i: %s",
7270: 20 74 63 6c 5f 72 65 74 2c 20 54 63 6c 5f 47 65   tcl_ret, Tcl_Ge
7280: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
7290: 74 65 72 70 29 29 3b 0a 09 09 29 0a 09 7d 0a 0a  terp));...)..}..
72a0: 09 72 65 74 75 72 6e 3b 0a 7d 0a 23 65 6e 64 69  .return;.}.#endi
72b0: 66 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  f..static int ap
72c0: 70 66 73 5f 66 75 73 65 5f 72 65 61 64 6c 69 6e  pfs_fuse_readlin
72d0: 6b 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  k(const char *pa
72e0: 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c 20 73  th, char *buf, s
72f0: 69 7a 65 5f 74 20 73 69 7a 65 29 20 7b 0a 09 73  ize_t size) {..s
7300: 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68  truct appfs_path
7310: 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09  info pathinfo;..
7320: 69 6e 74 20 72 65 74 76 61 6c 20 3d 20 30 3b 0a  int retval = 0;.
7330: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45  ..APPFS_DEBUG("E
7340: 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c  nter (path = %s,
7350: 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a   ...)", path);..
7360: 09 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d  .pathinfo.type =
7370: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
7380: 49 4e 56 41 4c 49 44 3b 0a 0a 09 72 65 74 76 61  INVALID;...retva
7390: 6c 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61  l = appfs_get_pa
73a0: 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26 70  th_info(path, &p
73b0: 61 74 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 72  athinfo);..if (r
73c0: 65 74 76 61 6c 20 21 3d 20 30 29 20 7b 0a 09 09  etval != 0) {...
73d0: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a  return(retval);.
73e0: 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66  .}...if (pathinf
73f0: 6f 2e 74 79 70 65 20 21 3d 20 41 50 50 46 53 5f  o.type != APPFS_
7400: 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b  PATHTYPE_SYMLINK
7410: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
7420: 4e 56 41 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  NVAL);..}...if (
7430: 28 73 74 72 6c 65 6e 28 70 61 74 68 69 6e 66 6f  (strlen(pathinfo
7440: 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e  .typeinfo.symlin
7450: 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31 29 20 3e  k.source) + 1) >
7460: 20 73 69 7a 65 29 20 7b 0a 09 09 72 65 74 75 72   size) {...retur
7470: 6e 28 2d 45 4e 41 4d 45 54 4f 4f 4c 4f 4e 47 29  n(-ENAMETOOLONG)
7480: 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79 28 62 75  ;..}...memcpy(bu
7490: 66 2c 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65  f, pathinfo.type
74a0: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75  info.symlink.sou
74b0: 72 63 65 2c 20 73 74 72 6c 65 6e 28 70 61 74 68  rce, strlen(path
74c0: 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79  info.typeinfo.sy
74d0: 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 20 2b 20  mlink.source) + 
74e0: 31 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  1);...return(0);
74f0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
7500: 70 70 66 73 5f 66 75 73 65 5f 67 65 74 61 74 74  ppfs_fuse_getatt
7510: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  r(const char *pa
7520: 74 68 2c 20 73 74 72 75 63 74 20 73 74 61 74 20  th, struct stat 
7530: 2a 73 74 62 75 66 29 20 7b 0a 09 73 74 72 75 63  *stbuf) {..struc
7540: 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f  t appfs_pathinfo
7550: 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69 6e 74 20   pathinfo;..int 
7560: 63 68 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65  changeOwnerToUse
7570: 72 49 66 50 61 63 6b 61 67 65 64 3b 0a 09 69 6e  rIfPackaged;..in
7580: 74 20 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76  t retval;...retv
7590: 61 6c 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f  al = 0;...APPFS_
75a0: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
75b0: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
75c0: 70 61 74 68 29 3b 0a 0a 23 69 66 20 28 64 65 66  path);..#if (def
75d0: 69 6e 65 64 28 44 45 42 55 47 29 20 26 26 20 64  ined(DEBUG) && d
75e0: 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58 49  efined(APPFS_EXI
75f0: 54 5f 50 41 54 48 29 29 20 7c 7c 20 64 65 66 69  T_PATH)) || defi
7600: 6e 65 64 28 41 50 50 46 53 5f 45 58 49 54 5f 50  ned(APPFS_EXIT_P
7610: 41 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52  ATH_ENABLE_MAJOR
7620: 5f 53 45 43 55 52 49 54 59 5f 48 4f 4c 45 29 0a  _SECURITY_HOLE).
7630: 09 2f 2a 0a 09 20 2a 20 54 68 69 73 20 69 73 20  ./*.. * This is 
7640: 61 20 6d 61 6a 6f 72 20 73 65 63 75 72 69 74 79  a major security
7650: 20 69 73 73 75 65 20 73 6f 20 77 65 20 63 61 6e   issue so we can
7660: 6e 6f 74 20 6c 65 74 20 69 74 20 62 65 20 63 6f  not let it be co
7670: 6d 70 69 6c 65 64 20 69 6e 74 6f 0a 09 20 2a 20  mpiled into.. * 
7680: 61 6e 79 20 72 65 6c 65 61 73 65 0a 09 20 2a 2f  any release.. */
7690: 0a 09 69 66 20 28 73 74 72 63 6d 70 28 70 61 74  ..if (strcmp(pat
76a0: 68 2c 20 22 2f 65 78 69 74 22 29 20 3d 3d 20 30  h, "/exit") == 0
76b0: 29 20 7b 0a 09 09 61 70 70 66 73 5f 65 78 69 74  ) {...appfs_exit
76c0: 28 29 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 23 69  ();..}.#endif.#i
76d0: 66 20 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f  f defined(APPFS_
76e0: 45 58 45 43 5f 50 41 54 48 5f 45 4e 41 42 4c 45  EXEC_PATH_ENABLE
76f0: 5f 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f  _MAJOR_SECURITY_
7700: 48 4f 4c 45 29 0a 09 69 66 20 28 73 74 72 63 6d  HOLE)..if (strcm
7710: 70 28 70 61 74 68 2c 20 22 2f 65 78 65 63 22 29  p(path, "/exec")
7720: 20 3d 3d 20 30 29 20 7b 0a 09 09 6d 65 6d 73 65   == 0) {...memse
7730: 74 28 73 74 62 75 66 2c 20 30 2c 20 73 69 7a 65  t(stbuf, 0, size
7740: 6f 66 28 73 74 72 75 63 74 20 73 74 61 74 29 29  of(struct stat))
7750: 3b 0a 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d  ;....stbuf->st_m
7760: 74 69 6d 65 20 3d 20 30 3b 0a 09 09 73 74 62 75  time = 0;...stbu
7770: 66 2d 3e 73 74 5f 63 74 69 6d 65 20 3d 20 30 3b  f->st_ctime = 0;
7780: 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f 61 74 69  ...stbuf->st_ati
7790: 6d 65 20 3d 20 30 3b 0a 09 09 73 74 62 75 66 2d  me = 0;...stbuf-
77a0: 3e 73 74 5f 69 6e 6f 20 20 20 3d 20 33 3b 0a 09  >st_ino   = 3;..
77b0: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
77c0: 20 3d 20 30 3b 0a 09 09 73 74 62 75 66 2d 3e 73   = 0;...stbuf->s
77d0: 74 5f 6d 6f 64 65 20 20 3d 20 53 5f 49 46 52 45  t_mode  = S_IFRE
77e0: 47 20 7c 20 30 36 30 30 3b 0a 09 09 73 74 62 75  G | 0600;...stbu
77f0: 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b  f->st_nlink = 1;
7800: 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a  ...stbuf->st_siz
7810: 65 20 20 3d 20 30 3b 0a 0a 09 09 72 65 74 75 72  e  = 0;....retur
7820: 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d 0a 23 65  n(retval);..}.#e
7830: 6e 64 69 66 0a 0a 09 70 61 74 68 69 6e 66 6f 2e  ndif...pathinfo.
7840: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
7850: 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a  HTYPE_INVALID;..
7860: 09 72 65 74 76 61 6c 20 3d 20 61 70 70 66 73 5f  .retval = appfs_
7870: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61  get_path_info(pa
7880: 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a  th, &pathinfo);.
7890: 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20 30  .if (retval != 0
78a0: 29 20 7b 0a 09 09 69 66 20 28 72 65 74 76 61 6c  ) {...if (retval
78b0: 20 3d 3d 20 2d 45 4e 4f 45 4e 54 29 20 7b 0a 09   == -ENOENT) {..
78c0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67  ..APPFS_DEBUG("g
78d0: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20 72 65 74  et_path_info ret
78e0: 75 72 6e 65 64 20 45 4e 4f 45 4e 54 2c 20 72 65  urned ENOENT, re
78f0: 74 75 72 6e 69 6e 67 20 69 74 20 61 73 20 77 65  turning it as we
7900: 6c 6c 2e 22 29 3b 0a 09 09 7d 20 65 6c 73 65 20  ll.");...} else 
7910: 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  {....APPFS_DEBUG
7920: 28 22 65 72 72 6f 72 3a 20 67 65 74 5f 70 61 74  ("error: get_pat
7930: 68 5f 69 6e 66 6f 20 66 61 69 6c 65 64 22 29 3b  h_info failed");
7940: 0a 09 09 7d 0a 0a 09 09 72 65 74 75 72 6e 28 72  ...}....return(r
7950: 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09 6d 65 6d  etval);..}...mem
7960: 73 65 74 28 73 74 62 75 66 2c 20 30 2c 20 73 69  set(stbuf, 0, si
7970: 7a 65 6f 66 28 73 74 72 75 63 74 20 73 74 61 74  zeof(struct stat
7980: 29 29 3b 0a 0a 09 73 74 62 75 66 2d 3e 73 74 5f  ));...stbuf->st_
7990: 6d 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66 6f  mtime = pathinfo
79a0: 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e 73  .time;..stbuf->s
79b0: 74 5f 63 74 69 6d 65 20 3d 20 70 61 74 68 69 6e  t_ctime = pathin
79c0: 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d  fo.time;..stbuf-
79d0: 3e 73 74 5f 61 74 69 6d 65 20 3d 20 70 61 74 68  >st_atime = path
79e0: 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75  info.time;..stbu
79f0: 66 2d 3e 73 74 5f 69 6e 6f 20 20 20 3d 20 70 61  f->st_ino   = pa
7a00: 74 68 69 6e 66 6f 2e 69 6e 6f 64 65 3b 0a 09 73  thinfo.inode;..s
7a10: 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 20 3d  tbuf->st_mode  =
7a20: 20 30 3b 0a 0a 09 63 68 61 6e 67 65 4f 77 6e 65   0;...changeOwne
7a30: 72 54 6f 55 73 65 72 49 66 50 61 63 6b 61 67 65  rToUserIfPackage
7a40: 64 20 3d 20 31 3b 0a 0a 09 73 77 69 74 63 68 20  d = 1;...switch 
7a50: 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 29 20  (pathinfo.type) 
7a60: 7b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50  {...case APPFS_P
7a70: 41 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52  ATHTYPE_DIRECTOR
7a80: 59 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  Y:....stbuf->st_
7a90: 6d 6f 64 65 20 3d 20 53 5f 49 46 44 49 52 20 7c  mode = S_IFDIR |
7aa0: 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d   0555;....stbuf-
7ab0: 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 32 20 2b 20  >st_nlink = 2 + 
7ac0: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66  pathinfo.typeinf
7ad0: 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74  o.dir.childcount
7ae0: 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61  ;....break;...ca
7af0: 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50  se APPFS_PATHTYP
7b00: 45 5f 46 49 4c 45 3a 0a 09 09 09 73 74 62 75 66  E_FILE:....stbuf
7b10: 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46  ->st_mode = S_IF
7b20: 52 45 47 20 7c 20 30 34 34 34 3b 0a 0a 09 09 09  REG | 0444;.....
7b30: 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70  if (pathinfo.typ
7b40: 65 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75  einfo.file.execu
7b50: 74 61 62 6c 65 29 20 7b 0a 09 09 09 09 73 74 62  table) {.....stb
7b60: 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 7c 3d 20 30  uf->st_mode |= 0
7b70: 31 31 31 3b 0a 09 09 09 7d 0a 0a 09 09 09 69 66  111;....}.....if
7b80: 20 28 70 61 74 68 69 6e 66 6f 2e 70 61 63 6b 61   (pathinfo.packa
7b90: 67 65 64 29 20 7b 0a 09 09 09 09 69 66 20 28 70  ged) {.....if (p
7ba0: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
7bb0: 2e 66 69 6c 65 2e 73 75 69 64 52 6f 6f 74 29 20  .file.suidRoot) 
7bc0: 7b 0a 09 09 09 09 09 63 68 61 6e 67 65 4f 77 6e  {......changeOwn
7bd0: 65 72 54 6f 55 73 65 72 49 66 50 61 63 6b 61 67  erToUserIfPackag
7be0: 65 64 20 3d 20 30 3b 0a 0a 09 09 09 09 09 73 74  ed = 0;.......st
7bf0: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 7c 3d 20  buf->st_mode |= 
7c00: 30 34 30 30 30 3b 0a 09 09 09 09 7d 0a 09 09 09  04000;.....}....
7c10: 7d 0a 0a 09 09 09 69 66 20 28 70 61 74 68 69 6e  }.....if (pathin
7c20: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  fo.typeinfo.file
7c30: 2e 77 6f 72 6c 64 61 63 63 65 73 73 69 62 6c 65  .worldaccessible
7c40: 29 20 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e 73  ) {.....stbuf->s
7c50: 74 5f 6d 6f 64 65 20 26 3d 20 7e 30 37 37 3b 0a  t_mode &= ~077;.
7c60: 09 09 09 7d 0a 0a 09 09 09 73 74 62 75 66 2d 3e  ...}.....stbuf->
7c70: 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09  st_nlink = 1;...
7c80: 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20  .stbuf->st_size 
7c90: 3d 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69  = pathinfo.typei
7ca0: 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 3b 0a 0a  nfo.file.size;..
7cb0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65  ...break;...case
7cc0: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
7cd0: 53 59 4d 4c 49 4e 4b 3a 0a 09 09 09 73 74 62 75  SYMLINK:....stbu
7ce0: 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49  f->st_mode = S_I
7cf0: 46 4c 4e 4b 20 7c 20 30 35 35 35 3b 0a 09 09 09  FLNK | 0555;....
7d00: 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20  stbuf->st_nlink 
7d10: 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  = 1;....stbuf->s
7d20: 74 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e 66  t_size = pathinf
7d30: 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69  o.typeinfo.symli
7d40: 6e 6b 2e 73 69 7a 65 3b 0a 09 09 09 62 72 65 61  nk.size;....brea
7d50: 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f  k;...case APPFS_
7d60: 50 41 54 48 54 59 50 45 5f 53 4f 43 4b 45 54 3a  PATHTYPE_SOCKET:
7d70: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
7d80: 64 65 20 3d 20 53 5f 49 46 53 4f 43 4b 20 7c 20  de = S_IFSOCK | 
7d90: 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e  0555;....stbuf->
7da0: 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09  st_nlink = 1;...
7db0: 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20  .stbuf->st_size 
7dc0: 3d 20 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09  = 0;....break;..
7dd0: 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48  .case APPFS_PATH
7de0: 54 59 50 45 5f 46 49 46 4f 3a 0a 09 09 09 73 74  TYPE_FIFO:....st
7df0: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53  buf->st_mode = S
7e00: 5f 49 46 49 46 4f 20 7c 20 30 35 35 35 3b 0a 09  _IFIFO | 0555;..
7e10: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e  ..stbuf->st_nlin
7e20: 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d  k = 1;....stbuf-
7e30: 3e 73 74 5f 73 69 7a 65 20 3d 20 30 3b 0a 09 09  >st_size = 0;...
7e40: 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41  .break;...case A
7e50: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 4f  PPFS_PATHTYPE_DO
7e60: 45 53 5f 4e 4f 54 5f 45 58 49 53 54 3a 0a 09 09  ES_NOT_EXIST:...
7e70: 09 72 65 74 76 61 6c 20 3d 20 2d 45 4e 4f 45 4e  .retval = -ENOEN
7e80: 54 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09  T;.....break;...
7e90: 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54  case APPFS_PATHT
7ea0: 59 50 45 5f 49 4e 56 41 4c 49 44 3a 0a 09 09 09  YPE_INVALID:....
7eb0: 72 65 74 76 61 6c 20 3d 20 2d 45 49 4f 3b 0a 0a  retval = -EIO;..
7ec0: 09 09 09 62 72 65 61 6b 3b 0a 09 7d 0a 0a 09 69  ...break;..}...i
7ed0: 66 20 28 28 70 61 74 68 69 6e 66 6f 2e 70 61 63  f ((pathinfo.pac
7ee0: 6b 61 67 65 64 20 26 26 20 63 68 61 6e 67 65 4f  kaged && changeO
7ef0: 77 6e 65 72 54 6f 55 73 65 72 49 66 50 61 63 6b  wnerToUserIfPack
7f00: 61 67 65 64 29 20 7c 7c 20 28 21 70 61 74 68 69  aged) || (!pathi
7f10: 6e 66 6f 2e 70 61 63 6b 61 67 65 64 29 29 20 7b  nfo.packaged)) {
7f20: 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f 75 69 64  ...stbuf->st_uid
7f30: 20 20 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66     = appfs_get_f
7f40: 73 75 69 64 28 29 3b 0a 09 09 73 74 62 75 66 2d  suid();...stbuf-
7f50: 3e 73 74 5f 67 69 64 20 20 20 3d 20 61 70 70 66  >st_gid   = appf
7f60: 73 5f 67 65 74 5f 66 73 67 69 64 28 29 3b 0a 09  s_get_fsgid();..
7f70: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
7f80: 7c 3d 20 30 32 30 30 3b 0a 09 7d 0a 0a 09 72 65  |= 0200;..}...re
7f90: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a  turn(retval);.}.
7fa0: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
7fb0: 73 5f 66 75 73 65 5f 72 65 61 64 64 69 72 28 63  s_fuse_readdir(c
7fc0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
7fd0: 20 76 6f 69 64 20 2a 62 75 66 2c 20 66 75 73 65   void *buf, fuse
7fe0: 5f 66 69 6c 6c 5f 64 69 72 5f 74 20 66 69 6c 6c  _fill_dir_t fill
7ff0: 65 72 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74  er, off_t offset
8000: 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69  , struct fuse_fi
8010: 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09  le_info *fi) {..
8020: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
8030: 72 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a 63  rp;..Tcl_Obj **c
8040: 68 69 6c 64 72 65 6e 3b 0a 09 69 6e 74 20 63 68  hildren;..int ch
8050: 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c 20 69 64  ildren_count, id
8060: 78 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b  x;..int tcl_ret;
8070: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
8080: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
8090: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
80a0: 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
80b0: 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69  _TclInterp();..i
80c0: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
80d0: 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  L) {...APPFS_DEB
80e0: 55 47 28 22 65 72 72 6f 72 3a 20 55 6e 61 62 6c  UG("error: Unabl
80f0: 65 20 74 6f 20 67 65 74 20 61 6e 20 69 6e 74 65  e to get an inte
8100: 72 70 72 65 74 65 72 22 29 3b 0a 0a 09 09 72 65  rpreter");....re
8110: 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 61 70  turn(0);..}...ap
8120: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
8130: 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74  Tcl_Preserve(int
8140: 65 72 70 29 3b 29 0a 0a 09 66 69 6c 6c 65 72 28  erp);)...filler(
8150: 62 75 66 2c 20 22 2e 22 2c 20 4e 55 4c 4c 2c 20  buf, ".", NULL, 
8160: 30 29 3b 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c  0);..filler(buf,
8170: 20 22 2e 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b   "..", NULL, 0);
8180: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70  ...tcl_ret = app
8190: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65  fs_Tcl_Eval(inte
81a0: 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a  rp, 2, "::appfs:
81b0: 3a 67 65 74 63 68 69 6c 64 72 65 6e 22 2c 20 70  :getchildren", p
81c0: 61 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72  ath);..if (tcl_r
81d0: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
81e0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a  ..APPFS_DEBUG(":
81f0: 3a 61 70 70 66 73 3a 3a 67 65 74 63 68 69 6c 64  :appfs::getchild
8200: 72 65 6e 28 25 73 29 20 66 61 69 6c 65 64 2e 22  ren(%s) failed."
8210: 2c 20 70 61 74 68 29 3b 0a 09 09 61 70 70 66 73  , path);...appfs
8220: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
8230: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63  .APPFS_DEBUG("Tc
8240: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c  l Error is: %s",
8250: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
8260: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09  sult(interp));..
8270: 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  .)....appfs_call
8280: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
8290: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
82a0: 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a  .return(0);..}..
82b0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
82c0: 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20  cl(...tcl_ret = 
82d0: 54 63 6c 5f 4c 69 73 74 4f 62 6a 47 65 74 45 6c  Tcl_ListObjGetEl
82e0: 65 6d 65 6e 74 73 28 69 6e 74 65 72 70 2c 20 54  ements(interp, T
82f0: 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_GetObjResult(
8300: 69 6e 74 65 72 70 29 2c 20 26 63 68 69 6c 64 72  interp), &childr
8310: 65 6e 5f 63 6f 75 6e 74 2c 20 26 63 68 69 6c 64  en_count, &child
8320: 72 65 6e 29 3b 0a 09 29 0a 09 69 66 20 28 74 63  ren);..)..if (tc
8330: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
8340: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
8350: 28 22 50 61 72 73 69 6e 67 20 6c 69 73 74 20 6f  ("Parsing list o
8360: 66 20 63 68 69 6c 64 72 65 6e 20 6f 6e 20 70 61  f children on pa
8370: 74 68 20 25 73 20 66 61 69 6c 65 64 2e 22 2c 20  th %s failed.", 
8380: 70 61 74 68 29 3b 0a 09 09 61 70 70 66 73 5f 63  path);...appfs_c
8390: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41  all_libtcl(....A
83a0: 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20  PPFS_DEBUG("Tcl 
83b0: 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54  Error is: %s", T
83c0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
83d0: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29  lt(interp));...)
83e0: 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
83f0: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
8400: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72  e(interp);)....r
8410: 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 66  eturn(0);..}...f
8420: 6f 72 20 28 69 64 78 20 3d 20 30 3b 20 69 64 78  or (idx = 0; idx
8430: 20 3c 20 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e   < children_coun
8440: 74 3b 20 69 64 78 2b 2b 29 20 7b 0a 09 09 61 70  t; idx++) {...ap
8450: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
8460: 0a 09 09 09 66 69 6c 6c 65 72 28 62 75 66 2c 20  ....filler(buf, 
8470: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 63 68  Tcl_GetString(ch
8480: 69 6c 64 72 65 6e 5b 69 64 78 5d 29 2c 20 4e 55  ildren[idx]), NU
8490: 4c 4c 2c 20 30 29 3b 0a 09 09 29 0a 09 7d 0a 0a  LL, 0);...)..}..
84a0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
84b0: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
84c0: 6e 74 65 72 70 29 3b 29 0a 0a 09 72 65 74 75 72  nterp);)...retur
84d0: 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n(0);.}..static 
84e0: 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 6f  int appfs_fuse_o
84f0: 70 65 6e 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  pen(const char *
8500: 70 61 74 68 2c 20 73 74 72 75 63 74 20 66 75 73  path, struct fus
8510: 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29  e_file_info *fi)
8520: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
8530: 69 6e 74 65 72 70 3b 0a 09 73 74 72 75 63 74 20  interp;..struct 
8540: 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70  appfs_pathinfo p
8550: 61 74 68 69 6e 66 6f 3b 0a 09 63 6f 6e 73 74 20  athinfo;..const 
8560: 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 2c  char *real_path,
8570: 20 2a 6d 6f 64 65 3b 0a 09 69 6e 74 20 67 70 69   *mode;..int gpi
8580: 5f 72 65 74 2c 20 74 63 6c 5f 72 65 74 3b 0a 09  _ret, tcl_ret;..
8590: 69 6e 74 20 66 68 3b 0a 0a 09 41 50 50 46 53 5f  int fh;...APPFS_
85a0: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
85b0: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
85c0: 70 61 74 68 29 3b 0a 0a 23 69 66 20 64 65 66 69  path);..#if defi
85d0: 6e 65 64 28 41 50 50 46 53 5f 45 58 45 43 5f 50  ned(APPFS_EXEC_P
85e0: 41 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52  ATH_ENABLE_MAJOR
85f0: 5f 53 45 43 55 52 49 54 59 5f 48 4f 4c 45 29 0a  _SECURITY_HOLE).
8600: 09 69 66 20 28 73 74 72 63 6d 70 28 70 61 74 68  .if (strcmp(path
8610: 2c 20 22 2f 65 78 65 63 22 29 20 3d 3d 20 30 29  , "/exec") == 0)
8620: 20 7b 0a 09 09 66 69 2d 3e 66 68 20 3d 20 30 3b   {...fi->fh = 0;
8630: 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09  ....return(0);..
8640: 7d 0a 23 65 6e 64 69 66 0a 0a 09 67 70 69 5f 72  }.#endif...gpi_r
8650: 65 74 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 70  et = appfs_get_p
8660: 61 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26  ath_info(path, &
8670: 70 61 74 68 69 6e 66 6f 29 3b 0a 0a 09 69 66 20  pathinfo);...if 
8680: 28 28 66 69 2d 3e 66 6c 61 67 73 20 26 20 28 4f  ((fi->flags & (O
8690: 5f 57 52 4f 4e 4c 59 7c 4f 5f 43 52 45 41 54 29  _WRONLY|O_CREAT)
86a0: 29 20 3d 3d 20 28 4f 5f 43 52 45 41 54 7c 4f 5f  ) == (O_CREAT|O_
86b0: 57 52 4f 4e 4c 59 29 29 20 7b 0a 09 09 2f 2a 20  WRONLY)) {.../* 
86c0: 54 68 65 20 66 69 6c 65 20 77 69 6c 6c 20 62 65  The file will be
86d0: 20 63 72 65 61 74 65 64 20 69 66 20 69 74 20 64   created if it d
86e0: 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20 2a 2f  oes not exist */
86f0: 0a 09 09 69 66 20 28 67 70 69 5f 72 65 74 20 21  ...if (gpi_ret !
8700: 3d 20 30 20 26 26 20 67 70 69 5f 72 65 74 20 21  = 0 && gpi_ret !
8710: 3d 20 2d 45 4e 4f 45 4e 54 29 20 7b 0a 09 09 09  = -ENOENT) {....
8720: 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72  APPFS_DEBUG("err
8730: 6f 72 3a 20 67 65 74 5f 70 61 74 68 5f 69 6e 66  or: get_path_inf
8740: 6f 20 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09 09  o failed");.....
8750: 72 65 74 75 72 6e 28 67 70 69 5f 72 65 74 29 3b  return(gpi_ret);
8760: 0a 09 09 7d 0a 0a 09 09 6d 6f 64 65 20 3d 20 22  ...}....mode = "
8770: 63 72 65 61 74 65 22 3b 0a 0a 09 09 2f 2a 0a 09  create";..../*..
8780: 09 20 2a 20 57 65 20 68 61 76 65 20 74 6f 20 63  . * We have to c
8790: 6c 65 61 72 20 74 68 65 20 63 61 63 68 65 20 68  lear the cache h
87a0: 65 72 65 20 73 6f 20 74 68 61 74 20 74 68 65 20  ere so that the 
87b0: 6e 75 6d 62 65 72 20 6f 66 0a 09 09 20 2a 20 6c  number of... * l
87c0: 69 6e 6b 73 20 67 65 74 73 20 6d 61 69 6e 74 61  inks gets mainta
87d0: 69 6e 65 64 20 6f 6e 20 74 68 65 20 70 61 72 65  ined on the pare
87e0: 6e 74 20 64 69 72 65 63 74 6f 72 79 0a 09 09 20  nt directory... 
87f0: 2a 2f 0a 09 09 61 70 70 66 73 5f 67 65 74 5f 70  */...appfs_get_p
8800: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66  ath_info_cache_f
8810: 6c 75 73 68 28 61 70 70 66 73 5f 67 65 74 5f 66  lush(appfs_get_f
8820: 73 75 69 64 28 29 2c 20 2d 31 29 3b 0a 09 7d 20  suid(), -1);..} 
8830: 65 6c 73 65 20 7b 0a 09 09 2f 2a 20 54 68 65 20  else {.../* The 
8840: 66 69 6c 65 20 6d 75 73 74 20 61 6c 72 65 61 64  file must alread
8850: 79 20 65 78 69 73 74 20 2a 2f 0a 09 09 69 66 20  y exist */...if 
8860: 28 67 70 69 5f 72 65 74 20 21 3d 20 30 29 20 7b  (gpi_ret != 0) {
8870: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
8880: 22 65 72 72 6f 72 3a 20 67 65 74 5f 70 61 74 68  "error: get_path
8890: 5f 69 6e 66 6f 20 66 61 69 6c 65 64 22 29 3b 0a  _info failed");.
88a0: 0a 09 09 09 72 65 74 75 72 6e 28 67 70 69 5f 72  ....return(gpi_r
88b0: 65 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d 6f 64 65  et);...}....mode
88c0: 20 3d 20 22 22 3b 0a 0a 09 09 69 66 20 28 28 66   = "";....if ((f
88d0: 69 2d 3e 66 6c 61 67 73 20 26 20 4f 5f 57 52 4f  i->flags & O_WRO
88e0: 4e 4c 59 29 20 3d 3d 20 4f 5f 57 52 4f 4e 4c 59  NLY) == O_WRONLY
88f0: 29 20 7b 0a 09 09 09 6d 6f 64 65 20 3d 20 22 77  ) {....mode = "w
8900: 72 69 74 65 22 3b 0a 09 09 7d 0a 09 7d 0a 0a 09  rite";...}..}...
8910: 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70  if (pathinfo.typ
8920: 65 20 3d 3d 20 41 50 50 46 53 5f 50 41 54 48 54  e == APPFS_PATHT
8930: 59 50 45 5f 44 49 52 45 43 54 4f 52 59 29 20 7b  YPE_DIRECTORY) {
8940: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
8950: 65 72 72 6f 72 3a 20 41 73 6b 65 64 20 74 6f 20  error: Asked to 
8960: 6f 70 65 6e 20 61 20 64 69 72 65 63 74 6f 72 79  open a directory
8970: 2e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d  .");....return(-
8980: 45 49 53 44 49 52 29 3b 0a 09 7d 0a 0a 09 69 6e  EISDIR);..}...in
8990: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c  terp = appfs_Tcl
89a0: 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69  Interp();..if (i
89b0: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
89c0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
89d0: 65 72 72 6f 72 3a 20 55 6e 61 62 6c 65 20 74 6f  error: Unable to
89e0: 20 67 65 74 20 61 6e 20 69 6e 74 65 72 70 72 65   get an interpre
89f0: 74 65 72 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  ter");....return
8a00: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70  (-EIO);..}...app
8a10: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
8a20: 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65  cl_Preserve(inte
8a30: 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72 65 74 20  rp);)...tcl_ret 
8a40: 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c  = appfs_Tcl_Eval
8a50: 28 69 6e 74 65 72 70 2c 20 33 2c 20 22 3a 3a 61  (interp, 3, "::a
8a60: 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 22 2c  ppfs::openpath",
8a70: 20 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 09 69   path, mode);..i
8a80: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
8a90: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
8aa0: 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a  DEBUG("::appfs::
8ab0: 6f 70 65 6e 70 61 74 68 28 25 73 2c 20 25 73 29  openpath(%s, %s)
8ac0: 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 2c   failed.", path,
8ad0: 20 6d 6f 64 65 29 3b 0a 09 09 61 70 70 66 73 5f   mode);...appfs_
8ae0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
8af0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c  APPFS_DEBUG("Tcl
8b00: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20   Error is: %s", 
8b10: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
8b20: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
8b30: 29 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  )....appfs_call_
8b40: 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61  libtcl(Tcl_Relea
8b50: 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09  se(interp);)....
8b60: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
8b70: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
8b80: 62 74 63 6c 28 0a 09 09 72 65 61 6c 5f 70 61 74  btcl(...real_pat
8b90: 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  h = Tcl_GetStrin
8ba0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  gResult(interp);
8bb0: 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..)...appfs_call
8bc0: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
8bd0: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
8be0: 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d  if (real_path ==
8bf0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53   NULL) {...APPFS
8c00: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 72  _DEBUG("error: r
8c10: 65 61 6c 5f 70 61 74 68 20 77 61 73 20 4e 55 4c  eal_path was NUL
8c20: 4c 2e 22 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d  L.")....return(-
8c30: 45 49 4f 29 3b 0a 09 7d 0a 0a 09 41 50 50 46 53  EIO);..}...APPFS
8c40: 5f 44 45 42 55 47 28 22 54 72 61 6e 73 6c 61 74  _DEBUG("Translat
8c50: 65 64 20 72 65 71 75 65 73 74 20 74 6f 20 6f 70  ed request to op
8c60: 65 6e 20 25 73 20 74 6f 20 6f 70 65 6e 69 6e 67  en %s to opening
8c70: 20 25 73 20 28 6d 6f 64 65 20 3d 20 5c 22 25 73   %s (mode = \"%s
8c80: 5c 22 29 22 2c 20 70 61 74 68 2c 20 72 65 61 6c  \")", path, real
8c90: 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09  _path, mode);...
8ca0: 66 68 20 3d 20 6f 70 65 6e 28 72 65 61 6c 5f 70  fh = open(real_p
8cb0: 61 74 68 2c 20 66 69 2d 3e 66 6c 61 67 73 2c 20  ath, fi->flags, 
8cc0: 30 36 30 30 29 3b 0a 0a 09 69 66 20 28 66 68 20  0600);...if (fh 
8cd0: 3c 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  < 0) {...APPFS_D
8ce0: 45 42 55 47 28 22 65 72 72 6f 72 3a 20 6f 70 65  EBUG("error: ope
8cf0: 6e 20 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09 72  n failed");....r
8d00: 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31  eturn(errno * -1
8d10: 29 3b 0a 09 7d 0a 0a 09 66 69 2d 3e 66 68 20 3d  );..}...fi->fh =
8d20: 20 66 68 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42   fh;...APPFS_DEB
8d30: 55 47 28 22 4f 70 65 6e 65 64 20 5c 22 25 73 5c  UG("Opened \"%s\
8d40: 22 20 28 66 6f 72 20 5c 22 25 73 5c 22 29 20 77  " (for \"%s\") w
8d50: 69 74 68 20 66 69 6c 65 20 64 65 73 63 72 69 70  ith file descrip
8d60: 74 6f 72 20 25 69 22 2c 20 72 65 61 6c 5f 70 61  tor %i", real_pa
8d70: 74 68 2c 20 70 61 74 68 2c 20 66 68 29 3b 0a 0a  th, path, fh);..
8d80: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
8d90: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
8da0: 66 75 73 65 5f 63 6c 6f 73 65 28 63 6f 6e 73 74  fuse_close(const
8db0: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72   char *path, str
8dc0: 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e  uct fuse_file_in
8dd0: 66 6f 20 2a 66 69 29 20 7b 0a 09 69 6e 74 20 63  fo *fi) {..int c
8de0: 6c 6f 73 65 5f 72 65 74 3b 0a 0a 09 41 50 50 46  lose_ret;...APPF
8df0: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
8e00: 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22  path = %s, ...)"
8e10: 2c 20 70 61 74 68 29 3b 0a 0a 23 69 66 20 64 65  , path);..#if de
8e20: 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58 45 43  fined(APPFS_EXEC
8e30: 5f 50 41 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a  _PATH_ENABLE_MAJ
8e40: 4f 52 5f 53 45 43 55 52 49 54 59 5f 48 4f 4c 45  OR_SECURITY_HOLE
8e50: 29 0a 09 69 66 20 28 73 74 72 63 6d 70 28 70 61  )..if (strcmp(pa
8e60: 74 68 2c 20 22 2f 65 78 65 63 22 29 20 3d 3d 20  th, "/exec") == 
8e70: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 30 29  0) {...return(0)
8e80: 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 61 70  ;..}.#endif...ap
8e90: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
8ea0: 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c  o_cache_rm(path,
8eb0: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
8ec0: 28 29 29 3b 0a 0a 09 63 6c 6f 73 65 5f 72 65 74  ());...close_ret
8ed0: 20 3d 20 63 6c 6f 73 65 28 66 69 2d 3e 66 68 29   = close(fi->fh)
8ee0: 3b 0a 09 69 66 20 28 63 6c 6f 73 65 5f 72 65 74  ;..if (close_ret
8ef0: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53   != 0) {...APPFS
8f00: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 63  _DEBUG("error: c
8f10: 6c 6f 73 65 20 66 61 69 6c 65 64 22 29 3b 0a 0a  lose failed");..
8f20: 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a  ..return(errno *
8f30: 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72   -1);..}...retur
8f40: 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n(0);.}..static 
8f50: 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72  int appfs_fuse_r
8f60: 65 61 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ead(const char *
8f70: 70 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c  path, char *buf,
8f80: 20 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f 66   size_t size, of
8f90: 66 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75  f_t offset, stru
8fa0: 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66  ct fuse_file_inf
8fb0: 6f 20 2a 66 69 29 20 7b 0a 09 73 73 69 7a 65 5f  o *fi) {..ssize_
8fc0: 74 20 72 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74  t read_ret;..int
8fd0: 20 72 65 74 76 61 6c 3b 0a 0a 09 41 50 50 46 53   retval;...APPFS
8fe0: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
8ff0: 61 74 68 20 3d 20 25 73 2c 20 62 75 66 2c 20 73  ath = %s, buf, s
9000: 69 7a 65 20 3d 20 25 6c 6c 69 2c 20 6f 66 66 73  ize = %lli, offs
9010: 65 74 20 3d 20 25 6c 6c 69 2c 20 66 64 20 3d 20  et = %lli, fd = 
9020: 25 6c 6c 69 29 22 2c 20 70 61 74 68 2c 20 28 6c  %lli)", path, (l
9030: 6f 6e 67 20 6c 6f 6e 67 29 20 73 69 7a 65 2c 20  ong long) size, 
9040: 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 6f 66 66 73  (long long) offs
9050: 65 74 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20  et, (long long) 
9060: 66 69 2d 3e 66 68 29 3b 0a 0a 09 72 65 74 76 61  fi->fh);...retva
9070: 6c 20 3d 20 30 3b 0a 0a 09 77 68 69 6c 65 20 28  l = 0;...while (
9080: 73 69 7a 65 20 21 3d 20 30 29 20 7b 0a 23 69 66  size != 0) {.#if
9090: 64 65 66 20 41 50 50 46 53 5f 4e 4f 5f 50 52 45  def APPFS_NO_PRE
90a0: 41 44 20 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a 20  AD /* XXX:TODO: 
90b0: 57 72 69 74 65 20 61 20 77 72 61 70 70 65 72 20  Write a wrapper 
90c0: 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 09 09 6f 66  function */...of
90d0: 66 5f 74 20 73 65 65 6b 5f 72 65 74 3b 0a 0a 09  f_t seek_ret;...
90e0: 09 73 65 65 6b 5f 72 65 74 20 3d 20 6c 73 65 65  .seek_ret = lsee
90f0: 6b 28 66 69 2d 3e 66 68 2c 20 6f 66 66 73 65 74  k(fi->fh, offset
9100: 2c 20 53 45 45 4b 5f 53 45 54 29 3b 0a 09 09 69  , SEEK_SET);...i
9110: 66 20 28 73 65 65 6b 5f 72 65 74 20 3d 3d 20 6f  f (seek_ret == o
9120: 66 66 73 65 74 29 20 7b 0a 09 09 09 72 65 61 64  ffset) {....read
9130: 5f 72 65 74 20 3d 20 72 65 61 64 28 66 69 2d 3e  _ret = read(fi->
9140: 66 68 2c 20 62 75 66 2c 20 73 69 7a 65 29 3b 0a  fh, buf, size);.
9150: 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 72 65  ..} else {....re
9160: 61 64 5f 72 65 74 20 3d 20 2d 31 3b 0a 09 09 7d  ad_ret = -1;...}
9170: 0a 23 65 6c 73 65 0a 09 09 72 65 61 64 5f 72 65  .#else...read_re
9180: 74 20 3d 20 70 72 65 61 64 28 66 69 2d 3e 66 68  t = pread(fi->fh
9190: 2c 20 62 75 66 2c 20 73 69 7a 65 2c 20 6f 66 66  , buf, size, off
91a0: 73 65 74 29 3b 0a 23 65 6e 64 69 66 0a 0a 09 09  set);.#endif....
91b0: 69 66 20 28 72 65 61 64 5f 72 65 74 20 3c 20 30  if (read_ret < 0
91c0: 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42  ) {....APPFS_DEB
91d0: 55 47 28 22 65 72 72 6f 72 3a 20 72 65 61 64 20  UG("error: read 
91e0: 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09 09 72 65  failed");.....re
91f0: 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29  turn(errno * -1)
9200: 3b 0a 09 09 7d 0a 0a 09 09 69 66 20 28 72 65 61  ;...}....if (rea
9210: 64 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09 09  d_ret == 0) {...
9220: 09 62 72 65 61 6b 3b 0a 09 09 7d 0a 0a 09 09 73  .break;...}....s
9230: 69 7a 65 20 2d 3d 20 72 65 61 64 5f 72 65 74 3b  ize -= read_ret;
9240: 0a 09 09 62 75 66 20 20 2b 3d 20 72 65 61 64 5f  ...buf  += read_
9250: 72 65 74 3b 0a 09 09 6f 66 66 73 65 74 20 2b 3d  ret;...offset +=
9260: 20 72 65 61 64 5f 72 65 74 3b 0a 09 09 72 65 74   read_ret;...ret
9270: 76 61 6c 20 2b 3d 20 72 65 61 64 5f 72 65 74 3b  val += read_ret;
9280: 0a 09 7d 0a 0a 09 69 66 20 28 73 69 7a 65 20 21  ..}...if (size !
9290: 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  = 0) {...APPFS_D
92a0: 45 42 55 47 28 22 65 72 72 6f 72 3a 20 69 6e 63  EBUG("error: inc
92b0: 6f 6d 70 6c 65 74 65 20 72 65 61 64 20 28 74 68  omplete read (th
92c0: 69 73 20 6d 69 67 68 74 20 62 65 20 61 6e 20 65  is might be an e
92d0: 72 72 6f 72 20 62 65 63 61 75 73 65 20 46 55 53  rror because FUS
92e0: 45 20 77 69 6c 6c 20 72 65 71 75 65 73 74 20 74  E will request t
92f0: 68 65 20 65 78 61 63 74 20 6c 65 6e 67 74 68 20  he exact length 
9300: 6f 66 20 74 68 65 20 66 69 6c 65 29 22 29 3b 0a  of the file)");.
9310: 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  .}...APPFS_DEBUG
9320: 28 22 52 65 74 75 72 6e 69 6e 67 3a 20 25 69 22  ("Returning: %i"
9330: 2c 20 72 65 74 76 61 6c 29 3b 0a 0a 09 72 65 74  , retval);...ret
9340: 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a  urn(retval);.}..
9350: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
9360: 5f 66 75 73 65 5f 77 72 69 74 65 28 63 6f 6e 73  _fuse_write(cons
9370: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 63 6f  t char *path, co
9380: 6e 73 74 20 63 68 61 72 20 2a 62 75 66 2c 20 73  nst char *buf, s
9390: 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f 66 66 5f  ize_t size, off_
93a0: 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63 74  t offset, struct
93b0: 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20   fuse_file_info 
93c0: 2a 66 69 29 20 7b 0a 09 73 73 69 7a 65 5f 74 20  *fi) {..ssize_t 
93d0: 77 72 69 74 65 5f 72 65 74 3b 0a 09 69 6e 74 20  write_ret;..int 
93e0: 72 65 74 76 61 6c 3b 0a 0a 09 41 50 50 46 53 5f  retval;...APPFS_
93f0: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
9400: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
9410: 70 61 74 68 29 3b 0a 0a 23 69 66 20 64 65 66 69  path);..#if defi
9420: 6e 65 64 28 41 50 50 46 53 5f 45 58 45 43 5f 50  ned(APPFS_EXEC_P
9430: 41 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52  ATH_ENABLE_MAJOR
9440: 5f 53 45 43 55 52 49 54 59 5f 48 4f 4c 45 29 0a  _SECURITY_HOLE).
9450: 09 69 66 20 28 73 74 72 63 6d 70 28 70 61 74 68  .if (strcmp(path
9460: 2c 20 22 2f 65 78 65 63 22 29 20 3d 3d 20 30 29  , "/exec") == 0)
9470: 20 7b 0a 09 09 61 70 70 66 73 5f 72 75 6e 54 63   {...appfs_runTc
9480: 6c 28 62 75 66 2c 20 73 69 7a 65 29 3b 0a 0a 09  l(buf, size);...
9490: 09 72 65 74 75 72 6e 28 73 69 7a 65 29 3b 0a 09  .return(size);..
94a0: 7d 0a 23 65 6e 64 69 66 0a 0a 09 61 70 70 66 73  }.#endif...appfs
94b0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
94c0: 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70  ache_rm(path, ap
94d0: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29  pfs_get_fsuid())
94e0: 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a  ;...retval = 0;.
94f0: 0a 09 77 68 69 6c 65 20 28 73 69 7a 65 20 21 3d  ..while (size !=
9500: 20 30 29 20 7b 0a 23 69 66 64 65 66 20 41 50 50   0) {.#ifdef APP
9510: 46 53 5f 4e 4f 5f 50 57 52 49 54 45 20 2f 2a 20  FS_NO_PWRITE /* 
9520: 58 58 58 3a 54 4f 44 4f 3a 20 57 72 69 74 65 20  XXX:TODO: Write 
9530: 61 20 77 72 61 70 70 65 72 20 66 75 6e 63 74 69  a wrapper functi
9540: 6f 6e 20 2a 2f 0a 23 20 20 69 66 20 31 0a 09 09  on */.#  if 1...
9550: 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a 20 53 74 69  /* XXX:TODO: Sti
9560: 6c 6c 20 66 61 69 6c 73 20 6f 6e 20 77 69 6e 33  ll fails on win3
9570: 32 20 2a 2f 0a 09 09 77 72 69 74 65 5f 72 65 74  2 */...write_ret
9580: 20 3d 20 2d 31 3b 0a 23 65 6c 73 65 0a 09 09 6f   = -1;.#else...o
9590: 66 66 5f 74 20 73 65 65 6b 5f 72 65 74 3b 0a 0a  ff_t seek_ret;..
95a0: 09 09 73 65 65 6b 5f 72 65 74 20 3d 20 6c 73 65  ..seek_ret = lse
95b0: 65 6b 28 66 69 2d 3e 66 68 2c 20 6f 66 66 73 65  ek(fi->fh, offse
95c0: 74 2c 20 53 45 45 4b 5f 53 45 54 29 3b 0a 09 09  t, SEEK_SET);...
95d0: 69 66 20 28 73 65 65 6b 5f 72 65 74 20 3d 3d 20  if (seek_ret == 
95e0: 6f 66 66 73 65 74 29 20 7b 0a 09 09 09 77 72 69  offset) {....wri
95f0: 74 65 5f 72 65 74 20 3d 20 77 72 69 74 65 28 66  te_ret = write(f
9600: 69 2d 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a 65  i->fh, buf, size
9610: 29 3b 20 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09  ); ...} else {..
9620: 09 09 77 72 69 74 65 5f 72 65 74 20 3d 20 2d 31  ..write_ret = -1
9630: 3b 0a 09 09 7d 0a 23 20 20 65 6e 64 69 66 0a 23  ;...}.#  endif.#
9640: 65 6c 73 65 0a 09 09 77 72 69 74 65 5f 72 65 74  else...write_ret
9650: 20 3d 20 70 77 72 69 74 65 28 66 69 2d 3e 66 68   = pwrite(fi->fh
9660: 2c 20 62 75 66 2c 20 73 69 7a 65 2c 20 6f 66 66  , buf, size, off
9670: 73 65 74 29 3b 0a 23 65 6e 64 69 66 0a 0a 09 09  set);.#endif....
9680: 69 66 20 28 77 72 69 74 65 5f 72 65 74 20 3c 20  if (write_ret < 
9690: 30 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45  0) {....APPFS_DE
96a0: 42 55 47 28 22 65 72 72 6f 72 3a 20 77 72 69 74  BUG("error: writ
96b0: 65 20 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09 09  e failed");.....
96c0: 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d  return(errno * -
96d0: 31 29 3b 0a 09 09 7d 0a 0a 09 09 69 66 20 28 77  1);...}....if (w
96e0: 72 69 74 65 5f 72 65 74 20 3d 3d 20 30 29 20 7b  rite_ret == 0) {
96f0: 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 7d 0a 0a  ....break;...}..
9700: 09 09 73 69 7a 65 20 2d 3d 20 77 72 69 74 65 5f  ..size -= write_
9710: 72 65 74 3b 0a 09 09 62 75 66 20 20 2b 3d 20 77  ret;...buf  += w
9720: 72 69 74 65 5f 72 65 74 3b 0a 09 09 6f 66 66 73  rite_ret;...offs
9730: 65 74 20 2b 3d 20 77 72 69 74 65 5f 72 65 74 3b  et += write_ret;
9740: 0a 09 09 72 65 74 76 61 6c 20 2b 3d 20 77 72 69  ...retval += wri
9750: 74 65 5f 72 65 74 3b 0a 09 7d 0a 0a 09 69 66 20  te_ret;..}...if 
9760: 28 73 69 7a 65 20 21 3d 20 30 29 20 7b 0a 09 09  (size != 0) {...
9770: 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72  APPFS_DEBUG("err
9780: 6f 72 3a 20 69 6e 63 6f 6d 70 6c 65 74 65 20 77  or: incomplete w
9790: 72 69 74 65 22 29 3b 0a 09 7d 0a 0a 09 72 65 74  rite");..}...ret
97a0: 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a  urn(retval);.}..
97b0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
97c0: 5f 66 75 73 65 5f 6d 6b 6e 6f 64 28 63 6f 6e 73  _fuse_mknod(cons
97d0: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f  t char *path, mo
97e0: 64 65 5f 74 20 6d 6f 64 65 2c 20 64 65 76 5f 74  de_t mode, dev_t
97f0: 20 64 65 76 69 63 65 29 20 7b 0a 09 63 68 61 72   device) {..char
9800: 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e   *real_path;..in
9810: 74 20 6d 6b 6e 6f 64 5f 72 65 74 3b 0a 0a 09 41  t mknod_ret;...A
9820: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
9830: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
9840: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69 66  .)", path);...if
9850: 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 43 48   ((mode & S_IFCH
9860: 52 29 20 3d 3d 20 53 5f 49 46 43 48 52 29 20 7b  R) == S_IFCHR) {
9870: 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45 52 4d  ...return(-EPERM
9880: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 6d 6f 64  );..}...if ((mod
9890: 65 20 26 20 53 5f 49 46 42 4c 4b 29 20 3d 3d 20  e & S_IFBLK) == 
98a0: 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09 72 65 74  S_IFBLK) {...ret
98b0: 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a  urn(-EPERM);..}.
98c0: 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70  ..real_path = ap
98d0: 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63  pfs_prepare_to_c
98e0: 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09 69 66  reate(path);..if
98f0: 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e   (real_path == N
9900: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
9910: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  -EIO);..}...appf
9920: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
9930: 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b  fs_enter();...mk
9940: 6e 6f 64 5f 72 65 74 20 3d 20 6d 6b 6e 6f 64 28  nod_ret = mknod(
9950: 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 2c  real_path, mode,
9960: 20 64 65 76 69 63 65 29 3b 0a 0a 09 61 70 70 66   device);...appf
9970: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
9980: 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72  fs_leave();...fr
9990: 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a  ee(real_path);..
99a0: 09 69 66 20 28 6d 6b 6e 6f 64 5f 72 65 74 20 21  .if (mknod_ret !
99b0: 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  = 0) {...return(
99c0: 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a  errno * -1);..}.
99d0: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
99e0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
99f0: 5f 66 75 73 65 5f 63 72 65 61 74 65 28 63 6f 6e  _fuse_create(con
9a00: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d  st char *path, m
9a10: 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 73 74 72 75  ode_t mode, stru
9a20: 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66  ct fuse_file_inf
9a30: 6f 20 2a 66 69 29 20 7b 0a 09 63 68 61 72 20 2a  o *fi) {..char *
9a40: 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20  real_path;..int 
9a50: 66 64 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  fd;...APPFS_DEBU
9a60: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
9a70: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
9a80: 29 3b 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26  );...if ((mode &
9a90: 20 53 5f 49 46 43 48 52 29 20 3d 3d 20 53 5f 49   S_IFCHR) == S_I
9aa0: 46 43 48 52 29 20 7b 0a 09 09 72 65 74 75 72 6e  FCHR) {...return
9ab0: 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69  (-EPERM);..}...i
9ac0: 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 42  f ((mode & S_IFB
9ad0: 4c 4b 29 20 3d 3d 20 53 5f 49 46 42 4c 4b 29 20  LK) == S_IFBLK) 
9ae0: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45 52  {...return(-EPER
9af0: 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61  M);..}...real_pa
9b00: 74 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70 61  th = appfs_prepa
9b10: 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 70 61 74  re_to_create(pat
9b20: 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61  h);..if (real_pa
9b30: 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th == NULL) {...
9b40: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
9b50: 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  ...appfs_simulat
9b60: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
9b70: 29 3b 0a 0a 09 66 64 20 3d 20 63 72 65 61 74 28  );...fd = creat(
9b80: 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29  real_path, mode)
9b90: 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61  ;...appfs_simula
9ba0: 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65  te_user_fs_leave
9bb0: 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f  ();...free(real_
9bc0: 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 66 64 20  path);...if (fd 
9bd0: 3c 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  < 0) {...return(
9be0: 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a  errno * -1);..}.
9bf0: 0a 09 66 69 2d 3e 66 68 20 3d 20 66 64 3b 0a 0a  ..fi->fh = fd;..
9c00: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
9c10: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
9c20: 66 75 73 65 5f 74 72 75 6e 63 61 74 65 28 63 6f  fuse_truncate(co
9c30: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
9c40: 6f 66 66 5f 74 20 73 69 7a 65 29 20 7b 0a 09 63  off_t size) {..c
9c50: 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a  har *real_path;.
9c60: 09 69 6e 74 20 74 72 75 6e 63 61 74 65 5f 72 65  .int truncate_re
9c70: 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  t;...APPFS_DEBUG
9c80: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
9c90: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
9ca0: 3b 0a 0a 23 69 66 20 64 65 66 69 6e 65 64 28 41  ;..#if defined(A
9cb0: 50 50 46 53 5f 45 58 45 43 5f 50 41 54 48 5f 45  PPFS_EXEC_PATH_E
9cc0: 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f 53 45 43 55  NABLE_MAJOR_SECU
9cd0: 52 49 54 59 5f 48 4f 4c 45 29 0a 09 69 66 20 28  RITY_HOLE)..if (
9ce0: 73 74 72 63 6d 70 28 70 61 74 68 2c 20 22 2f 65  strcmp(path, "/e
9cf0: 78 65 63 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09  xec") == 0) {...
9d00: 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 23 65  return(0);..}.#e
9d10: 6e 64 69 66 0a 0a 09 72 65 61 6c 5f 70 61 74 68  ndif...real_path
9d20: 20 3d 20 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61   = appfs_localpa
9d30: 74 68 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72  th(path);..if (r
9d40: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
9d50: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
9d60: 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67  O);..}...appfs_g
9d70: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
9d80: 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70 70 66  he_rm(path, appf
9d90: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a  s_get_fsuid());.
9da0: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  ..appfs_simulate
9db0: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29  _user_fs_enter()
9dc0: 3b 0a 0a 09 74 72 75 6e 63 61 74 65 5f 72 65 74  ;...truncate_ret
9dd0: 20 3d 20 74 72 75 6e 63 61 74 65 28 72 65 61 6c   = truncate(real
9de0: 5f 70 61 74 68 2c 20 73 69 7a 65 29 3b 0a 0a 09  _path, size);...
9df0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
9e00: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a  ser_fs_leave();.
9e10: 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68  ..free(real_path
9e20: 29 3b 0a 0a 09 69 66 20 28 74 72 75 6e 63 61 74  );...if (truncat
9e30: 65 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  e_ret != 0) {...
9e40: 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d  return(errno * -
9e50: 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  1);..}...return(
9e60: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
9e70: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c  t appfs_fuse_unl
9e80: 69 6e 6b 5f 72 6d 64 69 72 28 63 6f 6e 73 74 20  ink_rmdir(const 
9e90: 63 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54  char *path) {..T
9ea0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
9eb0: 70 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b  p;..int tcl_ret;
9ec0: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
9ed0: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
9ee0: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
9ef0: 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  ..appfs_get_path
9f00: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73  _info_cache_flus
9f10: 68 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  h(appfs_get_fsui
9f20: 64 28 29 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74 65  d(), -1);...inte
9f30: 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e  rp = appfs_TclIn
9f40: 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74  terp();..if (int
9f50: 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  erp == NULL) {..
9f60: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
9f70: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
9f80: 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72  ibtcl(Tcl_Preser
9f90: 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74  ve(interp);)...t
9fa0: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
9fb0: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
9fc0: 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c  2, "::appfs::unl
9fd0: 69 6e 6b 70 61 74 68 22 2c 20 70 61 74 68 29 3b  inkpath", path);
9fe0: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
9ff0: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
a000: 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66  FS_DEBUG("::appf
a010: 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68 28 25 73  s::unlinkpath(%s
a020: 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68  ) failed.", path
a030: 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  );...appfs_call_
a040: 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53  libtcl(....APPFS
a050: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
a060: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
a070: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
a080: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
a090: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
a0a0: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
a0b0: 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72  terp);)....retur
a0c0: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70  n(-EIO);..}...ap
a0d0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
a0e0: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
a0f0: 72 70 29 3b 29 0a 0a 09 72 65 74 75 72 6e 28 30  rp);)...return(0
a100: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
a110: 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b 64 69   appfs_fuse_mkdi
a120: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  r(const char *pa
a130: 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 29  th, mode_t mode)
a140: 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70   {..char *real_p
a150: 61 74 68 3b 0a 09 69 6e 74 20 6d 6b 64 69 72 5f  ath;..int mkdir_
a160: 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42  ret;...APPFS_DEB
a170: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
a180: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74  = %s, ...)", pat
a190: 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20  h);...real_path 
a1a0: 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f  = appfs_prepare_
a1b0: 74 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b  to_create(path);
a1c0: 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20  ..if (real_path 
a1d0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
a1e0: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
a1f0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
a200: 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a  ser_fs_enter();.
a210: 0a 09 6d 6b 64 69 72 5f 72 65 74 20 3d 20 6d 6b  ..mkdir_ret = mk
a220: 64 69 72 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d  dir(real_path, m
a230: 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  ode);...appfs_si
a240: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
a250: 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72  eave();...free(r
a260: 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20  eal_path);...if 
a270: 28 6d 6b 64 69 72 5f 72 65 74 20 21 3d 20 30 29  (mkdir_ret != 0)
a280: 20 7b 0a 09 09 69 66 20 28 65 72 72 6e 6f 20 21   {...if (errno !
a290: 3d 20 45 45 58 49 53 54 29 20 7b 0a 09 09 09 72  = EEXIST) {....r
a2a0: 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31  eturn(errno * -1
a2b0: 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75  );...}..}...retu
a2c0: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn(0);.}..static
a2d0: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
a2e0: 63 68 6d 6f 64 28 63 6f 6e 73 74 20 63 68 61 72  chmod(const char
a2f0: 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d   *path, mode_t m
a300: 6f 64 65 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  ode) {..Tcl_Inte
a310: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e  rp *interp;..con
a320: 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 61  st char *real_pa
a330: 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  th;..int tcl_ret
a340: 2c 20 63 68 6d 6f 64 5f 72 65 74 3b 0a 0a 09 41  , chmod_ret;...A
a350: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
a360: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
a370: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70  .)", path);...ap
a380: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
a390: 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c  o_cache_rm(path,
a3a0: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64   appfs_get_fsuid
a3b0: 28 29 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20  ());...interp = 
a3c0: 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28  appfs_TclInterp(
a3d0: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  );..if (interp =
a3e0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
a3f0: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
a400: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
a410: 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e  (Tcl_Preserve(in
a420: 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72 65  terp);)...tcl_re
a430: 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76  t = appfs_Tcl_Ev
a440: 61 6c 28 69 6e 74 65 72 70 2c 20 33 2c 20 22 3a  al(interp, 3, ":
a450: 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68  :appfs::openpath
a460: 22 2c 20 70 61 74 68 2c 20 22 77 72 69 74 65 22  ", path, "write"
a470: 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  );..if (tcl_ret 
a480: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41  != TCL_OK) {...A
a490: 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70  PPFS_DEBUG("::ap
a4a0: 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28 25 73  pfs::openpath(%s
a4b0: 2c 20 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20  , %s) failed.", 
a4c0: 70 61 74 68 2c 20 22 77 72 69 74 65 22 29 3b 0a  path, "write");.
a4d0: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
a4e0: 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45  tcl(....APPFS_DE
a4f0: 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69  BUG("Tcl Error i
a500: 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53  s: %s", Tcl_GetS
a510: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
a520: 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70  rp));...)....app
a530: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
a540: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
a550: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d  p);)....return(-
a560: 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  EIO);..}...appfs
a570: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
a580: 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f  real_path = Tcl_
a590: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
a5a0: 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70  interp);..)...ap
a5b0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
a5c0: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
a5d0: 72 70 29 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c  rp);)...if (real
a5e0: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
a5f0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
a600: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  ..}...appfs_simu
a610: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
a620: 65 72 28 29 3b 0a 0a 09 63 68 6d 6f 64 5f 72 65  er();...chmod_re
a630: 74 20 3d 20 63 68 6d 6f 64 28 72 65 61 6c 5f 70  t = chmod(real_p
a640: 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61 70  ath, mode);...ap
a650: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
a660: 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09  r_fs_leave();...
a670: 72 65 74 75 72 6e 28 63 68 6d 6f 64 5f 72 65 74  return(chmod_ret
a680: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
a690: 20 61 70 70 66 73 5f 66 75 73 65 5f 73 79 6d 6c   appfs_fuse_syml
a6a0: 69 6e 6b 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ink(const char *
a6b0: 6f 6c 64 70 61 74 68 2c 20 63 6f 6e 73 74 20 63  oldpath, const c
a6c0: 68 61 72 20 2a 6e 65 77 70 61 74 68 29 20 7b 0a  har *newpath) {.
a6d0: 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68  .char *real_path
a6e0: 3b 0a 09 69 6e 74 20 73 79 6d 6c 69 6e 6b 5f 72  ;..int symlink_r
a6f0: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  et;...APPFS_DEBU
a700: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
a710: 20 25 73 2c 20 25 73 29 22 2c 20 6f 6c 64 70 61   %s, %s)", oldpa
a720: 74 68 2c 20 6e 65 77 70 61 74 68 29 3b 0a 0a 09  th, newpath);...
a730: 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66  real_path = appf
a740: 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65  s_prepare_to_cre
a750: 61 74 65 28 6e 65 77 70 61 74 68 29 3b 0a 09 69  ate(newpath);..i
a760: 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20  f (real_path == 
a770: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
a780: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70  (-EIO);..}...app
a790: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
a7a0: 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 73  _fs_enter();...s
a7b0: 79 6d 6c 69 6e 6b 5f 72 65 74 20 3d 20 73 79 6d  ymlink_ret = sym
a7c0: 6c 69 6e 6b 28 6f 6c 64 70 61 74 68 2c 20 72 65  link(oldpath, re
a7d0: 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 61 70 70 66  al_path);...appf
a7e0: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
a7f0: 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72  fs_leave();...fr
a800: 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a  ee(real_path);..
a810: 09 69 66 20 28 73 79 6d 6c 69 6e 6b 5f 72 65 74  .if (symlink_ret
a820: 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72   != 0) {...retur
a830: 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09  n(errno * -1);..
a840: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  }...return(0);.}
a850: 0a 0a 2f 2a 0a 20 2a 20 53 51 4c 69 74 65 33 20  ../*. * SQLite3 
a860: 6d 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72 61  mode: Execute ra
a870: 77 20 53 51 4c 20 61 6e 64 20 72 65 74 75 72 6e  w SQL and return
a880: 20 73 75 63 63 65 73 73 20 6f 72 20 66 61 69 6c   success or fail
a890: 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69  ure. */.static i
a8a0: 6e 74 20 61 70 70 66 73 5f 73 71 6c 69 74 65 33  nt appfs_sqlite3
a8b0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c  (const char *sql
a8c0: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
a8d0: 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20  *interp;..const 
a8e0: 63 68 61 72 20 2a 73 71 6c 5f 72 65 74 3b 0a 09  char *sql_ret;..
a8f0: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69  int tcl_ret;...i
a900: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72  nterp = appfs_cr
a910: 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e  eate_TclInterp(N
a920: 55 4c 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65 72  ULL);..if (inter
a930: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41  p == NULL) {...A
a940: 50 50 46 53 5f 45 52 52 4f 52 28 22 55 6e 61 62  PPFS_ERROR("Unab
a950: 6c 65 20 74 6f 20 63 72 65 61 74 65 20 61 20 54  le to create a T
a960: 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20  cl interpreter. 
a970: 20 41 62 6f 72 74 69 6e 67 2e 22 29 3b 0a 0a 09   Aborting.");...
a980: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a  .return(1);..}..
a990: 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73  .tcl_ret = appfs
a9a0: 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70  _Tcl_Eval(interp
a9b0: 2c 20 35 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 64  , 5, "::appfs::d
a9c0: 62 22 2c 20 22 65 76 61 6c 22 2c 20 73 71 6c 2c  b", "eval", sql,
a9d0: 20 22 72 6f 77 22 2c 20 22 75 6e 73 65 74 20 2d   "row", "unset -
a9e0: 6e 6f 63 6f 6d 70 6c 61 69 6e 20 72 6f 77 28 2a  nocomplain row(*
a9f0: 29 3b 20 70 61 72 72 61 79 20 72 6f 77 3b 20 70  ); parray row; p
aa00: 75 74 73 20 5c 22 2d 2d 2d 2d 5c 22 22 29 3b 0a  uts \"----\"");.
aa10: 09 73 71 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47  .sql_ret = Tcl_G
aa20: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
aa30: 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 74 63  nterp);...if (tc
aa40: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
aa50: 20 7b 0a 09 09 41 50 50 46 53 5f 45 52 52 4f 52   {...APPFS_ERROR
aa60: 28 22 5b 65 72 72 6f 72 5d 20 25 73 22 2c 20 73  ("[error] %s", s
aa70: 71 6c 5f 72 65 74 29 3b 0a 0a 09 09 72 65 74 75  ql_ret);....retu
aa80: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  rn(1);..}...if (
aa90: 73 71 6c 5f 72 65 74 20 26 26 20 73 71 6c 5f 72  sql_ret && sql_r
aaa0: 65 74 5b 30 5d 20 21 3d 20 27 5c 30 27 29 20 7b  et[0] != '\0') {
aab0: 0a 09 09 70 72 69 6e 74 66 28 22 25 73 5c 6e 22  ...printf("%s\n"
aac0: 2c 20 73 71 6c 5f 72 65 74 29 3b 0a 09 7d 0a 0a  , sql_ret);..}..
aad0: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f  .return(0);.}../
aae0: 2a 0a 20 2a 20 54 63 6c 20 6d 6f 64 65 3a 20 45  *. * Tcl mode: E
aaf0: 78 65 63 75 74 65 20 72 61 77 20 54 63 6c 20 61  xecute raw Tcl a
ab00: 6e 64 20 72 65 74 75 72 6e 20 73 75 63 63 65 73  nd return succes
ab10: 73 20 6f 72 20 66 61 69 6c 75 72 65 0a 20 2a 2f  s or failure. */
ab20: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
ab30: 73 5f 74 63 6c 28 63 6f 6e 73 74 20 63 68 61 72  s_tcl(const char
ab40: 20 2a 74 63 6c 29 20 7b 0a 09 54 63 6c 5f 49 6e   *tcl) {..Tcl_In
ab50: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63  terp *interp;..c
ab60: 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c 5f 72  onst char *tcl_r
ab70: 65 73 75 6c 74 3b 0a 09 69 6e 74 20 74 63 6c 5f  esult;..int tcl_
ab80: 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20  ret;...interp = 
ab90: 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c  appfs_create_Tcl
aba0: 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 09 69  Interp(NULL);..i
abb0: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
abc0: 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 45 52 52  L) {...APPFS_ERR
abd0: 4f 52 28 22 55 6e 61 62 6c 65 20 74 6f 20 63 72  OR("Unable to cr
abe0: 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72  eate a Tcl inter
abf0: 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69 6e  preter.  Abortin
ac00: 67 2e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  g.");....return(
ac10: 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74  1);..}...tcl_ret
ac20: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65   = Tcl_Eval(inte
ac30: 72 70 2c 20 74 63 6c 29 3b 0a 09 74 63 6c 5f 72  rp, tcl);..tcl_r
ac40: 65 73 75 6c 74 20 3d 20 54 63 6c 5f 47 65 74 53  esult = Tcl_GetS
ac50: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
ac60: 72 70 29 3b 0a 0a 09 69 66 20 28 74 63 6c 5f 72  rp);...if (tcl_r
ac70: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
ac80: 09 09 41 50 50 46 53 5f 45 52 52 4f 52 28 22 5b  ..APPFS_ERROR("[
ac90: 65 72 72 6f 72 5d 20 25 73 22 2c 20 54 63 6c 5f  error] %s", Tcl_
aca0: 47 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22  GetVar(interp, "
acb0: 65 72 72 6f 72 49 6e 66 6f 22 2c 20 54 43 4c 5f  errorInfo", TCL_
acc0: 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 29 3b 0a 0a  GLOBAL_ONLY));..
acd0: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
ace0: 0a 09 69 66 20 28 74 63 6c 5f 72 65 73 75 6c 74  ..if (tcl_result
acf0: 20 26 26 20 74 63 6c 5f 72 65 73 75 6c 74 5b 30   && tcl_result[0
ad00: 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09 70  ] != '\0') {...p
ad10: 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 74 63  rintf("%s\n", tc
ad20: 6c 5f 72 65 73 75 6c 74 29 3b 0a 09 7d 0a 0a 09  l_result);..}...
ad30: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a  return(0);.}../*
ad40: 0a 20 2a 20 41 70 70 46 53 64 20 50 61 63 6b 61  . * AppFSd Packa
ad50: 67 65 20 66 6f 72 20 54 63 6c 3a 0a 20 2a 20 20  ge for Tcl:. *  
ad60: 20 20 20 20 20 20 20 42 72 69 64 67 65 20 66 6f         Bridge fo
ad70: 72 20 49 2f 4f 20 6f 70 65 72 61 74 69 6f 6e 73  r I/O operations
ad80: 20 74 6f 20 72 65 71 75 65 73 74 20 69 6e 66 6f   to request info
ad90: 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 74 68  rmation about th
ada0: 65 20 63 75 72 72 65 6e 74 0a 20 2a 20 20 20 20  e current. *    
adb0: 20 20 20 20 20 74 72 61 6e 73 61 63 74 69 6f 6e       transaction
adc0: 0a 20 2a 2f 0a 2f 2a 0a 20 2a 20 54 63 6c 20 69  . */./*. * Tcl i
add0: 6e 74 65 72 66 61 63 65 20 74 6f 20 67 65 74 20  nterface to get 
ade0: 74 68 65 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  the home directo
adf0: 72 79 20 66 6f 72 20 74 68 65 20 75 73 65 72 20  ry for the user 
ae00: 6d 61 6b 69 6e 67 20 74 68 65 20 22 63 75 72 72  making the "curr
ae10: 65 6e 74 22 0a 20 2a 20 46 55 53 45 20 49 2f 4f  ent". * FUSE I/O
ae20: 20 72 65 71 75 65 73 74 0a 20 2a 2f 0a 73 74 61   request. */.sta
ae30: 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66  tic int tcl_appf
ae40: 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 43 6c  s_get_homedir(Cl
ae50: 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c  ientData cd, Tcl
ae60: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
ae70: 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f   int objc, Tcl_O
ae80: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
ae90: 29 20 7b 0a 09 63 68 61 72 20 2a 68 6f 6d 65 64  ) {..char *homed
aea0: 69 72 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 68 6f  ir;..Tcl_Obj *ho
aeb0: 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 75 69 64 5f  medir_obj;..uid_
aec0: 74 20 66 73 75 69 64 3b 0a 09 73 74 61 74 69 63  t fsuid;..static
aed0: 20 5f 5f 74 68 72 65 61 64 20 54 63 6c 5f 4f 62   __thread Tcl_Ob
aee0: 6a 20 2a 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f  j *last_homedir_
aef0: 6f 62 6a 20 3d 20 4e 55 4c 4c 3b 0a 09 73 74 61  obj = NULL;..sta
af00: 74 69 63 20 5f 5f 74 68 72 65 61 64 20 75 69 64  tic __thread uid
af10: 5f 74 20 6c 61 73 74 5f 66 73 75 69 64 20 3d 20  _t last_fsuid = 
af20: 2d 31 3b 0a 0a 20 20 20 20 20 20 20 20 69 66 20  -1;..        if 
af30: 28 6f 62 6a 63 20 21 3d 20 31 29 20 7b 0a 20 20  (objc != 1) {.  
af40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 63                Tc
af50: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69  l_WrongNumArgs(i
af60: 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20  nterp, 1, objv, 
af70: 4e 55 4c 4c 29 3b 0a 20 20 20 20 20 20 20 20 20  NULL);.         
af80: 20 20 20 20 20 20 20 72 65 74 75 72 6e 28 54 43         return(TC
af90: 4c 5f 45 52 52 4f 52 29 3b 0a 20 20 20 20 20 20  L_ERROR);.      
afa0: 20 20 7d 0a 0a 09 66 73 75 69 64 20 3d 20 61 70    }...fsuid = ap
afb0: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b  pfs_get_fsuid();
afc0: 0a 0a 09 69 66 20 28 66 73 75 69 64 20 3d 3d 20  ...if (fsuid == 
afd0: 6c 61 73 74 5f 66 73 75 69 64 20 26 26 20 6c 61  last_fsuid && la
afe0: 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 21  st_homedir_obj !
aff0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 6f 6d 65  = NULL) {...home
b000: 64 69 72 5f 6f 62 6a 20 3d 20 6c 61 73 74 5f 68  dir_obj = last_h
b010: 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 0a 09 09 54  omedir_obj;....T
b020: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
b030: 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 7d  homedir_obj);..}
b040: 20 65 6c 73 65 20 7b 0a 09 09 68 6f 6d 65 64 69   else {...homedi
b050: 72 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 68 6f  r = appfs_get_ho
b060: 6d 65 64 69 72 28 61 70 70 66 73 5f 67 65 74 5f  medir(appfs_get_
b070: 66 73 75 69 64 28 29 29 3b 0a 0a 09 09 69 66 20  fsuid());....if 
b080: 28 68 6f 6d 65 64 69 72 20 3d 3d 20 4e 55 4c 4c  (homedir == NULL
b090: 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 54 43  ) {....return(TC
b0a0: 4c 5f 45 52 52 4f 52 29 3b 0a 09 09 7d 0a 0a 09  L_ERROR);...}...
b0b0: 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 54  .homedir_obj = T
b0c0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
b0d0: 68 6f 6d 65 64 69 72 2c 20 2d 31 29 3b 0a 0a 09  homedir, -1);...
b0e0: 09 66 72 65 65 28 68 6f 6d 65 64 69 72 29 3b 0a  .free(homedir);.
b0f0: 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f  ...Tcl_IncrRefCo
b100: 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29  unt(homedir_obj)
b110: 3b 0a 0a 09 09 69 66 20 28 6c 61 73 74 5f 68 6f  ;....if (last_ho
b120: 6d 65 64 69 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c  medir_obj != NUL
b130: 4c 29 20 7b 0a 09 09 09 54 63 6c 5f 44 65 63 72  L) {....Tcl_Decr
b140: 52 65 66 43 6f 75 6e 74 28 6c 61 73 74 5f 68 6f  RefCount(last_ho
b150: 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 09 7d 0a  medir_obj);...}.
b160: 0a 09 09 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f  ...last_homedir_
b170: 6f 62 6a 20 3d 20 68 6f 6d 65 64 69 72 5f 6f 62  obj = homedir_ob
b180: 6a 3b 0a 09 09 6c 61 73 74 5f 66 73 75 69 64 20  j;...last_fsuid 
b190: 3d 20 66 73 75 69 64 3b 0a 0a 09 09 54 63 6c 5f  = fsuid;....Tcl_
b1a0: 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 68 6f 6d  IncrRefCount(hom
b1b0: 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 7d 0a 0a 20  edir_obj);..}.. 
b1c0: 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74 4f 62        .Tcl_SetOb
b1d0: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  jResult(interp, 
b1e0: 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 0a 09  homedir_obj);...
b1f0: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74  Tcl_DecrRefCount
b200: 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 0a  (homedir_obj);..
b210: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 28 54          return(T
b220: 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69  CL_OK);.}..stati
b230: 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f  c int tcl_appfs_
b240: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
b250: 5f 65 6e 74 65 72 28 43 6c 69 65 6e 74 44 61 74  _enter(ClientDat
b260: 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70  a cd, Tcl_Interp
b270: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62   *interp, int ob
b280: 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  jc, Tcl_Obj *CON
b290: 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70  ST objv[]) {..ap
b2a0: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
b2b0: 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09  r_fs_enter();...
b2c0: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a  return(TCL_OK);.
b2d0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  }..static int tc
b2e0: 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  l_appfs_simulate
b2f0: 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 43  _user_fs_leave(C
b300: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63  lientData cd, Tc
b310: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
b320: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f  , int objc, Tcl_
b330: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
b340: 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75  ]) {..appfs_simu
b350: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
b360: 76 65 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54  ve();...return(T
b370: 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69  CL_OK);.}..stati
b380: 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f  c int tcl_appfs_
b390: 67 65 74 5f 66 73 75 69 64 28 43 6c 69 65 6e 74  get_fsuid(Client
b3a0: 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74  Data cd, Tcl_Int
b3b0: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74  erp *interp, int
b3c0: 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a   objc, Tcl_Obj *
b3d0: 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a  CONST objv[]) {.
b3e0: 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a 0a 09  .uid_t fsuid;...
b3f0: 66 73 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65  fsuid = appfs_ge
b400: 74 5f 66 73 75 69 64 28 29 3b 0a 0a 20 20 20 20  t_fsuid();..    
b410: 20 20 20 09 54 63 6c 5f 53 65 74 4f 62 6a 52 65     .Tcl_SetObjRe
b420: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c  sult(interp, Tcl
b430: 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 66  _NewWideIntObj(f
b440: 73 75 69 64 29 29 3b 0a 0a 09 72 65 74 75 72 6e  suid));...return
b450: 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61  (TCL_OK);.}..sta
b460: 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66  tic int tcl_appf
b470: 73 5f 67 65 74 5f 66 73 67 69 64 28 43 6c 69 65  s_get_fsgid(Clie
b480: 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49  ntData cd, Tcl_I
b490: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69  nterp *interp, i
b4a0: 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a  nt objc, Tcl_Obj
b4b0: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20   *CONST objv[]) 
b4c0: 7b 0a 09 67 69 64 5f 74 20 66 73 67 69 64 3b 0a  {..gid_t fsgid;.
b4d0: 0a 09 66 73 67 69 64 20 3d 20 61 70 70 66 73 5f  ..fsgid = appfs_
b4e0: 67 65 74 5f 66 73 67 69 64 28 29 3b 0a 0a 20 20  get_fsgid();..  
b4f0: 20 20 20 20 20 09 54 63 6c 5f 53 65 74 4f 62 6a       .Tcl_SetObj
b500: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54  Result(interp, T
b510: 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a  cl_NewWideIntObj
b520: 28 66 73 67 69 64 29 29 3b 0a 0a 09 72 65 74 75  (fsgid));...retu
b530: 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73  rn(TCL_OK);.}..s
b540: 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70  tatic int tcl_ap
b550: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
b560: 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 43 6c  o_cache_flush(Cl
b570: 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c  ientData cd, Tcl
b580: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
b590: 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f   int objc, Tcl_O
b5a0: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
b5b0: 29 20 7b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  ) {..int tcl_ret
b5c0: 3b 0a 09 69 6e 74 20 6e 65 77 5f 73 69 7a 65 3b  ;..int new_size;
b5d0: 0a 0a 09 6e 65 77 5f 73 69 7a 65 20 3d 20 2d 31  ...new_size = -1
b5e0: 3b 0a 0a 09 69 66 20 28 6f 62 6a 63 20 3d 3d 20  ;...if (objc == 
b5f0: 32 29 20 7b 0a 09 09 74 63 6c 5f 72 65 74 20 3d  2) {...tcl_ret =
b600: 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f   Tcl_GetIntFromO
b610: 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b  bj(interp, objv[
b620: 31 5d 2c 20 26 6e 65 77 5f 73 69 7a 65 29 3b 0a  1], &new_size);.
b630: 09 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
b640: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 72 65   TCL_OK) {....re
b650: 74 75 72 6e 28 74 63 6c 5f 72 65 74 29 3b 0a 09  turn(tcl_ret);..
b660: 09 7d 0a 09 7d 20 65 6c 73 65 20 69 66 20 28 6f  .}..} else if (o
b670: 62 6a 63 20 3e 20 32 20 7c 7c 20 6f 62 6a 63 20  bjc > 2 || objc 
b680: 3c 20 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20  < 1) {.         
b690: 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67         Tcl_Wrong
b6a0: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
b6b0: 31 2c 20 6f 62 6a 76 2c 20 22 3f 6e 65 77 5f 63  1, objv, "?new_c
b6c0: 61 63 68 65 5f 73 69 7a 65 3f 22 29 3b 0a 09 09  ache_size?");...
b6d0: 72 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52  return(TCL_ERROR
b6e0: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67 65  );..}...appfs_ge
b6f0: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
b700: 65 5f 66 6c 75 73 68 28 2d 31 2c 20 6e 65 77 5f  e_flush(-1, new_
b710: 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72 6e 28  size);...return(
b720: 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74  TCL_OK);.}..stat
b730: 69 63 20 69 6e 74 20 41 70 70 66 73 64 5f 49 6e  ic int Appfsd_In
b740: 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  it(Tcl_Interp *i
b750: 6e 74 65 72 70 29 20 7b 0a 23 69 66 64 65 66 20  nterp) {.#ifdef 
b760: 55 53 45 5f 54 43 4c 5f 53 54 55 42 53 0a 09 69  USE_TCL_STUBS..i
b770: 66 20 28 54 63 6c 5f 49 6e 69 74 53 74 75 62 73  f (Tcl_InitStubs
b780: 28 69 6e 74 65 72 70 2c 20 54 43 4c 5f 56 45 52  (interp, TCL_VER
b790: 53 49 4f 4e 2c 20 30 29 20 3d 3d 20 30 4c 29 20  SION, 0) == 0L) 
b7a0: 7b 0a 09 09 72 65 74 75 72 6e 28 54 43 4c 5f 45  {...return(TCL_E
b7b0: 52 52 4f 52 29 3b 0a 09 7d 0a 23 65 6e 64 69 66  RROR);..}.#endif
b7c0: 0a 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a  ...Tcl_CreateObj
b7d0: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
b7e0: 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 68 6f 6d  "appfsd::get_hom
b7f0: 65 64 69 72 22 2c 20 74 63 6c 5f 61 70 70 66 73  edir", tcl_appfs
b800: 5f 67 65 74 5f 68 6f 6d 65 64 69 72 2c 20 4e 55  _get_homedir, NU
b810: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f  LL, NULL);..Tcl_
b820: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64  CreateObjCommand
b830: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
b840: 3a 3a 67 65 74 5f 66 73 75 69 64 22 2c 20 74 63  ::get_fsuid", tc
b850: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  l_appfs_get_fsui
b860: 64 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  d, NULL, NULL);.
b870: 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f  .Tcl_CreateObjCo
b880: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61  mmand(interp, "a
b890: 70 70 66 73 64 3a 3a 67 65 74 5f 66 73 67 69 64  ppfsd::get_fsgid
b8a0: 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74  ", tcl_appfs_get
b8b0: 5f 66 73 67 69 64 2c 20 4e 55 4c 4c 2c 20 4e 55  _fsgid, NULL, NU
b8c0: 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65  LL);..Tcl_Create
b8d0: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
b8e0: 70 2c 20 22 61 70 70 66 73 64 3a 3a 73 69 6d 75  p, "appfsd::simu
b8f0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
b900: 65 72 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 73  er", tcl_appfs_s
b910: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
b920: 65 6e 74 65 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  enter, NULL, NUL
b930: 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f  L);..Tcl_CreateO
b940: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
b950: 2c 20 22 61 70 70 66 73 64 3a 3a 73 69 6d 75 6c  , "appfsd::simul
b960: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76  ate_user_fs_leav
b970: 65 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 73 69  e", tcl_appfs_si
b980: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
b990: 65 61 76 65 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  eave, NULL, NULL
b9a0: 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62  );..Tcl_CreateOb
b9b0: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  jCommand(interp,
b9c0: 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 70 61   "appfsd::get_pa
b9d0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c  th_info_cache_fl
b9e0: 75 73 68 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f  ush", tcl_appfs_
b9f0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
ba00: 63 68 65 5f 66 6c 75 73 68 2c 20 4e 55 4c 4c 2c  che_flush, NULL,
ba10: 20 4e 55 4c 4c 29 3b 0a 0a 09 54 63 6c 5f 50 6b   NULL);...Tcl_Pk
ba20: 67 50 72 6f 76 69 64 65 28 69 6e 74 65 72 70 2c  gProvide(interp,
ba30: 20 22 61 70 70 66 73 64 22 2c 20 22 31 2e 30 22   "appfsd", "1.0"
ba40: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f  );...return(TCL_
ba50: 4f 4b 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 41  OK);.}..#ifdef A
ba60: 50 50 46 53 5f 4e 4f 5f 53 49 47 4e 41 4c 53 0a  PPFS_NO_SIGNALS.
ba70: 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66  static void appf
ba80: 73 5f 73 65 74 5f 73 69 67 68 61 6e 64 6c 65 72  s_set_sighandler
ba90: 28 76 6f 69 64 29 20 7b 0a 09 72 65 74 75 72 6e  (void) {..return
baa0: 3b 0a 7d 0a 23 65 6c 73 65 0a 23 69 6e 63 6c 75  ;.}.#else.#inclu
bab0: 64 65 20 3c 73 69 67 6e 61 6c 2e 68 3e 0a 0a 2f  de <signal.h>../
bac0: 2a 0a 20 2a 20 48 6f 74 2d 72 65 73 74 61 72 74  *. * Hot-restart
bad0: 20 73 75 70 70 6f 72 74 0a 20 2a 2f 0a 2f 2a 20   support. */./* 
bae0: 49 6e 69 74 69 61 74 65 20 61 20 68 6f 74 2d 72  Initiate a hot-r
baf0: 65 73 74 61 72 74 20 2a 2f 0a 73 74 61 74 69 63  estart */.static
bb00: 20 76 6f 69 64 20 61 70 70 66 73 5f 68 6f 74 5f   void appfs_hot_
bb10: 72 65 73 74 61 72 74 28 76 6f 69 64 29 20 7b 0a  restart(void) {.
bb20: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 41 73  .APPFS_DEBUG("As
bb30: 6b 65 64 20 74 6f 20 69 6e 69 74 69 61 74 65 20  ked to initiate 
bb40: 68 6f 74 20 72 65 73 74 61 72 74 22 29 3b 0a 0a  hot restart");..
bb50: 09 61 70 70 66 73 5f 74 63 6c 5f 52 65 73 65 74  .appfs_tcl_Reset
bb60: 49 6e 74 65 72 70 73 28 29 3b 0a 0a 09 61 70 70  Interps();...app
bb70: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
bb80: 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c  _cache_flush(-1,
bb90: 20 2d 31 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a   -1);...return;.
bba0: 7d 0a 0a 2f 2a 0a 20 2a 20 53 69 67 6e 61 6c 20  }../*. * Signal 
bbb0: 68 61 6e 64 6c 65 72 0a 20 2a 20 20 20 20 20 20  handler. *      
bbc0: 20 20 20 53 49 47 48 55 50 20 69 6e 69 74 69 61     SIGHUP initia
bbd0: 74 65 73 20 61 20 68 6f 74 20 72 65 73 74 61 72  tes a hot restar
bbe0: 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  t. */.static voi
bbf0: 64 20 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f 68  d appfs_signal_h
bc00: 61 6e 64 6c 65 72 28 69 6e 74 20 73 69 67 29 20  andler(int sig) 
bc10: 7b 0a 09 2f 2a 20 44 6f 20 6e 6f 74 20 68 61 6e  {../* Do not han
bc20: 64 6c 65 20 73 69 67 6e 61 6c 73 20 75 6e 74 69  dle signals unti
bc30: 6c 20 46 55 53 45 20 68 61 73 20 62 65 65 6e 20  l FUSE has been 
bc40: 73 74 61 72 74 65 64 20 2a 2f 0a 09 69 66 20 28  started */..if (
bc50: 21 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72  !appfs_fuse_star
bc60: 74 65 64 29 20 7b 0a 09 09 72 65 74 75 72 6e 3b  ted) {...return;
bc70: 0a 09 7d 0a 0a 09 2f 2a 20 52 65 71 75 65 73 74  ..}.../* Request
bc80: 20 74 6f 20 70 65 72 66 6f 72 6d 20 61 20 22 68   to perform a "h
bc90: 6f 74 22 20 72 65 73 74 61 72 74 20 2a 2f 0a 09  ot" restart */..
bca0: 69 66 20 28 73 69 67 20 3d 3d 20 53 49 47 48 55  if (sig == SIGHU
bcb0: 50 29 20 7b 0a 09 09 61 70 70 66 73 5f 68 6f 74  P) {...appfs_hot
bcc0: 5f 72 65 73 74 61 72 74 28 29 3b 0a 09 7d 0a 0a  _restart();..}..
bcd0: 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74  .return;.}..stat
bce0: 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 73 65  ic void appfs_se
bcf0: 74 5f 73 69 67 68 61 6e 64 6c 65 72 28 76 6f 69  t_sighandler(voi
bd00: 64 29 20 7b 0a 09 76 6f 69 64 20 2a 73 69 67 6e  d) {..void *sign
bd10: 61 6c 5f 72 65 74 3b 0a 0a 09 2f 2a 0a 09 20 2a  al_ret;.../*.. *
bd20: 20 52 65 67 69 73 74 65 72 20 61 20 73 69 67 6e   Register a sign
bd30: 61 6c 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 68  al handler for h
bd40: 6f 74 2d 72 65 73 74 61 72 74 20 72 65 71 75 65  ot-restart reque
bd50: 73 74 73 0a 09 20 2a 2f 0a 09 73 69 67 6e 61 6c  sts.. */..signal
bd60: 5f 72 65 74 20 3d 20 73 69 67 6e 61 6c 28 53 49  _ret = signal(SI
bd70: 47 48 55 50 2c 20 61 70 70 66 73 5f 73 69 67 6e  GHUP, appfs_sign
bd80: 61 6c 5f 68 61 6e 64 6c 65 72 29 3b 0a 09 69 66  al_handler);..if
bd90: 20 28 73 69 67 6e 61 6c 5f 72 65 74 20 3d 3d 20   (signal_ret == 
bda0: 53 49 47 5f 45 52 52 29 20 7b 0a 09 09 41 50 50  SIG_ERR) {...APP
bdb0: 46 53 5f 45 52 52 4f 52 28 22 55 6e 61 62 6c 65  FS_ERROR("Unable
bdc0: 20 74 6f 20 69 6e 73 74 61 6c 6c 20 73 69 67 6e   to install sign
bdd0: 61 6c 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 68  al handler for h
bde0: 6f 74 2d 72 65 73 74 61 72 74 22 29 3b 0a 09 09  ot-restart");...
bdf0: 41 50 50 46 53 5f 45 52 52 4f 52 28 22 48 6f 74  APPFS_ERROR("Hot
be00: 2d 72 65 73 74 61 72 74 20 77 69 6c 6c 20 6e 6f  -restart will no
be10: 74 20 62 65 20 61 76 61 69 6c 61 62 6c 65 2e 22  t be available."
be20: 29 3b 0a 09 7d 0a 7d 0a 23 65 6e 64 69 66 0a 2f  );..}.}.#endif./
be30: 2a 0a 20 2a 20 54 65 72 6d 69 6e 61 74 65 20 61  *. * Terminate a
be40: 20 74 68 72 65 61 64 0a 20 2a 2f 0a 73 74 61 74   thread. */.stat
be50: 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 74 65  ic void appfs_te
be60: 72 6d 69 6e 61 74 65 5f 69 6e 74 65 72 70 5f 61  rminate_interp_a
be70: 6e 64 5f 74 68 72 65 61 64 28 76 6f 69 64 20 2a  nd_thread(void *
be80: 5f 69 6e 74 65 72 70 29 20 7b 0a 09 54 63 6c 5f  _interp) {..Tcl_
be90: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
bea0: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 43  ..APPFS_DEBUG("C
beb0: 61 6c 6c 65 64 3a 20 5f 69 6e 74 65 72 70 20 3d  alled: _interp =
bec0: 20 25 70 22 2c 20 5f 69 6e 74 65 72 70 29 3b 0a   %p", _interp);.
bed0: 0a 09 69 66 20 28 5f 69 6e 74 65 72 70 20 21 3d  ..if (_interp !=
bee0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 6e 74 65 72   NULL) {...inter
bef0: 70 20 3d 20 5f 69 6e 74 65 72 70 3b 0a 0a 09 09  p = _interp;....
bf00: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 65 72  APPFS_DEBUG("Ter
bf10: 6d 69 6e 61 74 69 6e 67 20 69 6e 74 65 72 70 72  minating interpr
bf20: 65 74 65 72 20 64 75 65 20 74 6f 20 74 68 72 65  eter due to thre
bf30: 61 64 20 74 65 72 6d 69 6e 61 74 69 6f 6e 22 29  ad termination")
bf40: 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  ;....appfs_call_
bf50: 6c 69 62 74 63 6c 28 0a 09 09 09 54 63 6c 5f 44  libtcl(....Tcl_D
bf60: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65  eleteInterp(inte
bf70: 72 70 29 3b 0a 09 09 29 0a 09 7d 20 65 6c 73 65  rp);...)..} else
bf80: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
bf90: 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 74 68  ("Terminating th
bfa0: 72 65 61 64 20 77 69 74 68 20 6e 6f 20 69 6e 74  read with no int
bfb0: 65 72 70 72 65 74 65 72 22 29 3b 0a 09 7d 0a 0a  erpreter");..}..
bfc0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
bfd0: 63 6c 28 0a 09 09 54 63 6c 5f 46 69 6e 61 6c 69  cl(...Tcl_Finali
bfe0: 7a 65 54 68 72 65 61 64 28 29 3b 0a 09 29 0a 0a  zeThread();..)..
bff0: 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20  .return;.}../*. 
c000: 2a 20 43 6f 6d 6d 61 6e 64 2d 6c 69 6e 65 20 70  * Command-line p
c010: 61 72 73 69 6e 67 20 74 6f 6f 6c 73 0a 20 2a 2f  arsing tools. */
c020: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
c030: 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28 46 49  fs_print_help(FI
c040: 4c 45 20 2a 63 68 61 6e 6e 65 6c 29 20 7b 0a 09  LE *channel) {..
c050: 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c  fprintf(channel,
c060: 20 22 55 73 61 67 65 3a 20 7b 61 70 70 66 73 64   "Usage: {appfsd
c070: 7c 6d 6f 75 6e 74 2e 61 70 70 66 73 7d 20 5b 2d  |mount.appfs} [-
c080: 6f 20 3c 6f 70 74 69 6f 6e 3e 5d 20 5b 2d 64 66  o <option>] [-df
c090: 73 68 5d 20 3c 63 61 63 68 65 64 69 72 3e 20 3c  sh] <cachedir> <
c0a0: 6d 6f 75 6e 74 70 6f 69 6e 74 3e 5c 6e 22 29 3b  mountpoint>\n");
c0b0: 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65  ..fprintf(channe
c0c0: 6c 2c 20 22 5c 6e 22 29 3b 0a 09 66 70 72 69 6e  l, "\n");..fprin
c0d0: 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 4f 70 74  tf(channel, "Opt
c0e0: 69 6f 6e 73 3a 5c 6e 22 29 3b 0a 09 66 70 72 69  ions:\n");..fpri
c0f0: 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20 20  ntf(channel, "  
c100: 2d 64 20 20 20 20 20 20 20 20 20 20 20 20 20 20  -d              
c110: 45 6e 61 62 6c 65 20 46 55 53 45 20 64 65 62 75  Enable FUSE debu
c120: 67 20 6d 6f 64 65 2e 5c 6e 22 29 3b 0a 09 66 70  g mode.\n");..fp
c130: 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22  rintf(channel, "
c140: 20 20 2d 66 20 20 20 20 20 20 20 20 20 20 20 20    -f            
c150: 20 20 52 75 6e 20 69 6e 20 66 6f 72 65 67 72 6f    Run in foregro
c160: 75 6e 64 2e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e  und.\n");..fprin
c170: 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20 20 2d  tf(channel, "  -
c180: 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20 45  s              E
c190: 6e 61 62 6c 65 20 73 69 6e 67 6c 65 20 74 68 72  nable single thr
c1a0: 65 61 64 65 64 20 6d 6f 64 65 2e 5c 6e 22 29 3b  eaded mode.\n");
c1b0: 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65  ..fprintf(channe
c1c0: 6c 2c 20 22 20 20 2d 68 20 20 20 20 20 20 20 20  l, "  -h        
c1d0: 20 20 20 20 20 20 47 69 76 65 20 74 68 69 73 20        Give this 
c1e0: 68 65 6c 70 2e 5c 6e 22 29 3b 0a 09 66 70 72 69  help.\n");..fpri
c1f0: 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20 20  ntf(channel, "  
c200: 2d 6f 20 6e 6f 74 68 72 65 61 64 73 20 20 20 20  -o nothreads    
c210: 45 6e 61 62 6c 65 20 73 69 6e 67 6c 65 20 74 68  Enable single th
c220: 72 65 61 64 65 64 20 6d 6f 64 65 2e 5c 6e 22 29  readed mode.\n")
c230: 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e  ;..fprintf(chann
c240: 65 6c 2c 20 22 20 20 2d 6f 20 61 6c 6c 6f 77 5f  el, "  -o allow_
c250: 6f 74 68 65 72 20 20 41 6c 6c 6f 77 20 6f 74 68  other  Allow oth
c260: 65 72 20 75 73 65 72 73 20 74 6f 20 61 63 63 65  er users to acce
c270: 73 73 20 74 68 69 73 20 6d 6f 75 6e 74 70 6f 69  ss this mountpoi
c280: 6e 74 20 28 64 65 66 61 75 6c 74 5c 6e 22 29 3b  nt (default\n");
c290: 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65  ..fprintf(channe
c2a0: 6c 2c 20 22 20 20 20 20 20 20 20 20 20 20 20 20  l, "            
c2b0: 20 20 20 20 20 20 69 66 20 72 6f 6f 74 29 2e 5c        if root).\
c2c0: 6e 22 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d  n");...return;.}
c2d0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
c2e0: 66 73 5f 6f 70 74 5f 70 61 72 73 65 28 69 6e 74  fs_opt_parse(int
c2f0: 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a 61 72   argc, char **ar
c300: 67 76 2c 20 20 73 74 72 75 63 74 20 66 75 73 65  gv,  struct fuse
c310: 5f 61 72 67 73 20 2a 61 72 67 73 29 20 7b 0a 09  _args *args) {..
c320: 69 6e 74 20 63 68 3b 0a 09 63 68 61 72 20 2a 6f  int ch;..char *o
c330: 70 74 73 74 72 2c 20 2a 6f 70 74 73 74 72 5f 6e  ptstr, *optstr_n
c340: 65 78 74 2c 20 2a 6f 70 74 73 74 72 5f 73 3b 0a  ext, *optstr_s;.
c350: 09 63 68 61 72 20 66 61 6b 65 5f 61 72 67 5b 33  .char fake_arg[3
c360: 5d 20 3d 20 7b 27 2d 27 2c 20 30 2c 20 30 7d 3b  ] = {'-', 0, 0};
c370: 0a 0a 09 2f 2a 0a 09 20 2a 20 44 65 66 61 75 6c  .../*.. * Defaul
c380: 74 20 76 61 6c 75 65 73 0a 09 20 2a 2f 0a 23 69  t values.. */.#i
c390: 66 20 64 65 66 69 6e 65 64 28 54 43 4c 5f 54 48  f defined(TCL_TH
c3a0: 52 45 41 44 53 29 20 26 26 20 54 43 4c 5f 54 48  READS) && TCL_TH
c3b0: 52 45 41 44 53 20 3d 3d 20 31 0a 09 61 70 70 66  READS == 1..appf
c3c0: 73 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 20 3d  s_threaded_tcl =
c3d0: 20 31 3b 0a 23 65 6c 73 65 0a 09 61 70 70 66 73   1;.#else..appfs
c3e0: 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 20 3d 20  _threaded_tcl = 
c3f0: 30 3b 0a 23 65 6e 64 69 66 0a 0a 09 2f 2a 2a 0a  0;.#endif.../**.
c400: 09 20 2a 2a 20 41 64 64 20 46 55 53 45 20 61 72  . ** Add FUSE ar
c410: 67 75 6d 65 6e 74 73 20 77 68 69 63 68 20 77 65  guments which we
c420: 20 61 6c 77 61 79 73 20 73 75 70 70 6c 79 0a 09   always supply..
c430: 20 2a 2a 2f 0a 09 66 75 73 65 5f 6f 70 74 5f 61   **/..fuse_opt_a
c440: 64 64 5f 61 72 67 28 61 72 67 73 2c 20 22 2d 6f  dd_arg(args, "-o
c450: 64 65 66 61 75 6c 74 5f 70 65 72 6d 69 73 73 69  default_permissi
c460: 6f 6e 73 2c 66 73 6e 61 6d 65 3d 61 70 70 66 73  ons,fsname=appfs
c470: 2c 73 75 62 74 79 70 65 3d 61 70 70 66 73 64 2c  ,subtype=appfsd,
c480: 75 73 65 5f 69 6e 6f 2c 65 6e 74 72 79 5f 74 69  use_ino,entry_ti
c490: 6d 65 6f 75 74 3d 30 2c 61 74 74 72 5f 74 69 6d  meout=0,attr_tim
c4a0: 65 6f 75 74 3d 30 2c 62 69 67 5f 77 72 69 74 65  eout=0,big_write
c4b0: 73 2c 69 6e 74 72 2c 68 61 72 64 5f 72 65 6d 6f  s,intr,hard_remo
c4c0: 76 65 22 29 3b 0a 0a 09 69 66 20 28 67 65 74 75  ve");...if (getu
c4d0: 69 64 28 29 20 3d 3d 20 30 29 20 7b 0a 09 09 66  id() == 0) {...f
c4e0: 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72  use_opt_parse(ar
c4f0: 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20  gs, NULL, NULL, 
c500: 4e 55 4c 4c 29 3b 0a 09 09 66 75 73 65 5f 6f 70  NULL);...fuse_op
c510: 74 5f 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20  t_add_arg(args, 
c520: 22 2d 6f 61 6c 6c 6f 77 5f 6f 74 68 65 72 22 29  "-oallow_other")
c530: 3b 0a 0a 09 09 2f 2a 0a 09 09 20 2a 20 54 68 69  ;..../*... * Thi
c540: 73 20 73 68 6f 75 6c 64 20 67 65 6e 65 72 61 6c  s should general
c550: 6c 79 20 62 65 20 61 76 6f 69 64 65 64 2c 20 62  ly be avoided, b
c560: 75 74 20 69 66 20 74 68 65 72 65 20 61 72 65 20  ut if there are 
c570: 73 65 63 75 72 69 74 79 0a 09 09 20 2a 20 63 6f  security... * co
c580: 6e 63 65 72 6e 73 20 73 75 69 64 20 63 61 6e 20  ncerns suid can 
c590: 62 65 20 64 69 73 61 62 6c 65 64 20 63 6f 6d 70  be disabled comp
c5a0: 6c 65 74 65 6c 79 20 6f 6e 20 74 68 65 20 63 6f  letely on the co
c5b0: 6d 6d 61 6e 64 6c 69 6e 65 0a 09 09 20 2a 2f 0a  mmandline... */.
c5c0: 09 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65  ..fuse_opt_parse
c5d0: 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  (args, NULL, NUL
c5e0: 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09 66 75 73 65  L, NULL);...fuse
c5f0: 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72 67  _opt_add_arg(arg
c600: 73 2c 20 22 2d 6f 73 75 69 64 22 29 3b 0a 09 7d  s, "-osuid");..}
c610: 0a 0a 09 77 68 69 6c 65 20 28 28 63 68 20 3d 20  ...while ((ch = 
c620: 67 65 74 6f 70 74 28 61 72 67 63 2c 20 61 72 67  getopt(argc, arg
c630: 76 2c 20 22 64 66 73 68 76 6f 3a 22 29 29 20 21  v, "dfshvo:")) !
c640: 3d 20 2d 31 29 20 7b 0a 09 09 73 77 69 74 63 68  = -1) {...switch
c650: 20 28 63 68 29 20 7b 0a 09 09 09 63 61 73 65 20   (ch) {....case 
c660: 27 76 27 3a 0a 09 09 09 09 2f 2a 20 49 67 6e 6f  'v':...../* Igno
c670: 72 65 64 20 2a 2f 0a 09 09 09 09 62 72 65 61 6b  red */.....break
c680: 3b 0a 09 09 09 63 61 73 65 20 27 6f 27 3a 0a 09  ;....case 'o':..
c690: 09 09 09 6f 70 74 73 74 72 5f 6e 65 78 74 20 3d  ...optstr_next =
c6a0: 20 6f 70 74 73 74 72 20 3d 20 6f 70 74 73 74 72   optstr = optstr
c6b0: 5f 73 20 3d 20 73 74 72 64 75 70 28 6f 70 74 61  _s = strdup(opta
c6c0: 72 67 29 3b 0a 0a 09 09 09 09 77 68 69 6c 65 20  rg);......while 
c6d0: 28 31 29 20 7b 0a 09 09 09 09 09 6f 70 74 73 74  (1) {......optst
c6e0: 72 20 3d 20 6f 70 74 73 74 72 5f 6e 65 78 74 3b  r = optstr_next;
c6f0: 0a 0a 09 09 09 09 09 69 66 20 28 21 6f 70 74 73  .......if (!opts
c700: 74 72 29 20 7b 0a 09 09 09 09 09 09 62 72 65 61  tr) {.......brea
c710: 6b 3b 0a 09 09 09 09 09 7d 0a 0a 09 09 09 09 09  k;......}.......
c720: 6f 70 74 73 74 72 5f 6e 65 78 74 20 3d 20 73 74  optstr_next = st
c730: 72 63 68 72 28 6f 70 74 73 74 72 2c 20 27 2c 27  rchr(optstr, ','
c740: 29 3b 0a 09 09 09 09 09 69 66 20 28 6f 70 74 73  );......if (opts
c750: 74 72 5f 6e 65 78 74 29 20 7b 0a 09 09 09 09 09  tr_next) {......
c760: 09 2a 6f 70 74 73 74 72 5f 6e 65 78 74 20 3d 20  .*optstr_next = 
c770: 27 5c 30 27 3b 0a 09 09 09 09 09 09 6f 70 74 73  '\0';.......opts
c780: 74 72 5f 6e 65 78 74 2b 2b 3b 0a 09 09 09 09 09  tr_next++;......
c790: 7d 0a 0a 09 09 09 09 09 69 66 20 28 73 74 72 63  }.......if (strc
c7a0: 6d 70 28 6f 70 74 73 74 72 2c 20 22 6e 6f 74 68  mp(optstr, "noth
c7b0: 72 65 61 64 73 22 29 20 3d 3d 20 30 29 20 7b 0a  reads") == 0) {.
c7c0: 09 09 09 09 09 09 41 50 50 46 53 5f 44 45 42 55  ......APPFS_DEBU
c7d0: 47 28 22 50 61 73 73 69 6e 67 20 6f 70 74 69 6f  G("Passing optio
c7e0: 6e 20 74 6f 20 46 55 53 45 3a 20 2d 73 22 29 3b  n to FUSE: -s");
c7f0: 0a 0a 09 09 09 09 09 09 66 75 73 65 5f 6f 70 74  ........fuse_opt
c800: 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c  _parse(args, NUL
c810: 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  L, NULL, NULL);.
c820: 09 09 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 61  ......fuse_opt_a
c830: 64 64 5f 61 72 67 28 61 72 67 73 2c 20 22 2d 73  dd_arg(args, "-s
c840: 22 29 3b 0a 0a 09 09 09 09 09 09 61 70 70 66 73  ");........appfs
c850: 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 20 3d 20  _threaded_tcl = 
c860: 30 3b 0a 09 09 09 09 09 7d 20 65 6c 73 65 20 69  0;......} else i
c870: 66 20 28 73 74 72 63 6d 70 28 6f 70 74 73 74 72  f (strcmp(optstr
c880: 2c 20 22 61 6c 6c 6f 77 5f 6f 74 68 65 72 22 29  , "allow_other")
c890: 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09 09 41   == 0) {.......A
c8a0: 50 50 46 53 5f 44 45 42 55 47 28 22 50 61 73 73  PPFS_DEBUG("Pass
c8b0: 69 6e 67 20 6f 70 74 69 6f 6e 20 74 6f 20 46 55  ing option to FU
c8c0: 53 45 3a 20 2d 6f 20 61 6c 6c 6f 77 5f 6f 74 68  SE: -o allow_oth
c8d0: 65 72 22 29 3b 0a 0a 09 09 09 09 09 09 66 75 73  er");........fus
c8e0: 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67 73  e_opt_parse(args
c8f0: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55  , NULL, NULL, NU
c900: 4c 4c 29 3b 0a 09 09 09 09 09 09 66 75 73 65 5f  LL);.......fuse_
c910: 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72 67 73  opt_add_arg(args
c920: 2c 20 22 2d 6f 61 6c 6c 6f 77 5f 6f 74 68 65 72  , "-oallow_other
c930: 22 29 3b 0a 09 09 09 09 09 7d 20 65 6c 73 65 20  ");......} else 
c940: 69 66 20 28 73 74 72 63 6d 70 28 6f 70 74 73 74  if (strcmp(optst
c950: 72 2c 20 22 72 77 22 29 20 3d 3d 20 30 29 20 7b  r, "rw") == 0) {
c960: 0a 09 09 09 09 09 09 2f 2a 20 49 67 6e 6f 72 65  ......./* Ignore
c970: 64 20 2a 2f 0a 09 09 09 09 09 7d 20 65 6c 73 65  d */......} else
c980: 20 7b 0a 09 09 09 09 09 09 41 50 50 46 53 5f 45   {.......APPFS_E
c990: 52 52 4f 52 28 22 61 70 70 66 73 64 3a 20 69 6e  RROR("appfsd: in
c9a0: 76 61 6c 69 64 20 6f 70 74 69 6f 6e 3a 20 5c 22  valid option: \"
c9b0: 2d 6f 20 25 73 5c 22 22 2c 20 6f 70 74 73 74 72  -o %s\"", optstr
c9c0: 29 3b 0a 0a 09 09 09 09 09 09 66 72 65 65 28 6f  );........free(o
c9d0: 70 74 73 74 72 5f 73 29 3b 0a 0a 09 09 09 09 09  ptstr_s);.......
c9e0: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 09 09 09  .return(1);.....
c9f0: 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66 72  .}.....}......fr
ca00: 65 65 28 6f 70 74 73 74 72 5f 73 29 3b 0a 0a 09  ee(optstr_s);...
ca10: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73  ...break;....cas
ca20: 65 20 27 64 27 3a 0a 09 09 09 63 61 73 65 20 27  e 'd':....case '
ca30: 66 27 3a 0a 09 09 09 63 61 73 65 20 27 73 27 3a  f':....case 's':
ca40: 0a 09 09 09 09 69 66 20 28 63 68 20 3d 3d 20 27  .....if (ch == '
ca50: 73 27 29 20 7b 0a 09 09 09 09 09 61 70 70 66 73  s') {......appfs
ca60: 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 20 3d 20  _threaded_tcl = 
ca70: 30 3b 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66 61  0;.....}......fa
ca80: 6b 65 5f 61 72 67 5b 31 5d 20 3d 20 63 68 3b 0a  ke_arg[1] = ch;.
ca90: 0a 09 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  .....APPFS_DEBUG
caa0: 28 22 50 61 73 73 69 6e 67 20 6f 70 74 69 6f 6e  ("Passing option
cab0: 20 74 6f 20 46 55 53 45 3a 20 25 73 22 2c 20 66   to FUSE: %s", f
cac0: 61 6b 65 5f 61 72 67 29 3b 0a 0a 09 09 09 09 66  ake_arg);......f
cad0: 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72  use_opt_parse(ar
cae0: 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20  gs, NULL, NULL, 
caf0: 4e 55 4c 4c 29 3b 0a 09 09 09 09 66 75 73 65 5f  NULL);.....fuse_
cb00: 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72 67 73  opt_add_arg(args
cb10: 2c 20 66 61 6b 65 5f 61 72 67 29 3b 0a 09 09 09  , fake_arg);....
cb20: 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20  .break;....case 
cb30: 27 68 27 3a 0a 09 09 09 09 61 70 70 66 73 5f 70  'h':.....appfs_p
cb40: 72 69 6e 74 5f 68 65 6c 70 28 73 74 64 6f 75 74  rint_help(stdout
cb50: 29 3b 0a 0a 09 09 09 09 72 65 74 75 72 6e 28 2d  );......return(-
cb60: 31 29 3b 0a 09 09 09 63 61 73 65 20 27 3a 27 3a  1);....case ':':
cb70: 0a 09 09 09 63 61 73 65 20 27 3f 27 3a 0a 09 09  ....case '?':...
cb80: 09 64 65 66 61 75 6c 74 3a 0a 09 09 09 09 61 70  .default:.....ap
cb90: 70 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28 73  pfs_print_help(s
cba0: 74 64 65 72 72 29 3b 0a 0a 09 09 09 09 72 65 74  tderr);......ret
cbb0: 75 72 6e 28 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a  urn(1);...}..}..
cbc0: 09 69 66 20 28 28 6f 70 74 69 6e 64 20 2b 20 32  .if ((optind + 2
cbd0: 29 20 21 3d 20 61 72 67 63 29 20 7b 0a 09 09 69  ) != argc) {...i
cbe0: 66 20 28 28 6f 70 74 69 6e 64 20 2b 20 32 29 20  f ((optind + 2) 
cbf0: 3c 20 61 72 67 63 29 20 7b 0a 09 09 09 41 50 50  < argc) {....APP
cc00: 46 53 5f 45 52 52 4f 52 28 22 54 6f 6f 20 6d 61  FS_ERROR("Too ma
cc10: 6e 79 20 61 72 67 75 6d 65 6e 74 73 22 29 3b 0a  ny arguments");.
cc20: 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 41 50  ..} else {....AP
cc30: 50 46 53 5f 45 52 52 4f 52 28 22 4d 69 73 73 69  PFS_ERROR("Missi
cc40: 6e 67 20 63 61 63 68 65 64 69 72 20 6f 72 20 6d  ng cachedir or m
cc50: 6f 75 6e 74 70 6f 69 6e 74 22 29 3b 0a 09 09 7d  ountpoint");...}
cc60: 0a 0a 09 09 61 70 70 66 73 5f 70 72 69 6e 74 5f  ....appfs_print_
cc70: 68 65 6c 70 28 73 74 64 65 72 72 29 3b 0a 0a 09  help(stderr);...
cc80: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a  .return(1);..}..
cc90: 09 2f 2a 0a 09 20 2a 20 53 65 74 20 63 61 63 68  ./*.. * Set cach
cca0: 65 20 64 69 72 20 61 73 20 66 69 72 73 74 20 61  e dir as first a
ccb0: 72 67 75 6d 65 6e 74 20 28 74 68 65 20 22 64 65  rgument (the "de
ccc0: 76 69 63 65 22 2c 20 65 73 73 65 6e 74 69 61 6c  vice", essential
ccd0: 6c 79 29 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f  ly).. */..appfs_
cce0: 63 61 63 68 65 64 69 72 20 3d 20 61 72 67 76 5b  cachedir = argv[
ccf0: 6f 70 74 69 6e 64 5d 3b 0a 0a 09 2f 2a 0a 09 20  optind];.../*.. 
cd00: 2a 20 50 61 73 73 20 74 68 65 20 72 65 6d 61 69  * Pass the remai
cd10: 6e 69 6e 67 20 61 72 67 75 6d 65 6e 74 20 74 6f  ning argument to
cd20: 20 46 55 53 45 20 61 73 20 74 68 65 20 64 69 72   FUSE as the dir
cd30: 65 63 74 6f 72 79 0a 09 20 2a 2f 0a 09 66 75 73  ectory.. */..fus
cd40: 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67 73  e_opt_parse(args
cd50: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55  , NULL, NULL, NU
cd60: 4c 4c 29 3b 0a 09 66 75 73 65 5f 6f 70 74 5f 61  LL);..fuse_opt_a
cd70: 64 64 5f 61 72 67 28 61 72 67 73 2c 20 61 72 67  dd_arg(args, arg
cd80: 76 5b 6f 70 74 69 6e 64 20 2b 20 31 5d 29 3b 0a  v[optind + 1]);.
cd90: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
cda0: 0a 2f 2a 0a 20 2a 20 46 55 53 45 20 6f 70 65 72  ./*. * FUSE oper
cdb0: 61 74 69 6f 6e 73 20 73 74 72 75 63 74 75 72 65  ations structure
cdc0: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 75  . */.static stru
cdd0: 63 74 20 66 75 73 65 5f 6f 70 65 72 61 74 69 6f  ct fuse_operatio
cde0: 6e 73 20 61 70 70 66 73 5f 6f 70 65 72 61 74 69  ns appfs_operati
cdf0: 6f 6e 73 20 3d 20 7b 0a 09 2e 67 65 74 61 74 74  ons = {...getatt
ce00: 72 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  r   = appfs_fuse
ce10: 5f 67 65 74 61 74 74 72 2c 0a 09 2e 72 65 61 64  _getattr,...read
ce20: 64 69 72 20 20 20 3d 20 61 70 70 66 73 5f 66 75  dir   = appfs_fu
ce30: 73 65 5f 72 65 61 64 64 69 72 2c 0a 09 2e 72 65  se_readdir,...re
ce40: 61 64 6c 69 6e 6b 20 20 3d 20 61 70 70 66 73 5f  adlink  = appfs_
ce50: 66 75 73 65 5f 72 65 61 64 6c 69 6e 6b 2c 0a 09  fuse_readlink,..
ce60: 2e 6f 70 65 6e 20 20 20 20 20 20 3d 20 61 70 70  .open      = app
ce70: 66 73 5f 66 75 73 65 5f 6f 70 65 6e 2c 0a 09 2e  fs_fuse_open,...
ce80: 72 65 6c 65 61 73 65 20 20 20 3d 20 61 70 70 66  release   = appf
ce90: 73 5f 66 75 73 65 5f 63 6c 6f 73 65 2c 0a 09 2e  s_fuse_close,...
cea0: 72 65 61 64 20 20 20 20 20 20 3d 20 61 70 70 66  read      = appf
ceb0: 73 5f 66 75 73 65 5f 72 65 61 64 2c 0a 09 2e 77  s_fuse_read,...w
cec0: 72 69 74 65 20 20 20 20 20 3d 20 61 70 70 66 73  rite     = appfs
ced0: 5f 66 75 73 65 5f 77 72 69 74 65 2c 0a 09 2e 6d  _fuse_write,...m
cee0: 6b 6e 6f 64 20 20 20 20 20 3d 20 61 70 70 66 73  knod     = appfs
cef0: 5f 66 75 73 65 5f 6d 6b 6e 6f 64 2c 0a 09 2e 63  _fuse_mknod,...c
cf00: 72 65 61 74 65 20 20 20 20 3d 20 61 70 70 66 73  reate    = appfs
cf10: 5f 66 75 73 65 5f 63 72 65 61 74 65 2c 0a 09 2e  _fuse_create,...
cf20: 74 72 75 6e 63 61 74 65 20 20 3d 20 61 70 70 66  truncate  = appf
cf30: 73 5f 66 75 73 65 5f 74 72 75 6e 63 61 74 65 2c  s_fuse_truncate,
cf40: 0a 09 2e 75 6e 6c 69 6e 6b 20 20 20 20 3d 20 61  ...unlink    = a
cf50: 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b  ppfs_fuse_unlink
cf60: 5f 72 6d 64 69 72 2c 0a 09 2e 72 6d 64 69 72 20  _rmdir,...rmdir 
cf70: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
cf80: 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72 2c 0a 09  _unlink_rmdir,..
cf90: 2e 6d 6b 64 69 72 20 20 20 20 20 3d 20 61 70 70  .mkdir     = app
cfa0: 66 73 5f 66 75 73 65 5f 6d 6b 64 69 72 2c 0a 09  fs_fuse_mkdir,..
cfb0: 2e 63 68 6d 6f 64 20 20 20 20 20 3d 20 61 70 70  .chmod     = app
cfc0: 66 73 5f 66 75 73 65 5f 63 68 6d 6f 64 2c 0a 09  fs_fuse_chmod,..
cfd0: 2e 73 79 6d 6c 69 6e 6b 20 20 20 3d 20 61 70 70  .symlink   = app
cfe0: 66 73 5f 66 75 73 65 5f 73 79 6d 6c 69 6e 6b 2c  fs_fuse_symlink,
cff0: 0a 7d 3b 0a 0a 0a 23 69 66 64 65 66 20 41 50 50  .};...#ifdef APP
d000: 46 53 5f 4e 4f 5f 52 4c 49 4d 49 54 0a 73 74 61  FS_NO_RLIMIT.sta
d010: 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 73  tic void appfs_s
d020: 65 74 5f 72 65 73 6f 75 72 63 65 5f 6c 69 6d 69  et_resource_limi
d030: 74 73 28 76 6f 69 64 29 20 7b 0a 09 72 65 74 75  ts(void) {..retu
d040: 72 6e 3b 0a 7d 0a 23 65 6c 73 65 0a 23 69 6e 63  rn;.}.#else.#inc
d050: 6c 75 64 65 20 3c 73 79 73 2f 72 65 73 6f 75 72  lude <sys/resour
d060: 63 65 2e 68 3e 20 20 0a 0a 73 74 61 74 69 63 20  ce.h>  ..static 
d070: 76 6f 69 64 20 61 70 70 66 73 5f 73 65 74 5f 72  void appfs_set_r
d080: 65 73 6f 75 72 63 65 5f 6c 69 6d 69 74 73 28 76  esource_limits(v
d090: 6f 69 64 29 20 7b 0a 09 73 74 72 75 63 74 20 72  oid) {..struct r
d0a0: 6c 69 6d 69 74 20 6e 75 6d 62 65 72 5f 6f 70 65  limit number_ope
d0b0: 6e 5f 66 69 6c 65 73 3b 0a 09 72 6c 69 6d 5f 74  n_files;..rlim_t
d0c0: 20 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c   number_open_fil
d0d0: 65 73 5f 6d 61 78 3b 0a 09 69 6e 74 20 72 6c 69  es_max;..int rli
d0e0: 6d 69 74 5f 72 65 74 3b 0a 0a 09 2f 2a 0a 09 20  mit_ret;.../*.. 
d0f0: 2a 20 49 6e 63 72 65 61 73 65 20 72 65 73 6f 75  * Increase resou
d100: 72 63 65 20 6c 69 6d 69 74 73 20 66 6f 72 20 6e  rce limits for n
d110: 75 6d 62 65 72 20 6f 66 20 6f 70 65 6e 20 66 69  umber of open fi
d120: 6c 65 73 0a 09 20 2a 20 74 6f 20 74 68 65 20 6d  les.. * to the m
d130: 61 78 69 6d 75 6d 20 76 61 6c 75 65 73 2c 20 73  aximum values, s
d140: 69 6e 63 65 20 77 65 20 6d 61 79 20 62 65 20 61  ince we may be a
d150: 73 6b 65 64 20 74 6f 0a 09 20 2a 20 68 6f 6c 64  sked to.. * hold
d160: 20 6f 70 65 6e 20 6d 61 6e 79 20 66 69 6c 65 73   open many files
d170: 20 6f 6e 20 62 65 68 61 6c 66 20 6f 66 20 6d 61   on behalf of ma
d180: 6e 79 20 6f 74 68 65 72 20 70 72 6f 63 65 73 73  ny other process
d190: 65 73 0a 09 20 2a 2f 0a 09 6e 75 6d 62 65 72 5f  es.. */..number_
d1a0: 6f 70 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f  open_files.rlim_
d1b0: 63 75 72 20 3d 20 6e 75 6d 62 65 72 5f 6f 70 65  cur = number_ope
d1c0: 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f 6d 61 78  n_files.rlim_max
d1d0: 20 3d 20 52 4c 49 4d 5f 49 4e 46 49 4e 49 54 59   = RLIM_INFINITY
d1e0: 3b 0a 0a 09 72 6c 69 6d 69 74 5f 72 65 74 20 3d  ;...rlimit_ret =
d1f0: 20 73 65 74 72 6c 69 6d 69 74 28 52 4c 49 4d 49   setrlimit(RLIMI
d200: 54 5f 4e 4f 46 49 4c 45 2c 20 26 6e 75 6d 62 65  T_NOFILE, &numbe
d210: 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 29 3b 0a 0a  r_open_files);..
d220: 09 69 66 20 28 72 6c 69 6d 69 74 5f 72 65 74 20  .if (rlimit_ret 
d230: 21 3d 20 30 29 20 7b 0a 09 09 72 6c 69 6d 69 74  != 0) {...rlimit
d240: 5f 72 65 74 20 3d 20 67 65 74 72 6c 69 6d 69 74  _ret = getrlimit
d250: 28 52 4c 49 4d 49 54 5f 4e 4f 46 49 4c 45 2c 20  (RLIMIT_NOFILE, 
d260: 26 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c  &number_open_fil
d270: 65 73 29 3b 0a 09 09 69 66 20 28 72 6c 69 6d 69  es);...if (rlimi
d280: 74 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09 09  t_ret == 0) {...
d290: 09 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c  .number_open_fil
d2a0: 65 73 5f 6d 61 78 20 3d 20 6e 75 6d 62 65 72 5f  es_max = number_
d2b0: 6f 70 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f  open_files.rlim_
d2c0: 6d 61 78 3b 0a 0a 09 09 09 69 66 20 28 6e 75 6d  max;.....if (num
d2d0: 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 5f 6d  ber_open_files_m
d2e0: 61 78 20 3c 20 28 31 30 32 34 20 2a 20 31 30 32  ax < (1024 * 102
d2f0: 34 29 29 20 7b 0a 09 09 09 09 6e 75 6d 62 65 72  4)) {.....number
d300: 5f 6f 70 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d  _open_files.rlim
d310: 5f 63 75 72 20 3d 20 6e 75 6d 62 65 72 5f 6f 70  _cur = number_op
d320: 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f 6d 61  en_files.rlim_ma
d330: 78 20 3d 20 31 30 32 34 20 2a 20 31 30 32 34 3b  x = 1024 * 1024;
d340: 0a 0a 09 09 09 09 72 6c 69 6d 69 74 5f 72 65 74  ......rlimit_ret
d350: 20 3d 20 73 65 74 72 6c 69 6d 69 74 28 52 4c 49   = setrlimit(RLI
d360: 4d 49 54 5f 4e 4f 46 49 4c 45 2c 20 26 6e 75 6d  MIT_NOFILE, &num
d370: 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 29 3b  ber_open_files);
d380: 0a 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09  ....} else {....
d390: 09 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c  .number_open_fil
d3a0: 65 73 2e 72 6c 69 6d 5f 63 75 72 20 3d 20 6e 75  es.rlim_cur = nu
d3b0: 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 2e  mber_open_files.
d3c0: 72 6c 69 6d 5f 6d 61 78 3b 0a 09 09 09 7d 0a 0a  rlim_max;....}..
d3d0: 09 09 09 72 6c 69 6d 69 74 5f 72 65 74 20 3d 20  ...rlimit_ret = 
d3e0: 73 65 74 72 6c 69 6d 69 74 28 52 4c 49 4d 49 54  setrlimit(RLIMIT
d3f0: 5f 4e 4f 46 49 4c 45 2c 20 26 6e 75 6d 62 65 72  _NOFILE, &number
d400: 5f 6f 70 65 6e 5f 66 69 6c 65 73 29 3b 0a 0a 09  _open_files);...
d410: 09 09 69 66 20 28 72 6c 69 6d 69 74 5f 72 65 74  ..if (rlimit_ret
d420: 20 21 3d 20 30 20 26 26 20 6e 75 6d 62 65 72 5f   != 0 && number_
d430: 6f 70 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f  open_files.rlim_
d440: 63 75 72 20 21 3d 20 6e 75 6d 62 65 72 5f 6f 70  cur != number_op
d450: 65 6e 5f 66 69 6c 65 73 5f 6d 61 78 29 20 7b 0a  en_files_max) {.
d460: 09 09 09 09 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f  ....number_open_
d470: 66 69 6c 65 73 2e 72 6c 69 6d 5f 63 75 72 20 3d  files.rlim_cur =
d480: 20 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c   number_open_fil
d490: 65 73 2e 72 6c 69 6d 5f 6d 61 78 20 3d 20 6e 75  es.rlim_max = nu
d4a0: 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 5f  mber_open_files_
d4b0: 6d 61 78 3b 0a 0a 09 09 09 09 73 65 74 72 6c 69  max;......setrli
d4c0: 6d 69 74 28 52 4c 49 4d 49 54 5f 4e 4f 46 49 4c  mit(RLIMIT_NOFIL
d4d0: 45 2c 20 26 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f  E, &number_open_
d4e0: 66 69 6c 65 73 29 3b 0a 09 09 09 7d 0a 09 09 7d  files);....}...}
d4f0: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a  ..}...return;.}.
d500: 23 65 6e 64 69 66 0a 0a 2f 2a 0a 20 2a 20 45 6e  #endif../*. * En
d510: 74 72 79 20 70 6f 69 6e 74 20 69 6e 74 6f 20 74  try point into t
d520: 68 69 73 20 70 72 6f 67 72 61 6d 2e 0a 20 2a 2f  his program.. */
d530: 0a 69 6e 74 20 6d 61 69 6e 28 69 6e 74 20 61 72  .int main(int ar
d540: 67 63 2c 20 63 68 61 72 20 2a 2a 61 72 67 76 29  gc, char **argv)
d550: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
d560: 74 65 73 74 5f 69 6e 74 65 72 70 3b 0a 09 63 68  test_interp;..ch
d570: 61 72 20 2a 74 65 73 74 5f 69 6e 74 65 72 70 5f  ar *test_interp_
d580: 65 72 72 6f 72 3b 0a 09 73 74 72 75 63 74 20 66  error;..struct f
d590: 75 73 65 5f 61 72 67 73 20 61 72 67 73 20 3d 20  use_args args = 
d5a0: 46 55 53 45 5f 41 52 47 53 5f 49 4e 49 54 28 30  FUSE_ARGS_INIT(0
d5b0: 2c 20 4e 55 4c 4c 29 3b 0a 09 69 6e 74 20 70 74  , NULL);..int pt
d5c0: 68 72 65 61 64 5f 72 65 74 2c 20 61 6f 70 5f 72  hread_ret, aop_r
d5d0: 65 74 3b 0a 09 63 68 61 72 20 2a 61 72 67 76 30  et;..char *argv0
d5e0: 3b 0a 69 6e 74 20 69 3b 0a 0a 09 2f 2a 0a 09 20  ;.int i;.../*.. 
d5f0: 2a 20 53 6b 69 70 20 70 61 73 73 65 64 20 70 72  * Skip passed pr
d600: 6f 67 72 61 6d 20 6e 61 6d 65 0a 09 20 2a 2f 0a  ogram name.. */.
d610: 09 69 66 20 28 61 72 67 63 20 3d 3d 20 30 20 7c  .if (argc == 0 |
d620: 7c 20 61 72 67 76 20 3d 3d 20 4e 55 4c 4c 29 20  | argv == NULL) 
d630: 7b 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  {...return(1);..
d640: 7d 0a 66 6f 72 20 28 69 20 3d 20 30 3b 20 69 20  }.for (i = 0; i 
d650: 3c 20 61 72 67 63 3b 20 69 2b 2b 29 20 7b 0a 2f  < argc; i++) {./
d660: 2f 09 70 72 69 6e 74 66 28 22 61 72 67 76 5b 25  /.printf("argv[%
d670: 69 5d 20 3d 20 5c 22 25 73 5c 22 5c 6e 22 2c 20  i] = \"%s\"\n", 
d680: 69 2c 20 61 72 67 76 5b 69 5d 29 3b 0a 7d 0a 0a  i, argv[i]);.}..
d690: 09 61 72 67 76 30 20 3d 20 61 72 67 76 5b 30 5d  .argv0 = argv[0]
d6a0: 3b 0a 0a 09 61 72 67 63 2d 2d 3b 0a 09 61 72 67  ;...argc--;..arg
d6b0: 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65  v++;.../*.. * Se
d6c0: 74 20 61 70 70 72 6f 70 72 69 61 74 65 20 75 6d  t appropriate um
d6d0: 61 73 6b 0a 09 20 2a 2f 0a 09 75 6d 61 73 6b 28  ask.. */..umask(
d6e0: 30 32 32 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53  022);.../*.. * S
d6f0: 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62  et global variab
d700: 6c 65 73 2c 20 74 68 65 73 65 20 73 68 6f 75 6c  les, these shoul
d710: 64 20 62 65 20 63 6f 6e 66 69 67 75 72 61 74 69  d be configurati
d720: 6f 6e 20 6f 70 74 69 6f 6e 73 2e 0a 09 20 2a 2f  on options... */
d730: 0a 09 61 70 70 66 73 5f 63 61 63 68 65 64 69 72  ..appfs_cachedir
d740: 20 3d 20 41 50 50 46 53 5f 43 41 43 48 45 44 49   = APPFS_CACHEDI
d750: 52 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65 74 20  R;.../*.. * Set 
d760: 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 20  global variable 
d770: 66 6f 72 20 22 62 6f 6f 74 20 74 69 6d 65 22 20  for "boot time" 
d780: 74 6f 20 73 65 74 20 61 20 74 69 6d 65 20 6f 6e  to set a time on
d790: 20 64 69 72 65 63 74 6f 72 69 65 73 0a 09 20 2a   directories.. *
d7a0: 20 74 68 61 74 20 77 65 20 66 61 6b 65 2e 0a 09   that we fake...
d7b0: 20 2a 2f 0a 09 61 70 70 66 73 5f 62 6f 6f 74 74   */..appfs_boott
d7c0: 69 6d 65 20 3d 20 74 69 6d 65 28 4e 55 4c 4c 29  ime = time(NULL)
d7d0: 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 67 69 73  ;.../*.. * Regis
d7e0: 74 65 72 20 22 73 68 61 31 22 20 61 6e 64 20 22  ter "sha1" and "
d7f0: 61 70 70 66 73 64 22 20 70 61 63 6b 61 67 65 20  appfsd" package 
d800: 77 69 74 68 20 6c 69 62 74 63 6c 20 73 6f 20 74  with libtcl so t
d810: 68 61 74 20 61 6e 79 20 6e 65 77 0a 09 20 2a 20  hat any new.. * 
d820: 69 6e 74 65 72 70 72 65 74 65 72 73 20 63 72 65  interpreters cre
d830: 61 74 65 64 20 28 77 68 69 63 68 20 61 72 65 20  ated (which are 
d840: 64 6f 6e 65 20 64 79 6e 61 6d 69 63 61 6c 6c 79  done dynamically
d850: 20 62 79 20 46 55 53 45 29 20 63 61 6e 20 68 61   by FUSE) can ha
d860: 76 65 0a 09 20 2a 20 74 68 65 20 61 70 70 72 6f  ve.. * the appro
d870: 70 72 69 61 74 65 20 63 6f 6e 66 69 67 75 72 61  priate configura
d880: 74 69 6f 6e 20 64 6f 6e 65 20 61 75 74 6f 6d 61  tion done automa
d890: 74 69 63 61 6c 6c 79 2e 0a 09 20 2a 2f 0a 09 54  tically... */..T
d8a0: 63 6c 5f 53 74 61 74 69 63 50 61 63 6b 61 67 65  cl_StaticPackage
d8b0: 28 4e 55 4c 4c 2c 20 22 73 68 61 31 22 2c 20 53  (NULL, "sha1", S
d8c0: 68 61 31 5f 49 6e 69 74 2c 20 4e 55 4c 4c 29 3b  ha1_Init, NULL);
d8d0: 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61 63 6b  ..Tcl_StaticPack
d8e0: 61 67 65 28 4e 55 4c 4c 2c 20 22 61 70 70 66 73  age(NULL, "appfs
d8f0: 64 22 2c 20 41 70 70 66 73 64 5f 49 6e 69 74 2c  d", Appfsd_Init,
d900: 20 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a   NULL);.../*.. *
d910: 20 43 72 65 61 74 65 20 61 20 74 68 72 65 61 64   Create a thread
d920: 2d 73 70 65 63 69 66 69 63 2d 64 61 74 61 20 28  -specific-data (
d930: 54 53 44 29 20 6b 65 79 20 66 6f 72 20 65 61 63  TSD) key for eac
d940: 68 20 74 68 72 65 61 64 20 74 6f 20 72 65 66 65  h thread to refe
d950: 72 0a 09 20 2a 20 74 6f 20 69 74 73 20 6f 77 6e  r.. * to its own
d960: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
d970: 2e 20 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  .  Tcl interpret
d980: 65 72 73 20 6d 75 73 74 20 62 65 20 75 6e 69 71  ers must be uniq
d990: 75 65 20 70 65 72 0a 09 20 2a 20 74 68 72 65 61  ue per.. * threa
d9a0: 64 20 61 6e 64 20 6e 65 77 20 74 68 72 65 61 64  d and new thread
d9b0: 73 20 61 72 65 20 64 79 6e 61 6d 69 63 61 6c 6c  s are dynamicall
d9c0: 79 20 63 72 65 61 74 65 64 20 62 79 20 46 55 53  y created by FUS
d9d0: 45 2e 0a 09 20 2a 2f 0a 09 70 74 68 72 65 61 64  E... */..pthread
d9e0: 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6b  _ret = pthread_k
d9f0: 65 79 5f 63 72 65 61 74 65 28 26 69 6e 74 65 72  ey_create(&inter
da00: 70 4b 65 79 2c 20 61 70 70 66 73 5f 74 65 72 6d  pKey, appfs_term
da10: 69 6e 61 74 65 5f 69 6e 74 65 72 70 5f 61 6e 64  inate_interp_and
da20: 5f 74 68 72 65 61 64 29 3b 0a 09 69 66 20 28 70  _thread);..if (p
da30: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
da40: 20 7b 0a 09 09 41 50 50 46 53 5f 45 52 52 4f 52   {...APPFS_ERROR
da50: 28 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61  ("Unable to crea
da60: 74 65 20 54 53 44 20 6b 65 79 20 66 6f 72 20 54  te TSD key for T
da70: 63 6c 2e 20 20 41 62 6f 72 74 69 6e 67 2e 22 29  cl.  Aborting.")
da80: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a  ;....return(1);.
da90: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4d 61 6e 75  .}.../*.. * Manu
daa0: 61 6c 6c 79 20 73 70 65 63 69 66 79 20 63 61 63  ally specify cac
dab0: 68 65 20 64 69 72 65 63 74 6f 72 79 2c 20 77 69  he directory, wi
dac0: 74 68 6f 75 74 20 46 55 53 45 20 63 61 6c 6c 62  thout FUSE callb
dad0: 61 63 6b 0a 09 20 2a 20 54 68 69 73 20 6f 70 74  ack.. * This opt
dae0: 69 6f 6e 20 6f 6e 6c 79 20 77 6f 72 6b 73 20 77  ion only works w
daf0: 68 65 6e 20 6e 6f 74 20 75 73 69 6e 67 20 46 55  hen not using FU
db00: 53 45 2c 20 73 69 6e 63 65 20 77 65 0a 09 20 2a  SE, since we.. *
db10: 20 64 6f 20 6e 6f 74 20 70 72 6f 63 65 73 73 20   do not process 
db20: 69 74 20 77 69 74 68 20 46 55 53 45 73 20 6f 70  it with FUSEs op
db30: 74 69 6f 6e 20 70 72 6f 63 65 73 73 69 6e 67 2e  tion processing.
db40: 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20  .. */..if (argc 
db50: 3e 3d 20 32 29 20 7b 0a 09 09 69 66 20 28 73 74  >= 2) {...if (st
db60: 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d  rcmp(argv[0], "-
db70: 2d 63 61 63 68 65 64 69 72 22 29 20 3d 3d 20 30  -cachedir") == 0
db80: 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 63  ) {....appfs_cac
db90: 68 65 64 69 72 20 3d 20 73 74 72 64 75 70 28 61  hedir = strdup(a
dba0: 72 67 76 5b 31 5d 29 3b 0a 0a 09 09 09 61 72 67  rgv[1]);.....arg
dbb0: 63 20 2d 3d 20 32 3b 0a 09 09 09 61 72 67 76 20  c -= 2;....argv 
dbc0: 2b 3d 20 32 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 2f  += 2;...}..}.../
dbd0: 2a 0a 09 20 2a 20 53 51 4c 69 74 65 33 20 6d 6f  *.. * SQLite3 mo
dbe0: 64 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20  de, for running 
dbf0: 72 61 77 20 53 51 4c 20 61 67 61 69 6e 73 74 20  raw SQL against 
dc00: 74 68 65 20 63 61 63 68 65 20 64 61 74 61 62 61  the cache databa
dc10: 73 65 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72 67  se.. */..if (arg
dc20: 63 20 3d 3d 20 32 20 26 26 20 73 74 72 63 6d 70  c == 2 && strcmp
dc30: 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 73 71 6c  (argv[0], "--sql
dc40: 69 74 65 33 22 29 20 3d 3d 20 30 29 20 7b 0a 09  ite3") == 0) {..
dc50: 09 72 65 74 75 72 6e 28 61 70 70 66 73 5f 73 71  .return(appfs_sq
dc60: 6c 69 74 65 33 28 61 72 67 76 5b 31 5d 29 29 3b  lite3(argv[1]));
dc70: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 54 63 6c  ..}.../*.. * Tcl
dc80: 20 6d 6f 64 65 2c 20 66 6f 72 20 72 75 6e 6e 69   mode, for runni
dc90: 6e 67 20 72 61 77 20 54 63 6c 20 69 6e 20 74 68  ng raw Tcl in th
dca0: 65 20 73 61 6d 65 20 65 6e 76 69 72 6f 6e 6d 65  e same environme
dcb0: 6e 74 20 41 70 70 46 53 64 20 77 6f 75 6c 64 0a  nt AppFSd would.
dcc0: 09 20 2a 20 72 75 6e 20 63 6f 64 65 2e 0a 09 20  . * run code... 
dcd0: 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20  */..if (argc == 
dce0: 32 20 26 26 20 73 74 72 63 6d 70 28 61 72 67 76  2 && strcmp(argv
dcf0: 5b 30 5d 2c 20 22 2d 2d 74 63 6c 22 29 20 3d 3d  [0], "--tcl") ==
dd00: 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 61   0) {...return(a
dd10: 70 70 66 73 5f 74 63 6c 28 61 72 67 76 5b 31 5d  ppfs_tcl(argv[1]
dd20: 29 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20  ));..}.../*.. * 
dd30: 50 61 72 73 65 20 63 6f 6d 6d 61 6e 64 20 6c 69  Parse command li
dd40: 6e 65 20 61 72 67 75 6d 65 6e 74 73 0a 09 20 2a  ne arguments.. *
dd50: 2f 0a 09 2f 2a 2a 0a 09 20 2a 2a 20 52 65 73 74  /../**.. ** Rest
dd60: 6f 72 65 20 61 72 67 63 2f 61 72 67 76 20 74 6f  ore argc/argv to
dd70: 20 6f 72 69 67 69 6e 61 6c 20 76 61 6c 75 65 73   original values
dd80: 2c 20 72 65 70 6c 61 63 69 6e 67 20 61 72 67 76  , replacing argv
dd90: 5b 30 5d 20 69 6e 20 63 61 73 65 0a 09 20 2a 2a  [0] in case.. **
dda0: 20 69 74 20 77 61 73 20 6d 6f 69 66 69 65 64 20   it was moified 
ddb0: 62 79 20 2d 2d 63 61 63 68 65 64 69 72 20 6f 70  by --cachedir op
ddc0: 74 69 6f 6e 2e 0a 09 20 2a 2a 2f 0a 09 61 72 67  tion... **/..arg
ddd0: 63 2b 2b 3b 0a 09 61 72 67 76 2d 2d 3b 0a 09 61  c++;..argv--;..a
dde0: 72 67 76 5b 30 5d 20 3d 20 61 72 67 76 30 3b 0a  rgv[0] = argv0;.
ddf0: 0a 09 2f 2a 2a 0a 09 20 2a 2a 20 50 65 72 66 6f  ../**.. ** Perfo
de00: 72 6d 20 74 68 65 20 61 72 67 75 6d 65 6e 74 20  rm the argument 
de10: 70 61 72 73 69 6e 67 0a 09 20 2a 2a 2f 0a 09 61  parsing.. **/..a
de20: 6f 70 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 6f  op_ret = appfs_o
de30: 70 74 5f 70 61 72 73 65 28 61 72 67 63 2c 20 61  pt_parse(argc, a
de40: 72 67 76 2c 20 26 61 72 67 73 29 3b 0a 09 69 66  rgv, &args);..if
de50: 20 28 61 6f 70 5f 72 65 74 20 21 3d 20 30 29 20   (aop_ret != 0) 
de60: 7b 0a 09 09 69 66 20 28 61 6f 70 5f 72 65 74 20  {...if (aop_ret 
de70: 3c 20 30 29 20 7b 0a 09 09 09 72 65 74 75 72 6e  < 0) {....return
de80: 28 30 29 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 75  (0);...}....retu
de90: 72 6e 28 61 6f 70 5f 72 65 74 29 3b 0a 09 7d 0a  rn(aop_ret);..}.
dea0: 0a 09 2f 2a 0a 09 20 2a 20 43 72 65 61 74 65 20  ../*.. * Create 
deb0: 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  a Tcl interprete
dec0: 72 20 6a 75 73 74 20 74 6f 20 76 65 72 69 66 79  r just to verify
ded0: 20 74 68 61 74 20 74 68 69 6e 67 73 20 61 72 65   that things are
dee0: 20 69 6e 20 77 6f 72 6b 69 6e 67 20 0a 09 20 2a   in working .. *
def0: 20 6f 72 64 65 72 20 62 65 66 6f 72 65 20 77 65   order before we
df00: 20 62 65 63 6f 6d 65 20 61 20 64 61 65 6d 6f 6e   become a daemon
df10: 2e 0a 09 20 2a 2f 0a 09 74 65 73 74 5f 69 6e 74  ... */..test_int
df20: 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61  erp = appfs_crea
df30: 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 26 74 65  te_TclInterp(&te
df40: 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 29  st_interp_error)
df50: 3b 0a 09 69 66 20 28 74 65 73 74 5f 69 6e 74 65  ;..if (test_inte
df60: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
df70: 69 66 20 28 74 65 73 74 5f 69 6e 74 65 72 70 5f  if (test_interp_
df80: 65 72 72 6f 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b  error == NULL) {
df90: 0a 09 09 09 74 65 73 74 5f 69 6e 74 65 72 70 5f  ....test_interp_
dfa0: 65 72 72 6f 72 20 3d 20 22 55 6e 6b 6e 6f 77 6e  error = "Unknown
dfb0: 20 65 72 72 6f 72 22 3b 0a 09 09 7d 0a 0a 09 09   error";...}....
dfc0: 41 50 50 46 53 5f 45 52 52 4f 52 28 22 55 6e 61  APPFS_ERROR("Una
dfd0: 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a  ble to initializ
dfe0: 65 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  e Tcl interprete
dff0: 72 20 66 6f 72 20 41 70 70 46 53 64 3a 22 29 3b  r for AppFSd:");
e000: 0a 09 09 41 50 50 46 53 5f 45 52 52 4f 52 28 22  ...APPFS_ERROR("
e010: 25 73 22 2c 20 74 65 73 74 5f 69 6e 74 65 72 70  %s", test_interp
e020: 5f 65 72 72 6f 72 29 3b 0a 0a 09 09 72 65 74 75  _error);....retu
e030: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f  rn(1);..}...Tcl_
e040: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 74 65 73  DeleteInterp(tes
e050: 74 5f 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20  t_interp);...if 
e060: 28 61 70 70 66 73 5f 74 68 72 65 61 64 65 64 5f  (appfs_threaded_
e070: 74 63 6c 29 20 7b 0a 09 09 54 63 6c 5f 46 69 6e  tcl) {...Tcl_Fin
e080: 61 6c 69 7a 65 4e 6f 74 69 66 69 65 72 28 4e 55  alizeNotifier(NU
e090: 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  LL);..}...appfs_
e0a0: 73 65 74 5f 72 65 73 6f 75 72 63 65 5f 6c 69 6d  set_resource_lim
e0b0: 69 74 73 28 29 3b 0a 09 61 70 70 66 73 5f 73 65  its();..appfs_se
e0c0: 74 5f 73 69 67 68 61 6e 64 6c 65 72 28 29 3b 0a  t_sighandler();.
e0d0: 0a 09 2f 2a 0a 09 20 2a 20 45 6e 74 65 72 20 74  ../*.. * Enter t
e0e0: 68 65 20 46 55 53 45 20 6d 61 69 6e 20 6c 6f 6f  he FUSE main loo
e0f0: 70 20 2d 2d 20 74 68 69 73 20 77 69 6c 6c 20 70  p -- this will p
e100: 72 6f 63 65 73 73 20 61 6e 79 20 61 72 67 75 6d  rocess any argum
e110: 65 6e 74 73 0a 09 20 2a 20 61 6e 64 20 73 74 61  ents.. * and sta
e120: 72 74 20 73 65 72 76 69 63 69 6e 67 20 72 65 71  rt servicing req
e130: 75 65 73 74 73 2e 0a 09 20 2a 2f 0a 09 61 70 70  uests... */..app
e140: 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 20  fs_fuse_started 
e150: 3d 20 31 3b 0a 09 72 65 74 75 72 6e 28 66 75 73  = 1;..return(fus
e160: 65 5f 6d 61 69 6e 28 61 72 67 73 2e 61 72 67 63  e_main(args.argc
e170: 2c 20 61 72 67 73 2e 61 72 67 76 2c 20 26 61 70  , args.argv, &ap
e180: 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 2c 20  pfs_operations, 
e190: 4e 55 4c 4c 29 29 3b 0a 7d 0a                    NULL));.}.