Hex Artifact Content

Artifact 55077e4885496e8343fadd511e07652b72e42365:


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 72 65 73 6f  nclude <sys/reso
0490: 75 72 63 65 2e 68 3e 20 20 0a 23 69 6e 63 6c 75  urce.h>  .#inclu
04a0: 64 65 20 3c 73 79 73 2f 66 73 75 69 64 2e 68 3e  de <sys/fsuid.h>
04b0: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74  .#include <sys/t
04c0: 79 70 65 73 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  ypes.h>.#include
04d0: 20 3c 73 79 73 2f 74 69 6d 65 2e 68 3e 0a 23 69   <sys/time.h>.#i
04e0: 6e 63 6c 75 64 65 20 3c 70 74 68 72 65 61 64 2e  nclude <pthread.
04f0: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 69 67  h>.#include <sig
0500: 6e 61 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  nal.h>.#include 
0510: 3c 6c 69 6d 69 74 73 2e 68 3e 0a 23 69 6e 63 6c  <limits.h>.#incl
0520: 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23  ude <string.h>.#
0530: 69 6e 63 6c 75 64 65 20 3c 73 74 64 61 72 67 2e  include <stdarg.
0540: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64  h>.#include <std
0550: 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  lib.h>.#include 
0560: 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c  <unistd.h>.#incl
0570: 75 64 65 20 3c 65 72 72 6e 6f 2e 68 3e 0a 23 69  ude <errno.h>.#i
0580: 6e 63 6c 75 64 65 20 3c 66 63 6e 74 6c 2e 68 3e  nclude <fcntl.h>
0590: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f  .#include <stdio
05a0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 66 75  .h>.#include <fu
05b0: 73 65 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  se.h>.#include <
05c0: 70 77 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  pwd.h>.#include 
05d0: 3c 74 63 6c 2e 68 3e 0a 0a 2f 2a 0a 20 2a 20 44  <tcl.h>../*. * D
05e0: 65 66 61 75 6c 74 20 63 61 63 68 65 20 64 69 72  efault cache dir
05f0: 65 63 74 6f 72 79 0a 20 2a 2f 0a 23 69 66 6e 64  ectory. */.#ifnd
0600: 65 66 20 41 50 50 46 53 5f 43 41 43 48 45 44 49  ef APPFS_CACHEDI
0610: 52 0a 23 64 65 66 69 6e 65 20 41 50 50 46 53 5f  R.#define APPFS_
0620: 43 41 43 48 45 44 49 52 20 22 2f 76 61 72 2f 63  CACHEDIR "/var/c
0630: 61 63 68 65 2f 61 70 70 66 73 22 0a 23 65 6e 64  ache/appfs".#end
0640: 69 66 0a 0a 2f 2a 20 44 65 62 75 67 67 69 6e 67  if../* Debugging
0650: 20 6d 61 63 72 6f 73 20 2a 2f 0a 23 69 66 64 65   macros */.#ifde
0660: 66 20 44 45 42 55 47 0a 69 6e 74 20 61 70 70 66  f DEBUG.int appf
0670: 73 5f 64 65 62 75 67 5f 66 64 20 3d 20 53 54 44  s_debug_fd = STD
0680: 45 52 52 5f 46 49 4c 45 4e 4f 3b 0a 23 64 65 66  ERR_FILENO;.#def
0690: 69 6e 65 20 41 50 50 46 53 5f 44 45 42 55 47 28  ine APPFS_DEBUG(
06a0: 78 2e 2e 2e 29 20 7b 20 5c 0a 09 63 68 61 72 20  x...) { \..char 
06b0: 62 75 66 5b 38 31 39 32 5d 3b 20 5c 0a 09 69 6e  buf[8192]; \..in
06c0: 74 20 62 75 66 6f 66 66 20 3d 20 30 3b 20 5c 0a  t bufoff = 0; \.
06d0: 09 69 66 20 28 61 70 70 66 73 5f 64 65 62 75 67  .if (appfs_debug
06e0: 5f 66 64 20 3d 3d 20 2d 31 29 20 7b 20 5c 0a 09  _fd == -1) { \..
06f0: 09 61 70 70 66 73 5f 64 65 62 75 67 5f 66 64 20  .appfs_debug_fd 
0700: 3d 20 6f 70 65 6e 28 22 2f 74 6d 70 2f 61 70 70  = open("/tmp/app
0710: 66 73 64 2e 6c 6f 67 22 2c 20 4f 5f 57 52 4f 4e  fsd.log", O_WRON
0720: 4c 59 20 7c 20 4f 5f 41 50 50 45 4e 44 20 7c 20  LY | O_APPEND | 
0730: 4f 5f 43 52 45 41 54 2c 20 30 36 30 30 29 3b 20  O_CREAT, 0600); 
0740: 5c 0a 09 7d 3b 20 5c 0a 09 62 75 66 6f 66 66 20  \..}; \..bufoff 
0750: 3d 20 73 6e 70 72 69 6e 74 66 28 62 75 66 2c 20  = snprintf(buf, 
0760: 73 69 7a 65 6f 66 28 62 75 66 29 2c 20 22 5b 64  sizeof(buf), "[d
0770: 65 62 75 67 5d 20 5b 74 3d 25 6c 6c 78 5d 20 25  ebug] [t=%llx] %
0780: 73 3a 25 69 3a 25 73 3a 20 22 2c 20 28 75 6e 73  s:%i:%s: ", (uns
0790: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29  igned long long)
07a0: 20 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29 2c   pthread_self(),
07b0: 20 5f 5f 46 49 4c 45 5f 5f 2c 20 5f 5f 4c 49 4e   __FILE__, __LIN
07c0: 45 5f 5f 2c 20 5f 5f 66 75 6e 63 5f 5f 29 3b 20  E__, __func__); 
07d0: 5c 0a 09 69 66 20 28 62 75 66 6f 66 66 20 3c 20  \..if (bufoff < 
07e0: 73 69 7a 65 6f 66 28 62 75 66 29 29 20 7b 20 5c  sizeof(buf)) { \
07f0: 0a 09 09 62 75 66 6f 66 66 20 2b 3d 20 73 6e 70  ...bufoff += snp
0800: 72 69 6e 74 66 28 62 75 66 20 2b 20 62 75 66 6f  rintf(buf + bufo
0810: 66 66 2c 20 73 69 7a 65 6f 66 28 62 75 66 29 20  ff, sizeof(buf) 
0820: 2d 20 62 75 66 6f 66 66 2c 20 78 29 3b 20 5c 0a  - bufoff, x); \.
0830: 09 7d 3b 20 5c 0a 09 69 66 20 28 62 75 66 6f 66  .}; \..if (bufof
0840: 66 20 3c 20 73 69 7a 65 6f 66 28 62 75 66 29 29  f < sizeof(buf))
0850: 20 7b 20 5c 0a 09 09 62 75 66 6f 66 66 20 2b 3d   { \...bufoff +=
0860: 20 73 6e 70 72 69 6e 74 66 28 62 75 66 20 2b 20   snprintf(buf + 
0870: 62 75 66 6f 66 66 2c 20 73 69 7a 65 6f 66 28 62  bufoff, sizeof(b
0880: 75 66 29 20 2d 20 62 75 66 6f 66 66 2c 20 22 5c  uf) - bufoff, "\
0890: 6e 22 29 3b 5c 0a 09 7d 20 5c 0a 09 69 66 20 28  n");\..} \..if (
08a0: 62 75 66 6f 66 66 20 3e 20 73 69 7a 65 6f 66 28  bufoff > sizeof(
08b0: 62 75 66 29 29 20 7b 20 5c 0a 09 09 62 75 66 6f  buf)) { \...bufo
08c0: 66 66 20 3d 20 73 69 7a 65 6f 66 28 62 75 66 29  ff = sizeof(buf)
08d0: 3b 20 5c 0a 09 7d 3b 20 5c 0a 09 77 72 69 74 65  ; \..}; \..write
08e0: 28 61 70 70 66 73 5f 64 65 62 75 67 5f 66 64 2c  (appfs_debug_fd,
08f0: 20 62 75 66 2c 20 62 75 66 6f 66 66 29 3b 20 5c   buf, bufoff); \
0900: 0a 7d 0a 23 65 6c 73 65 0a 23 64 65 66 69 6e 65  .}.#else.#define
0910: 20 41 50 50 46 53 5f 44 45 42 55 47 28 78 2e 2e   APPFS_DEBUG(x..
0920: 2e 29 20 2f 2a 2a 2f 0a 23 65 6e 64 69 66 0a 0a  .) /**/.#endif..
0930: 2f 2a 0a 20 2a 20 53 48 41 31 20 54 63 6c 20 50  /*. * SHA1 Tcl P
0940: 61 63 6b 61 67 65 20 69 6e 69 74 69 61 6c 69 7a  ackage initializ
0950: 65 72 2c 20 66 72 6f 6d 20 73 68 61 31 2e 6f 0a  er, from sha1.o.
0960: 20 2a 2f 0a 69 6e 74 20 53 68 61 31 5f 49 6e 69   */.int Sha1_Ini
0970: 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  t(Tcl_Interp *in
0980: 74 65 72 70 29 3b 0a 0a 2f 2a 0a 20 2a 20 54 68  terp);../*. * Th
0990: 72 65 61 64 20 53 70 65 63 69 66 69 63 20 44 61  read Specific Da
09a0: 74 61 20 28 54 53 44 29 20 66 6f 72 20 54 63 6c  ta (TSD) for Tcl
09b0: 20 49 6e 74 65 72 70 72 65 74 65 72 20 66 6f 72   Interpreter for
09c0: 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 68 72   the current thr
09d0: 65 61 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 70  ead. */.static p
09e0: 74 68 72 65 61 64 5f 6b 65 79 5f 74 20 69 6e 74  thread_key_t int
09f0: 65 72 70 4b 65 79 3b 0a 0a 2f 2a 0a 20 2a 20 47  erpKey;../*. * G
0a00: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 2c  lobal variables,
0a10: 20 6e 65 65 64 65 64 20 66 6f 72 20 61 6c 6c 20   needed for all 
0a20: 74 68 72 65 61 64 73 20 62 75 74 20 6f 6e 6c 79  threads but only
0a30: 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 62 65 66   initialized bef
0a40: 6f 72 65 20 61 6e 79 0a 20 2a 20 46 55 53 45 20  ore any. * FUSE 
0a50: 74 68 72 65 61 64 73 20 61 72 65 20 63 72 65 61  threads are crea
0a60: 74 65 64 0a 20 2a 2f 0a 63 6f 6e 73 74 20 63 68  ted. */.const ch
0a70: 61 72 20 2a 61 70 70 66 73 5f 63 61 63 68 65 64  ar *appfs_cached
0a80: 69 72 3b 0a 74 69 6d 65 5f 74 20 61 70 70 66 73  ir;.time_t appfs
0a90: 5f 62 6f 6f 74 74 69 6d 65 3b 0a 69 6e 74 20 61  _boottime;.int a
0aa0: 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65  ppfs_fuse_starte
0ab0: 64 20 3d 20 30 3b 0a 69 6e 74 20 61 70 70 66 73  d = 0;.int appfs
0ac0: 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 3b 0a 0a  _threaded_tcl;..
0ad0: 2f 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20 76 61 72  /*. * Global var
0ae0: 69 61 62 6c 65 73 20 66 6f 72 20 41 70 70 46 53  iables for AppFS
0af0: 20 63 61 63 68 69 6e 67 0a 20 2a 2f 0a 70 74 68   caching. */.pth
0b00: 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 61 70 70  read_mutex_t app
0b10: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
0b20: 68 65 5f 6d 75 74 65 78 20 3d 20 50 54 48 52 45  he_mutex = PTHRE
0b30: 41 44 5f 4d 55 54 45 58 5f 49 4e 49 54 49 41 4c  AD_MUTEX_INITIAL
0b40: 49 5a 45 52 3b 0a 69 6e 74 20 61 70 70 66 73 5f  IZER;.int appfs_
0b50: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
0b60: 73 69 7a 65 20 3d 20 38 32 30 39 3b 0a 73 74 72  size = 8209;.str
0b70: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e  uct appfs_pathin
0b80: 66 6f 20 2a 61 70 70 66 73 5f 70 61 74 68 5f 69  fo *appfs_path_i
0b90: 6e 66 6f 5f 63 61 63 68 65 20 3d 20 4e 55 4c 4c  nfo_cache = NULL
0ba0: 3b 0a 0a 23 69 66 6e 64 65 66 20 54 43 4c 5f 54  ;..#ifndef TCL_T
0bb0: 48 52 45 41 44 53 0a 2f 2a 0a 20 2a 20 48 61 6e  HREADS./*. * Han
0bc0: 64 6c 65 20 75 6e 74 68 72 65 61 64 65 64 20 54  dle unthreaded T
0bd0: 63 6c 0a 20 2a 2f 0a 70 74 68 72 65 61 64 5f 6d  cl. */.pthread_m
0be0: 75 74 65 78 5f 74 20 61 70 70 66 73 5f 74 63 6c  utex_t appfs_tcl
0bf0: 5f 62 69 67 5f 67 6c 6f 62 61 6c 5f 6c 6f 63 6b  _big_global_lock
0c00: 20 3d 20 50 54 48 52 45 41 44 5f 4d 55 54 45 58   = PTHREAD_MUTEX
0c10: 5f 49 4e 49 54 49 41 4c 49 5a 45 52 3b 0a 23 64  _INITIALIZER;.#d
0c20: 65 66 69 6e 65 20 61 70 70 66 73 5f 63 61 6c 6c  efine appfs_call
0c30: 5f 6c 69 62 74 63 6c 5f 65 6e 74 65 72 20 70 74  _libtcl_enter pt
0c40: 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b  hread_mutex_lock
0c50: 28 26 61 70 70 66 73 5f 74 63 6c 5f 62 69 67 5f  (&appfs_tcl_big_
0c60: 67 6c 6f 62 61 6c 5f 6c 6f 63 6b 29 3b 0a 23 64  global_lock);.#d
0c70: 65 66 69 6e 65 20 61 70 70 66 73 5f 63 61 6c 6c  efine appfs_call
0c80: 5f 6c 69 62 74 63 6c 5f 65 78 69 74 20 70 74 68  _libtcl_exit pth
0c90: 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63  read_mutex_unloc
0ca0: 6b 28 26 61 70 70 66 73 5f 74 63 6c 5f 62 69 67  k(&appfs_tcl_big
0cb0: 5f 67 6c 6f 62 61 6c 5f 6c 6f 63 6b 29 3b 0a 23  _global_lock);.#
0cc0: 65 6c 73 65 0a 23 64 65 66 69 6e 65 20 61 70 70  else.#define app
0cd0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65  fs_call_libtcl_e
0ce0: 6e 74 65 72 20 2f 2a 2a 2f 0a 23 64 65 66 69 6e  nter /**/.#defin
0cf0: 65 20 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  e appfs_call_lib
0d00: 74 63 6c 5f 65 78 69 74 20 2f 2a 2a 2f 0a 23 65  tcl_exit /**/.#e
0d10: 6e 64 69 66 0a 23 64 65 66 69 6e 65 20 61 70 70  ndif.#define app
0d20: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 78  fs_call_libtcl(x
0d30: 2e 2e 2e 29 20 61 70 70 66 73 5f 63 61 6c 6c 5f  ...) appfs_call_
0d40: 6c 69 62 74 63 6c 5f 65 6e 74 65 72 20 78 20 61  libtcl_enter x a
0d50: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
0d60: 5f 65 78 69 74 0a 0a 2f 2a 0a 20 2a 20 47 6c 6f  _exit../*. * Glo
0d70: 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20 66 6f  bal variables fo
0d80: 72 20 41 70 70 46 53 20 54 63 6c 20 49 6e 74 65  r AppFS Tcl Inte
0d90: 72 70 72 65 74 65 72 20 72 65 73 74 61 72 74 69  rpreter restarti
0da0: 6e 67 0a 20 2a 2f 0a 69 6e 74 20 69 6e 74 65 72  ng. */.int inter
0db0: 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 30 3b  p_reset_key = 0;
0dc0: 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 20 50 61  ../*. * AppFS Pa
0dd0: 74 68 20 54 79 70 65 3a 20 20 44 65 73 63 72 69  th Type:  Descri
0de0: 62 65 73 20 74 68 65 20 74 79 70 65 20 6f 66 20  bes the type of 
0df0: 70 61 74 68 20 61 20 67 69 76 65 6e 20 66 69 6c  path a given fil
0e00: 65 20 69 73 0a 20 2a 2f 0a 74 79 70 65 64 65 66  e is. */.typedef
0e10: 20 65 6e 75 6d 20 7b 0a 09 41 50 50 46 53 5f 50   enum {..APPFS_P
0e20: 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 2c  ATHTYPE_INVALID,
0e30: 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  ..APPFS_PATHTYPE
0e40: 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 2c  _DOES_NOT_EXIST,
0e50: 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  ..APPFS_PATHTYPE
0e60: 5f 46 49 4c 45 2c 0a 09 41 50 50 46 53 5f 50 41  _FILE,..APPFS_PA
0e70: 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59  THTYPE_DIRECTORY
0e80: 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50  ,..APPFS_PATHTYP
0e90: 45 5f 53 59 4d 4c 49 4e 4b 2c 0a 09 41 50 50 46  E_SYMLINK,..APPF
0ea0: 53 5f 50 41 54 48 54 59 50 45 5f 53 4f 43 4b 45  S_PATHTYPE_SOCKE
0eb0: 54 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59  T,..APPFS_PATHTY
0ec0: 50 45 5f 46 49 46 4f 2c 0a 7d 20 61 70 70 66 73  PE_FIFO,.} appfs
0ed0: 5f 70 61 74 68 74 79 70 65 5f 74 3b 0a 0a 2f 2a  _pathtype_t;../*
0ee0: 0a 20 2a 20 41 70 70 46 53 20 50 61 74 68 20 49  . * AppFS Path I
0ef0: 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 20 2a 20 20  nformation:. *  
0f00: 20 20 20 20 20 20 20 43 6f 6d 70 6c 65 74 65 6c         Completel
0f10: 79 20 64 65 73 63 72 69 62 65 73 20 61 20 73 70  y describes a sp
0f20: 65 63 69 66 69 63 20 70 61 74 68 2c 20 68 6f 77  ecific path, how
0f30: 20 69 74 20 73 68 6f 75 6c 64 20 62 65 20 72 65   it should be re
0f40: 74 75 72 6e 65 64 20 74 6f 0a 20 2a 20 20 20 20  turned to. *    
0f50: 20 20 20 20 20 74 6f 20 74 68 65 20 6b 65 72 6e       to the kern
0f60: 65 6c 0a 20 2a 2f 0a 73 74 72 75 63 74 20 61 70  el. */.struct ap
0f70: 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 7b 0a 09  pfs_pathinfo {..
0f80: 61 70 70 66 73 5f 70 61 74 68 74 79 70 65 5f 74  appfs_pathtype_t
0f90: 20 74 79 70 65 3b 0a 09 74 69 6d 65 5f 74 20 74   type;..time_t t
0fa0: 69 6d 65 3b 0a 09 63 68 61 72 20 68 6f 73 74 6e  ime;..char hostn
0fb0: 61 6d 65 5b 32 35 36 5d 3b 0a 09 69 6e 74 20 70  ame[256];..int p
0fc0: 61 63 6b 61 67 65 64 3b 0a 09 75 6e 73 69 67 6e  ackaged;..unsign
0fd0: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 20 69 6e 6f  ed long long ino
0fe0: 64 65 3b 0a 09 75 6e 69 6f 6e 20 7b 0a 09 09 73  de;..union {...s
0ff0: 74 72 75 63 74 20 7b 0a 09 09 09 69 6e 74 20 63  truct {....int c
1000: 68 69 6c 64 63 6f 75 6e 74 3b 0a 09 09 7d 20 64  hildcount;...} d
1010: 69 72 3b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09  ir;...struct {..
1020: 09 09 69 6e 74 20 65 78 65 63 75 74 61 62 6c 65  ..int executable
1030: 3b 0a 09 09 09 69 6e 74 20 73 75 69 64 52 6f 6f  ;....int suidRoo
1040: 74 3b 0a 09 09 09 69 6e 74 20 77 6f 72 6c 64 61  t;....int worlda
1050: 63 63 65 73 73 69 62 6c 65 3b 0a 09 09 09 6f 66  ccessible;....of
1060: 66 5f 74 20 73 69 7a 65 3b 0a 09 09 7d 20 66 69  f_t size;...} fi
1070: 6c 65 3b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09  le;...struct {..
1080: 09 09 6f 66 66 5f 74 20 73 69 7a 65 3b 0a 09 09  ..off_t size;...
1090: 09 63 68 61 72 20 73 6f 75 72 63 65 5b 32 35 36  .char source[256
10a0: 5d 3b 0a 09 09 7d 20 73 79 6d 6c 69 6e 6b 3b 0a  ];...} symlink;.
10b0: 09 7d 20 74 79 70 65 69 6e 66 6f 3b 0a 0a 09 2f  .} typeinfo;.../
10c0: 2a 20 41 74 74 72 69 62 75 74 65 73 20 75 73 65  * Attributes use
10d0: 64 20 6f 6e 6c 79 20 66 6f 72 20 63 61 63 68 69  d only for cachi
10e0: 6e 67 20 65 6e 74 72 69 65 73 20 2a 2f 0a 09 63  ng entries */..c
10f0: 68 61 72 20 2a 5f 63 61 63 68 65 5f 70 61 74 68  har *_cache_path
1100: 3b 0a 09 75 69 64 5f 74 20 5f 63 61 63 68 65 5f  ;..uid_t _cache_
1110: 75 69 64 3b 0a 7d 3b 0a 0a 2f 2a 0a 20 2a 20 43  uid;.};../*. * C
1120: 72 65 61 74 65 20 61 20 6e 65 77 20 54 63 6c 20  reate a new Tcl 
1130: 69 6e 74 65 72 70 72 65 74 65 72 20 61 6e 64 20  interpreter and 
1140: 63 6f 6d 70 6c 65 74 65 6c 79 20 69 6e 69 74 69  completely initi
1150: 61 6c 69 7a 65 20 69 74 0a 20 2a 2f 0a 73 74 61  alize it. */.sta
1160: 74 69 63 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  tic Tcl_Interp *
1170: 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c  appfs_create_Tcl
1180: 49 6e 74 65 72 70 28 63 68 61 72 20 2a 2a 65 72  Interp(char **er
1190: 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 54  ror_string) {..T
11a0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
11b0: 70 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b  p;..int tcl_ret;
11c0: 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63  ..const char *tc
11d0: 6c 5f 73 65 74 76 61 72 5f 72 65 74 3b 0a 0a 09  l_setvar_ret;...
11e0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 72 65  APPFS_DEBUG("Cre
11f0: 61 74 69 6e 67 20 6e 65 77 20 54 63 6c 20 69 6e  ating new Tcl in
1200: 74 65 72 70 72 65 74 65 72 20 66 6f 72 20 54 49  terpreter for TI
1210: 44 20 3d 20 30 78 25 6c 6c 78 22 2c 20 28 75 6e  D = 0x%llx", (un
1220: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
1230: 29 20 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29  ) pthread_self()
1240: 29 3b 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  );...appfs_call_
1250: 6c 69 62 74 63 6c 28 0a 09 09 69 6e 74 65 72 70  libtcl(...interp
1260: 20 3d 20 54 63 6c 5f 43 72 65 61 74 65 49 6e 74   = Tcl_CreateInt
1270: 65 72 70 28 29 3b 0a 09 29 0a 09 69 66 20 28 69  erp();..)..if (i
1280: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
1290: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
12a0: 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 72  r, "Unable to cr
12b0: 65 61 74 65 20 54 63 6c 20 49 6e 74 65 72 70 72  eate Tcl Interpr
12c0: 65 74 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e  eter.  Aborting.
12d0: 5c 6e 22 29 3b 0a 0a 09 09 69 66 20 28 65 72 72  \n");....if (err
12e0: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09  or_string) {....
12f0: 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20  *error_string = 
1300: 73 74 72 64 75 70 28 22 55 6e 61 62 6c 65 20 74  strdup("Unable t
1310: 6f 20 63 72 65 61 74 65 20 54 63 6c 20 69 6e 74  o create Tcl int
1320: 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 09 09 7d  erpreter.");...}
1330: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
1340: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
1350: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65  l_libtcl(Tcl_Pre
1360: 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a  serve(interp);).
1370: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1380: 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d  tcl(...tcl_ret =
1390: 20 54 63 6c 5f 49 6e 69 74 28 69 6e 74 65 72 70   Tcl_Init(interp
13a0: 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72  );..)..if (tcl_r
13b0: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
13c0: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
13d0: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69  , "Unable to ini
13e0: 74 69 61 6c 69 7a 65 20 54 63 6c 2e 20 20 41 62  tialize Tcl.  Ab
13f0: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61  orting.\n");...a
1400: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1410: 28 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64  (....fprintf(std
1420: 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20  err, "Tcl Error 
1430: 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47  is: %s\n", Tcl_G
1440: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
1450: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
1460: 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67  if (error_string
1470: 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c  ) {....appfs_cal
1480: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65  l_libtcl(.....*e
1490: 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74  rror_string = st
14a0: 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69  rdup(Tcl_GetStri
14b0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
14c0: 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61  );....)...}....a
14d0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
14e0: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
14f0: 65 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f  erp);)....APPFS_
1500: 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69  DEBUG("Terminati
1510: 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  ng Tcl interpret
1520: 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f  er.");....appfs_
1530: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
1540: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
1550: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e  erp);)....return
1560: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70  (NULL);..}...app
1570: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
1580: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
1590: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 70 61  Eval(interp, "pa
15a0: 63 6b 61 67 65 20 69 66 6e 65 65 64 65 64 20 73  ckage ifneeded s
15b0: 68 61 31 20 31 2e 30 20 5b 6c 69 73 74 20 6c 6f  ha1 1.0 [list lo
15c0: 61 64 20 7b 7d 20 73 68 61 31 5d 22 29 3b 0a 09  ad {} sha1]");..
15d0: 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  )..if (tcl_ret !
15e0: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70  = TCL_OK) {...fp
15f0: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55  rintf(stderr, "U
1600: 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c  nable to initial
1610: 69 7a 65 20 54 63 6c 20 53 48 41 31 2e 20 20 41  ize Tcl SHA1.  A
1620: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09  borting.\n");...
1630: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
1640: 6c 28 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74  l(....fprintf(st
1650: 64 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72  derr, "Tcl Error
1660: 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f   is: %s\n", Tcl_
1670: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
1680: 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09  interp));...)...
1690: 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e  .if (error_strin
16a0: 67 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61  g) {....appfs_ca
16b0: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a  ll_libtcl(.....*
16c0: 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73  error_string = s
16d0: 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72  trdup(Tcl_GetStr
16e0: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
16f0: 29 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09  ));....)...}....
1700: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
1710: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
1720: 74 65 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53  terp);)....APPFS
1730: 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74  _DEBUG("Terminat
1740: 69 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65  ing Tcl interpre
1750: 74 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73  ter.");....appfs
1760: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
1770: 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e  _DeleteInterp(in
1780: 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72  terp);)....retur
1790: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70  n(NULL);..}...ap
17a0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
17b0: 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
17c0: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 70  _Eval(interp, "p
17d0: 61 63 6b 61 67 65 20 69 66 6e 65 65 64 65 64 20  ackage ifneeded 
17e0: 61 70 70 66 73 64 20 31 2e 30 20 5b 6c 69 73 74  appfsd 1.0 [list
17f0: 20 6c 6f 61 64 20 7b 7d 20 61 70 70 66 73 64 5d   load {} appfsd]
1800: 22 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f  ");..)..if (tcl_
1810: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
1820: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
1830: 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e  r, "Unable to in
1840: 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 41 70 70  itialize Tcl App
1850: 46 53 20 50 61 63 6b 61 67 65 2e 20 20 41 62 6f  FS Package.  Abo
1860: 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70  rting.\n");...ap
1870: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
1880: 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ....fprintf(stde
1890: 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69  rr, "Tcl Error i
18a0: 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65  s: %s\n", Tcl_Ge
18b0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
18c0: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69  terp));...)....i
18d0: 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29  f (error_string)
18e0: 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c   {....appfs_call
18f0: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72  _libtcl(.....*er
1900: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
1910: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
1920: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
1930: 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70  ;....)...}....ap
1940: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
1950: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
1960: 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44  rp);)....APPFS_D
1970: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
1980: 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  g Tcl interprete
1990: 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63  r.");....appfs_c
19a0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44  all_libtcl(Tcl_D
19b0: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65  eleteInterp(inte
19c0: 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28  rp);)....return(
19d0: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  NULL);..}.../*..
19e0: 20 2a 20 4c 6f 61 64 20 22 70 6b 69 2e 74 63 6c   * Load "pki.tcl
19f0: 22 20 69 6e 20 74 68 65 20 73 61 6d 65 20 77 61  " in the same wa
1a00: 79 20 61 73 20 61 70 70 66 73 64 2e 74 63 6c 20  y as appfsd.tcl 
1a10: 28 73 65 65 20 62 65 6c 6f 77 29 0a 09 20 2a 2f  (see below).. */
1a20: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1a30: 74 63 6c 5f 65 6e 74 65 72 0a 09 09 74 63 6c 5f  tcl_enter...tcl_
1a40: 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69  ret = Tcl_Eval(i
1a50: 6e 74 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75  nterp, "".#inclu
1a60: 64 65 20 22 70 6b 69 2e 74 63 6c 2e 68 22 0a 09  de "pki.tcl.h"..
1a70: 09 22 22 29 3b 0a 09 61 70 70 66 73 5f 63 61 6c  ."");..appfs_cal
1a80: 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74 0a 09 69  l_libtcl_exit..i
1a90: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
1aa0: 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74  L_OK) {...fprint
1ab0: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
1ac0: 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20  e to initialize 
1ad0: 54 63 6c 20 50 4b 49 2e 20 20 41 62 6f 72 74 69  Tcl PKI.  Aborti
1ae0: 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 70 66 73  ng.\n");...appfs
1af0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
1b00: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
1b10: 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20   "Tcl Error is: 
1b20: 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74  %s\n", Tcl_GetSt
1b30: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
1b40: 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69 66 20 28  p));...)....if (
1b50: 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a  error_string) {.
1b60: 09 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
1b70: 62 74 63 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72  btcl(.....*error
1b80: 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70  _string = strdup
1b90: 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65  (Tcl_GetStringRe
1ba0: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09  sult(interp));..
1bb0: 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73  ..)...}....appfs
1bc0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
1bd0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
1be0: 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ;)....APPFS_DEBU
1bf0: 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 54  G("Terminating T
1c00: 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22  cl interpreter."
1c10: 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  );....appfs_call
1c20: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65  _libtcl(Tcl_Dele
1c30: 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29  teInterp(interp)
1c40: 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  ;)....return(NUL
1c50: 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20  L);..}.../*.. * 
1c60: 4c 6f 61 64 20 74 68 65 20 22 61 70 70 66 73 64  Load the "appfsd
1c70: 2e 74 63 6c 22 20 73 63 72 69 70 74 2c 20 77 68  .tcl" script, wh
1c80: 69 63 68 20 69 73 20 22 63 6f 6d 70 69 6c 65 64  ich is "compiled
1c90: 22 20 69 6e 74 6f 20 61 20 43 20 68 65 61 64 65  " into a C heade
1ca0: 72 0a 09 20 2a 20 73 6f 20 74 68 61 74 20 69 74  r.. * so that it
1cb0: 20 64 6f 65 73 20 6e 6f 74 20 6e 65 65 64 20 74   does not need t
1cc0: 6f 20 65 78 69 73 74 20 6f 6e 20 74 68 65 20 66  o exist on the f
1cd0: 69 6c 65 73 79 73 74 65 6d 20 61 6e 64 20 63 61  ilesystem and ca
1ce0: 6e 20 62 65 0a 09 20 2a 20 64 69 72 65 63 74 6c  n be.. * directl
1cf0: 79 20 65 76 61 6c 75 61 74 65 64 2e 0a 09 20 2a  y evaluated... *
1d00: 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  /..appfs_call_li
1d10: 62 74 63 6c 5f 65 6e 74 65 72 0a 09 09 74 63 6c  btcl_enter...tcl
1d20: 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28  _ret = Tcl_Eval(
1d30: 69 6e 74 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c  interp, "".#incl
1d40: 75 64 65 20 22 61 70 70 66 73 64 2e 74 63 6c 2e  ude "appfsd.tcl.
1d50: 68 22 0a 09 09 22 22 29 3b 0a 09 61 70 70 66 73  h"..."");..appfs
1d60: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69  _call_libtcl_exi
1d70: 74 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  t..if (tcl_ret !
1d80: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70  = TCL_OK) {...fp
1d90: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55  rintf(stderr, "U
1da0: 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c  nable to initial
1db0: 69 7a 65 20 54 63 6c 20 41 70 70 46 53 20 73 63  ize Tcl AppFS sc
1dc0: 72 69 70 74 2e 20 20 41 62 6f 72 74 69 6e 67 2e  ript.  Aborting.
1dd0: 5c 6e 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61  \n");...appfs_ca
1de0: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 66 70  ll_libtcl(....fp
1df0: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54  rintf(stderr, "T
1e00: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c  cl Error is: %s\
1e10: 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  n", Tcl_GetStrin
1e20: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
1e30: 3b 0a 09 09 29 0a 0a 09 09 69 66 20 28 65 72 72  ;...)....if (err
1e40: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09  or_string) {....
1e50: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
1e60: 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74  l(.....*error_st
1e70: 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63  ring = strdup(Tc
1e80: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
1e90: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29  t(interp));....)
1ea0: 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61  ...}....appfs_ca
1eb0: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
1ec0: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
1ed0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
1ee0: 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20  Terminating Tcl 
1ef0: 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a  interpreter.");.
1f00: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
1f10: 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49  btcl(Tcl_DeleteI
1f20: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a  nterp(interp);).
1f30: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
1f40: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65 74  ..}.../*.. * Set
1f50: 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65   global variable
1f60: 73 20 66 72 6f 6d 20 43 20 74 6f 20 54 63 6c 0a  s from C to Tcl.
1f70: 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c  . */..appfs_call
1f80: 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 73  _libtcl(...tcl_s
1f90: 65 74 76 61 72 5f 72 65 74 20 3d 20 54 63 6c 5f  etvar_ret = Tcl_
1fa0: 53 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22  SetVar(interp, "
1fb0: 3a 3a 61 70 70 66 73 3a 3a 63 61 63 68 65 64 69  ::appfs::cachedi
1fc0: 72 22 2c 20 61 70 70 66 73 5f 63 61 63 68 65 64  r", appfs_cached
1fd0: 69 72 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f  ir, TCL_GLOBAL_O
1fe0: 4e 4c 59 29 3b 0a 09 29 0a 09 69 66 20 28 74 63  NLY);..)..if (tc
1ff0: 6c 5f 73 65 74 76 61 72 5f 72 65 74 20 3d 3d 20  l_setvar_ret == 
2000: 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74  NULL) {...fprint
2010: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
2020: 65 20 74 6f 20 73 65 74 20 63 61 63 68 65 20 64  e to set cache d
2030: 69 72 65 63 74 6f 72 79 2e 20 20 54 68 69 73 20  irectory.  This 
2040: 73 68 6f 75 6c 64 20 6e 65 76 65 72 20 66 61 69  should never fai
2050: 6c 2e 5c 6e 22 29 3b 0a 0a 09 09 69 66 20 28 65  l.\n");....if (e
2060: 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09  rror_string) {..
2070: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
2080: 74 63 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f  tcl(.....*error_
2090: 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28  string = strdup(
20a0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
20b0: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
20c0: 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f  .)...}....appfs_
20d0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
20e0: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
20f0: 29 0a 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47  )....APPFS_DEBUG
2100: 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63  ("Terminating Tc
2110: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29  l interpreter.")
2120: 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  ;....appfs_call_
2130: 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74  libtcl(Tcl_Delet
2140: 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b  eInterp(interp);
2150: 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c  )....return(NULL
2160: 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 49  );..}.../*.. * I
2170: 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 22 61  nitialize the "a
2180: 70 70 66 73 64 2e 74 63 6c 22 20 65 6e 76 69 72  ppfsd.tcl" envir
2190: 6f 6e 6d 65 6e 74 2c 20 77 68 69 63 68 20 6d 75  onment, which mu
21a0: 73 74 20 62 65 20 64 6f 6e 65 20 61 66 74 65 72  st be done after
21b0: 0a 09 20 2a 20 67 6c 6f 62 61 6c 20 76 61 72 69  .. * global vari
21c0: 61 62 6c 65 73 20 61 72 65 20 73 65 74 2e 0a 09  ables are set...
21d0: 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f   */..appfs_call_
21e0: 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65  libtcl(...tcl_re
21f0: 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74  t = Tcl_Eval(int
2200: 65 72 70 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 69  erp, "::appfs::i
2210: 6e 69 74 22 29 3b 0a 09 29 0a 09 69 66 20 28 74  nit");..)..if (t
2220: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
2230: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
2240: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f  derr, "Unable to
2250: 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20   initialize Tcl 
2260: 41 70 70 46 53 20 73 63 72 69 70 74 20 28 3a 3a  AppFS script (::
2270: 61 70 70 66 73 3a 3a 69 6e 69 74 29 2e 20 20 41  appfs::init).  A
2280: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09  borting.\n");...
2290: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
22a0: 6c 28 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74  l(....fprintf(st
22b0: 64 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72  derr, "Tcl Error
22c0: 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f   is: %s\n", Tcl_
22d0: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
22e0: 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09  interp));...)...
22f0: 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e  .if (error_strin
2300: 67 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61  g) {....appfs_ca
2310: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a  ll_libtcl(.....*
2320: 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73  error_string = s
2330: 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72  trdup(Tcl_GetStr
2340: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
2350: 29 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09  ));....)...}....
2360: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
2370: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
2380: 74 65 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53  terp);)....APPFS
2390: 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74  _DEBUG("Terminat
23a0: 69 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65  ing Tcl interpre
23b0: 74 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73  ter.");....appfs
23c0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
23d0: 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e  _DeleteInterp(in
23e0: 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72  terp);)....retur
23f0: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a  n(NULL);..}.../*
2400: 0a 09 20 2a 20 48 69 64 65 20 73 6f 6d 65 20 54  .. * Hide some T
2410: 63 6c 20 63 6f 6d 6d 61 6e 64 73 20 74 68 61 74  cl commands that
2420: 20 77 65 20 64 6f 20 6e 6f 74 20 63 61 72 65 20   we do not care 
2430: 74 6f 20 75 73 65 20 61 6e 64 20 77 68 69 63 68  to use and which
2440: 20 6d 61 79 0a 09 20 2a 20 73 6c 6f 77 20 64 6f   may.. * slow do
2450: 77 6e 20 72 75 6e 2d 74 69 6d 65 20 6f 70 65 72  wn run-time oper
2460: 61 74 69 6f 6e 73 2e 0a 09 20 2a 2f 0a 09 61 70  ations... */..ap
2470: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
2480: 0a 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61  ...Tcl_HideComma
2490: 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 75 74 6f  nd(interp, "auto
24a0: 5f 6c 6f 61 64 5f 69 6e 64 65 78 22 2c 20 22 61  _load_index", "a
24b0: 75 74 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22 29  uto_load_index")
24c0: 3b 0a 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d  ;...Tcl_HideComm
24d0: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 75 6e 6b  and(interp, "unk
24e0: 6e 6f 77 6e 22 2c 20 22 75 6e 6b 6e 6f 77 6e 22  nown", "unknown"
24f0: 29 3b 0a 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d  );...Tcl_HideCom
2500: 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 65 78  mand(interp, "ex
2510: 69 74 22 2c 20 22 65 78 69 74 22 29 3b 0a 09 29  it", "exit");..)
2520: 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 6c 65 61 73  .../*.. * Releas
2530: 65 20 74 68 65 20 68 6f 6c 64 20 77 65 20 68 61  e the hold we ha
2540: 76 65 20 6f 6e 20 74 68 65 20 69 6e 74 65 72 70  ve on the interp
2550: 72 65 74 65 72 20 73 6f 20 74 68 61 74 20 69 74  reter so that it
2560: 20 6d 61 79 20 62 65 0a 09 20 2a 20 64 65 6c 65   may be.. * dele
2570: 74 65 64 20 69 66 20 6e 65 65 64 65 64 0a 09 20  ted if needed.. 
2580: 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  */..appfs_call_l
2590: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
25a0: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 2f 2a  e(interp);).../*
25b0: 0a 09 20 2a 20 52 65 74 75 72 6e 20 74 68 65 20  .. * Return the 
25c0: 63 6f 6d 70 6c 65 74 65 6c 79 20 69 6e 69 74 69  completely initi
25d0: 61 6c 69 7a 65 64 20 69 6e 74 65 72 70 72 65 74  alized interpret
25e0: 65 72 0a 09 20 2a 2f 0a 09 72 65 74 75 72 6e 28  er.. */..return(
25f0: 69 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20  interp);.}../*. 
2600: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 74 68 72  * Return the thr
2610: 65 61 64 2d 73 70 65 63 69 66 69 63 20 54 63 6c  ead-specific Tcl
2620: 20 69 6e 74 65 72 70 72 65 74 65 72 2c 20 63 72   interpreter, cr
2630: 65 61 74 69 6e 67 20 69 74 20 69 66 20 6e 65 65  eating it if nee
2640: 64 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 54  ded. */.static T
2650: 63 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70 66 73  cl_Interp *appfs
2660: 5f 54 63 6c 49 6e 74 65 72 70 28 76 6f 69 64 29  _TclInterp(void)
2670: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
2680: 69 6e 74 65 72 70 3b 0a 09 69 6e 74 20 70 74 68  interp;..int pth
2690: 72 65 61 64 5f 72 65 74 3b 0a 09 73 74 61 74 69  read_ret;..stati
26a0: 63 20 5f 5f 74 68 72 65 61 64 20 69 6e 74 20 74  c __thread int t
26b0: 68 72 65 61 64 5f 69 6e 74 65 72 70 5f 72 65 73  hread_interp_res
26c0: 65 74 5f 6b 65 79 20 3d 20 30 3b 0a 09 69 6e 74  et_key = 0;..int
26d0: 20 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72   global_interp_r
26e0: 65 73 65 74 5f 6b 65 79 3b 0a 0a 09 67 6c 6f 62  eset_key;...glob
26f0: 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  al_interp_reset_
2700: 6b 65 79 20 3d 20 5f 5f 73 79 6e 63 5f 66 65 74  key = __sync_fet
2710: 63 68 5f 61 6e 64 5f 61 64 64 28 26 69 6e 74 65  ch_and_add(&inte
2720: 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 30 29  rp_reset_key, 0)
2730: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 70 74 68  ;...interp = pth
2740: 72 65 61 64 5f 67 65 74 73 70 65 63 69 66 69 63  read_getspecific
2750: 28 69 6e 74 65 72 70 4b 65 79 29 3b 0a 09 69 66  (interpKey);..if
2760: 20 28 69 6e 74 65 72 70 20 21 3d 20 4e 55 4c 4c   (interp != NULL
2770: 20 26 26 20 74 68 72 65 61 64 5f 69 6e 74 65 72   && thread_inter
2780: 70 5f 72 65 73 65 74 5f 6b 65 79 20 21 3d 20 67  p_reset_key != g
2790: 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73  lobal_interp_res
27a0: 65 74 5f 6b 65 79 29 20 7b 0a 09 09 41 50 50 46  et_key) {...APPF
27b0: 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61  S_DEBUG("Termina
27c0: 74 69 6e 67 20 6f 6c 64 20 69 6e 74 65 72 70 72  ting old interpr
27d0: 65 74 65 72 20 61 6e 64 20 72 65 73 74 61 72 74  eter and restart
27e0: 69 6e 67 20 64 75 65 20 74 6f 20 72 65 73 65 74  ing due to reset
27f0: 20 72 65 71 75 65 73 74 2e 22 29 3b 0a 0a 09 09   request.");....
2800: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
2810: 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65  l(Tcl_DeleteInte
2820: 72 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09  rp(interp);)....
2830: 69 6e 74 65 72 70 20 3d 20 4e 55 4c 4c 3b 0a 0a  interp = NULL;..
2840: 09 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20  ..pthread_ret = 
2850: 70 74 68 72 65 61 64 5f 73 65 74 73 70 65 63 69  pthread_setspeci
2860: 66 69 63 28 69 6e 74 65 72 70 4b 65 79 2c 20 69  fic(interpKey, i
2870: 6e 74 65 72 70 29 3b 0a 09 7d 0a 0a 09 69 66 20  nterp);..}...if 
2880: 28 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72  (global_interp_r
2890: 65 73 65 74 5f 6b 65 79 20 3d 3d 20 2d 31 29 20  eset_key == -1) 
28a0: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
28b0: 22 52 65 74 75 72 6e 69 6e 67 20 4e 55 4c 4c 20  "Returning NULL 
28c0: 73 69 6e 63 65 20 77 65 20 61 72 65 20 69 6e 20  since we are in 
28d0: 74 68 65 20 70 72 6f 63 65 73 73 20 6f 66 20 74  the process of t
28e0: 65 72 6d 69 6e 61 74 69 6e 67 20 61 6c 6c 20 74  erminating all t
28f0: 68 72 65 61 64 73 2e 22 29 3b 0a 0a 09 09 72 65  hreads.");....re
2900: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
2910: 09 74 68 72 65 61 64 5f 69 6e 74 65 72 70 5f 72  .thread_interp_r
2920: 65 73 65 74 5f 6b 65 79 20 3d 20 67 6c 6f 62 61  eset_key = globa
2930: 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  l_interp_reset_k
2940: 65 79 3b 0a 0a 09 69 66 20 28 69 6e 74 65 72 70  ey;...if (interp
2950: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 6e   == NULL) {...in
2960: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65  terp = appfs_cre
2970: 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55  ate_TclInterp(NU
2980: 4c 4c 29 3b 0a 0a 09 09 69 66 20 28 69 6e 74 65  LL);....if (inte
2990: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
29a0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 72  .APPFS_DEBUG("Cr
29b0: 65 61 74 65 20 69 6e 74 65 72 70 20 66 61 69 6c  eate interp fail
29c0: 65 64 2c 20 72 65 74 75 72 6e 69 6e 67 69 6e 20  ed, returningin 
29d0: 66 61 69 6c 75 72 65 2e 22 29 3b 0a 0a 09 09 09  failure.");.....
29e0: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09  return(NULL);...
29f0: 7d 0a 0a 09 09 70 74 68 72 65 61 64 5f 72 65 74  }....pthread_ret
2a00: 20 3d 20 70 74 68 72 65 61 64 5f 73 65 74 73 70   = pthread_setsp
2a10: 65 63 69 66 69 63 28 69 6e 74 65 72 70 4b 65 79  ecific(interpKey
2a20: 2c 20 69 6e 74 65 72 70 29 3b 0a 09 09 69 66 20  , interp);...if 
2a30: 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20  (pthread_ret != 
2a40: 30 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45  0) {....APPFS_DE
2a50: 42 55 47 28 22 70 74 68 72 65 61 64 5f 73 65 74  BUG("pthread_set
2a60: 73 70 65 63 69 66 69 63 28 29 20 66 61 69 6c 65  specific() faile
2a70: 64 2e 20 20 54 65 72 6d 69 6e 61 74 69 6e 67 20  d.  Terminating 
2a80: 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e  Tcl interpreter.
2a90: 22 29 3b 0a 0a 09 09 09 61 70 70 66 73 5f 63 61  ");.....appfs_ca
2aa0: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65  ll_libtcl(Tcl_De
2ab0: 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72  leteInterp(inter
2ac0: 70 29 3b 29 0a 0a 09 09 09 72 65 74 75 72 6e 28  p);).....return(
2ad0: 4e 55 4c 4c 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09  NULL);...}..}...
2ae0: 72 65 74 75 72 6e 28 69 6e 74 65 72 70 29 3b 0a  return(interp);.
2af0: 7d 0a 0a 2f 2a 0a 20 2a 20 45 76 61 6c 75 61 74  }../*. * Evaluat
2b00: 65 20 61 20 54 63 6c 20 73 63 72 69 70 74 20 63  e a Tcl script c
2b10: 6f 6e 73 74 72 75 63 74 65 64 20 62 79 20 63 6f  onstructed by co
2b20: 6e 63 61 74 65 6e 61 74 69 6e 67 20 61 20 62 75  ncatenating a bu
2b30: 6e 63 68 20 6f 66 20 43 20 73 74 72 69 6e 67 73  nch of C strings
2b40: 0a 20 2a 20 74 6f 67 65 74 68 65 72 2e 0a 20 2a  . * together.. *
2b50: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  /.static int app
2b60: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 54 63 6c 5f  fs_Tcl_Eval(Tcl_
2b70: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20  Interp *interp, 
2b80: 69 6e 74 20 6f 62 6a 63 2c 20 63 6f 6e 73 74 20  int objc, const 
2b90: 63 68 61 72 20 2a 63 6d 64 2c 20 2e 2e 2e 29 20  char *cmd, ...) 
2ba0: 7b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a 6f 62 6a  {..Tcl_Obj **obj
2bb0: 76 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a  v;..const char *
2bc0: 61 72 67 3b 0a 09 76 61 5f 6c 69 73 74 20 61 72  arg;..va_list ar
2bd0: 67 70 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b  gp;..int retval;
2be0: 0a 09 69 6e 74 20 69 3b 0a 0a 09 69 66 20 28 69  ..int i;...if (i
2bf0: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
2c00: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
2c10: 49 6e 76 61 6c 69 64 20 69 6e 74 65 72 70 72 65  Invalid interpre
2c20: 74 65 72 20 70 61 73 73 65 64 20 69 6e 2c 20 72  ter passed in, r
2c30: 65 74 75 72 6e 69 6e 67 20 69 6e 20 66 61 69 6c  eturning in fail
2c40: 75 72 65 2e 22 29 3b 0a 0a 09 09 72 65 74 75 72  ure.");....retur
2c50: 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d  n(TCL_ERROR);..}
2c60: 0a 0a 09 6f 62 6a 76 20 3d 20 28 76 6f 69 64 20  ...objv = (void 
2c70: 2a 29 20 63 6b 61 6c 6c 6f 63 28 73 69 7a 65 6f  *) ckalloc(sizeo
2c80: 66 28 2a 6f 62 6a 76 29 20 2a 20 6f 62 6a 63 29  f(*objv) * objc)
2c90: 3b 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ;...appfs_call_l
2ca0: 69 62 74 63 6c 28 0a 09 09 6f 62 6a 76 5b 30 5d  ibtcl(...objv[0]
2cb0: 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67   = Tcl_NewString
2cc0: 4f 62 6a 28 63 6d 64 2c 20 2d 31 29 3b 0a 0a 09  Obj(cmd, -1);...
2cd0: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
2ce0: 74 28 6f 62 6a 76 5b 30 5d 29 3b 0a 0a 09 09 76  t(objv[0]);....v
2cf0: 61 5f 73 74 61 72 74 28 61 72 67 70 2c 20 63 6d  a_start(argp, cm
2d00: 64 29 3b 0a 09 09 66 6f 72 20 28 69 20 3d 20 31  d);...for (i = 1
2d10: 3b 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29  ; i < objc; i++)
2d20: 20 7b 0a 09 09 09 61 72 67 20 3d 20 76 61 5f 61   {....arg = va_a
2d30: 72 67 28 61 72 67 70 2c 20 63 6f 6e 73 74 20 63  rg(argp, const c
2d40: 68 61 72 20 2a 29 3b 0a 0a 09 09 09 6f 62 6a 76  har *);.....objv
2d50: 5b 69 5d 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72  [i] = Tcl_NewStr
2d60: 69 6e 67 4f 62 6a 28 61 72 67 2c 20 2d 31 29 3b  ingObj(arg, -1);
2d70: 0a 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66  .....Tcl_IncrRef
2d80: 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a  Count(objv[i]);.
2d90: 09 09 7d 0a 09 09 76 61 5f 65 6e 64 28 61 72 67  ..}...va_end(arg
2da0: 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63  p);..)...appfs_c
2db0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65  all_libtcl(...re
2dc0: 74 76 61 6c 20 3d 20 54 63 6c 5f 45 76 61 6c 4f  tval = Tcl_EvalO
2dd0: 62 6a 76 28 69 6e 74 65 72 70 2c 20 6f 62 6a 63  bjv(interp, objc
2de0: 2c 20 6f 62 6a 76 2c 20 30 29 3b 0a 09 29 0a 0a  , objv, 0);..)..
2df0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
2e00: 63 6c 28 0a 09 09 66 6f 72 20 28 69 20 3d 20 30  cl(...for (i = 0
2e10: 3b 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29  ; i < objc; i++)
2e20: 20 7b 0a 09 09 09 54 63 6c 5f 44 65 63 72 52 65   {....Tcl_DecrRe
2e30: 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b  fCount(objv[i]);
2e40: 0a 09 09 7d 0a 09 29 0a 0a 09 63 6b 66 72 65 65  ...}..)...ckfree
2e50: 28 28 76 6f 69 64 20 2a 29 20 6f 62 6a 76 29 3b  ((void *) objv);
2e60: 0a 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d  ...if (retval !=
2e70: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 61 70 70   TCL_OK) {...app
2e80: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
2e90: 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
2ea0: 54 63 6c 20 63 6f 6d 6d 61 6e 64 20 66 61 69 6c  Tcl command fail
2eb0: 65 64 2c 20 3a 3a 65 72 72 6f 72 49 6e 66 6f 20  ed, ::errorInfo 
2ec0: 63 6f 6e 74 61 69 6e 73 3a 20 25 73 5c 6e 22 2c  contains: %s\n",
2ed0: 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65   Tcl_GetVar(inte
2ee0: 72 70 2c 20 22 3a 3a 65 72 72 6f 72 49 6e 66 6f  rp, "::errorInfo
2ef0: 22 2c 20 30 29 29 3b 0a 09 09 29 0a 09 7d 0a 0a  ", 0));...)..}..
2f00: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
2f10: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 52 65 71 75 65 73  .}../*. * Reques
2f20: 74 20 61 6c 6c 20 54 63 6c 20 69 6e 74 65 72 70  t all Tcl interp
2f30: 72 65 74 65 72 73 20 72 65 73 74 61 72 74 0a 20  reters restart. 
2f40: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  */.static void a
2f50: 70 70 66 73 5f 74 63 6c 5f 52 65 73 65 74 49 6e  ppfs_tcl_ResetIn
2f60: 74 65 72 70 73 28 76 6f 69 64 29 20 7b 0a 09 41  terps(void) {..A
2f70: 50 50 46 53 5f 44 45 42 55 47 28 22 52 65 71 75  PPFS_DEBUG("Requ
2f80: 65 73 74 69 6e 67 20 72 65 73 65 74 20 6f 66 20  esting reset of 
2f90: 61 6c 6c 20 69 6e 74 65 72 70 72 65 74 65 72 73  all interpreters
2fa0: 2e 22 29 3b 0a 0a 09 5f 5f 73 79 6e 63 5f 61 64  .");...__sync_ad
2fb0: 64 5f 61 6e 64 5f 66 65 74 63 68 28 26 69 6e 74  d_and_fetch(&int
2fc0: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 31  erp_reset_key, 1
2fd0: 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a  );...return;.}..
2fe0: 2f 2a 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65 20  /*. * Determine 
2ff0: 74 68 65 20 55 49 44 20 66 6f 72 20 74 68 65 20  the UID for the 
3000: 75 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20  user making the 
3010: 63 75 72 72 65 6e 74 20 46 55 53 45 20 66 69 6c  current FUSE fil
3020: 65 73 79 73 74 65 6d 20 72 65 71 75 65 73 74 2e  esystem request.
3030: 0a 20 2a 20 54 68 69 73 20 77 69 6c 6c 20 62 65  . * This will be
3040: 20 75 73 65 64 20 74 6f 20 6c 6f 6f 6b 75 70 20   used to lookup 
3050: 74 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20  the user's home 
3060: 64 69 72 65 63 74 6f 72 79 20 73 6f 20 77 65 20  directory so we 
3070: 63 61 6e 20 73 65 61 72 63 68 20 66 6f 72 0a 20  can search for. 
3080: 2a 20 6c 6f 63 61 6c 6c 79 20 6d 6f 64 69 66 69  * locally modifi
3090: 65 64 20 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73 74  ed files.. */.st
30a0: 61 74 69 63 20 75 69 64 5f 74 20 61 70 70 66 73  atic uid_t appfs
30b0: 5f 67 65 74 5f 66 73 75 69 64 28 76 6f 69 64 29  _get_fsuid(void)
30c0: 20 7b 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f   {..struct fuse_
30d0: 63 6f 6e 74 65 78 74 20 2a 63 74 78 3b 0a 0a 09  context *ctx;...
30e0: 69 66 20 28 21 61 70 70 66 73 5f 66 75 73 65 5f  if (!appfs_fuse_
30f0: 73 74 61 72 74 65 64 29 20 7b 0a 09 09 72 65 74  started) {...ret
3100: 75 72 6e 28 67 65 74 75 69 64 28 29 29 3b 0a 09  urn(getuid());..
3110: 7d 0a 0a 09 63 74 78 20 3d 20 66 75 73 65 5f 67  }...ctx = fuse_g
3120: 65 74 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09 69  et_context();..i
3130: 66 20 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 20  f (ctx == NULL) 
3140: 7b 0a 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74 6f  {.../* Unable to
3150: 20 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72   lookup user for
3160: 20 73 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f 0a   some reason */.
3170: 09 09 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20 75  ../* Return an u
3180: 6e 70 72 69 76 69 6c 65 67 65 64 20 75 73 65 72  nprivileged user
3190: 20 49 44 20 2a 2f 0a 09 09 41 50 50 46 53 5f 44   ID */...APPFS_D
31a0: 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20  EBUG("Unable to 
31b0: 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20  lookup user for 
31c0: 73 6f 6d 65 20 72 65 61 73 6f 6e 2c 20 72 65 74  some reason, ret
31d0: 75 72 6e 69 6e 6e 67 20 75 73 65 72 20 49 44 20  urninng user ID 
31e0: 6f 66 20 31 22 29 3b 0a 0a 09 09 72 65 74 75 72  of 1");....retur
31f0: 6e 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  n(1);..}...retur
3200: 6e 28 63 74 78 2d 3e 75 69 64 29 3b 0a 7d 0a 0a  n(ctx->uid);.}..
3210: 2f 2a 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65 20  /*. * Determine 
3220: 74 68 65 20 47 49 44 20 66 6f 72 20 74 68 65 20  the GID for the 
3230: 75 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20  user making the 
3240: 63 75 72 72 65 6e 74 20 46 55 53 45 20 66 69 6c  current FUSE fil
3250: 65 73 79 73 74 65 6d 20 72 65 71 75 65 73 74 2e  esystem request.
3260: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 67 69 64 5f  . */.static gid_
3270: 74 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69  t appfs_get_fsgi
3280: 64 28 76 6f 69 64 29 20 7b 0a 09 73 74 72 75 63  d(void) {..struc
3290: 74 20 66 75 73 65 5f 63 6f 6e 74 65 78 74 20 2a  t fuse_context *
32a0: 63 74 78 3b 0a 0a 09 69 66 20 28 21 61 70 70 66  ctx;...if (!appf
32b0: 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 29 20  s_fuse_started) 
32c0: 7b 0a 09 09 72 65 74 75 72 6e 28 67 65 74 67 69  {...return(getgi
32d0: 64 28 29 29 3b 0a 09 7d 0a 0a 09 63 74 78 20 3d  d());..}...ctx =
32e0: 20 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65 78   fuse_get_contex
32f0: 74 28 29 3b 0a 09 69 66 20 28 63 74 78 20 3d 3d  t();..if (ctx ==
3300: 20 4e 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20 55 6e   NULL) {.../* Un
3310: 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 75  able to lookup u
3320: 73 65 72 20 66 6f 72 20 73 6f 6d 65 20 72 65 61  ser for some rea
3330: 73 6f 6e 20 2a 2f 0a 09 09 2f 2a 20 52 65 74 75  son */.../* Retu
3340: 72 6e 20 61 6e 20 75 6e 70 72 69 76 69 6c 65 67  rn an unprivileg
3350: 65 64 20 75 73 65 72 20 49 44 20 2a 2f 0a 09 09  ed user ID */...
3360: 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61  APPFS_DEBUG("Una
3370: 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 67 72  ble to lookup gr
3380: 6f 75 70 20 66 6f 72 20 73 6f 6d 65 20 72 65 61  oup for some rea
3390: 73 6f 6e 2c 20 72 65 74 75 72 6e 69 6e 6e 67 20  son, returninng 
33a0: 67 72 6f 75 70 20 49 44 20 6f 66 20 31 22 29 3b  group ID of 1");
33b0: 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  ....return(1);..
33c0: 7d 0a 0a 09 72 65 74 75 72 6e 28 63 74 78 2d 3e  }...return(ctx->
33d0: 67 69 64 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  gid);.}..static 
33e0: 76 6f 69 64 20 61 70 70 66 73 5f 73 69 6d 75 6c  void appfs_simul
33f0: 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65  ate_user_fs_ente
3400: 72 28 76 6f 69 64 29 20 7b 0a 09 73 65 74 66 73  r(void) {..setfs
3410: 75 69 64 28 61 70 70 66 73 5f 67 65 74 5f 66 73  uid(appfs_get_fs
3420: 75 69 64 28 29 29 3b 0a 09 73 65 74 66 73 67 69  uid());..setfsgi
3430: 64 28 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69  d(appfs_get_fsgi
3440: 64 28 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  d());.}..static 
3450: 76 6f 69 64 20 61 70 70 66 73 5f 73 69 6d 75 6c  void appfs_simul
3460: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76  ate_user_fs_leav
3470: 65 28 76 6f 69 64 29 20 7b 0a 09 73 65 74 66 73  e(void) {..setfs
3480: 75 69 64 28 30 29 3b 0a 09 73 65 74 66 73 67 69  uid(0);..setfsgi
3490: 64 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 4c  d(0);.}../*. * L
34a0: 6f 6f 6b 20 75 70 20 74 68 65 20 68 6f 6d 65 20  ook up the home 
34b0: 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20 61 20  directory for a 
34c0: 67 69 76 65 6e 20 55 49 44 0a 20 2a 20 20 20 20  given UID. *    
34d0: 20 20 20 20 52 65 74 75 72 6e 73 20 61 20 43 20      Returns a C 
34e0: 73 74 72 69 6e 67 20 63 6f 6e 74 61 69 6e 69 6e  string containin
34f0: 67 20 74 68 65 20 75 73 65 72 27 73 20 68 6f 6d  g the user's hom
3500: 65 20 64 69 72 65 63 74 6f 72 79 20 6f 72 20 4e  e directory or N
3510: 55 4c 4c 20 69 66 0a 20 2a 20 20 20 20 20 20 20  ULL if. *       
3520: 20 74 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65   the user's home
3530: 20 64 69 72 65 63 74 6f 72 79 20 64 6f 65 73 20   directory does 
3540: 6e 6f 74 20 65 78 69 73 74 20 6f 72 20 69 73 20  not exist or is 
3550: 6e 6f 74 20 63 6f 72 72 65 63 74 6c 79 0a 20 2a  not correctly. *
3560: 20 20 20 20 20 20 20 20 63 6f 6e 66 69 67 75 72          configur
3570: 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 63 68  ed. */.static ch
3580: 61 72 20 2a 61 70 70 66 73 5f 67 65 74 5f 68 6f  ar *appfs_get_ho
3590: 6d 65 64 69 72 28 75 69 64 5f 74 20 66 73 75 69  medir(uid_t fsui
35a0: 64 29 20 7b 0a 09 73 74 72 75 63 74 20 70 61 73  d) {..struct pas
35b0: 73 77 64 20 65 6e 74 72 79 2c 20 2a 72 65 73 75  swd entry, *resu
35c0: 6c 74 3b 0a 09 73 74 72 75 63 74 20 73 74 61 74  lt;..struct stat
35d0: 20 73 74 62 75 66 3b 0a 09 63 68 61 72 20 62 75   stbuf;..char bu
35e0: 66 5b 31 30 32 34 5d 2c 20 2a 72 65 74 76 61 6c  f[1024], *retval
35f0: 3b 0a 09 69 6e 74 20 67 70 75 5f 72 65 74 2c 20  ;..int gpu_ret, 
3600: 73 74 61 74 5f 72 65 74 3b 0a 0a 09 67 70 75 5f  stat_ret;...gpu_
3610: 72 65 74 20 3d 20 67 65 74 70 77 75 69 64 5f 72  ret = getpwuid_r
3620: 28 66 73 75 69 64 2c 20 26 65 6e 74 72 79 2c 20  (fsuid, &entry, 
3630: 62 75 66 2c 20 73 69 7a 65 6f 66 28 62 75 66 29  buf, sizeof(buf)
3640: 2c 20 26 72 65 73 75 6c 74 29 3b 0a 09 69 66 20  , &result);..if 
3650: 28 67 70 75 5f 72 65 74 20 21 3d 20 30 29 20 7b  (gpu_ret != 0) {
3660: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
3670: 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c  getpwuid_r(%llu,
3680: 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64 20 69   ...) returned i
3690: 6e 20 66 61 69 6c 75 72 65 22 2c 20 28 75 6e 73  n failure", (uns
36a0: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29  igned long long)
36b0: 20 66 73 75 69 64 29 3b 0a 0a 09 09 72 65 74 75   fsuid);....retu
36c0: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69  rn(NULL);..}...i
36d0: 66 20 28 72 65 73 75 6c 74 20 3d 3d 20 4e 55 4c  f (result == NUL
36e0: 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  L) {...APPFS_DEB
36f0: 55 47 28 22 67 65 74 70 77 75 69 64 5f 72 28 25  UG("getpwuid_r(%
3700: 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e  llu, ...) return
3710: 65 64 20 4e 55 4c 4c 20 72 65 73 75 6c 74 22 2c  ed NULL result",
3720: 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20   (unsigned long 
3730: 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b 0a 0a 09  long) fsuid);...
3740: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
3750: 7d 0a 0a 09 69 66 20 28 72 65 73 75 6c 74 2d 3e  }...if (result->
3760: 70 77 5f 64 69 72 20 3d 3d 20 4e 55 4c 4c 29 20  pw_dir == NULL) 
3770: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
3780: 22 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c 75  "getpwuid_r(%llu
3790: 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64 20  , ...) returned 
37a0: 4e 55 4c 4c 20 68 6f 6d 65 20 64 69 72 65 63 74  NULL home direct
37b0: 6f 72 79 22 2c 20 28 75 6e 73 69 67 6e 65 64 20  ory", (unsigned 
37c0: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64  long long) fsuid
37d0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  );....return(NUL
37e0: 4c 29 3b 0a 09 7d 0a 0a 09 73 74 61 74 5f 72 65  L);..}...stat_re
37f0: 74 20 3d 20 73 74 61 74 28 72 65 73 75 6c 74 2d  t = stat(result-
3800: 3e 70 77 5f 64 69 72 2c 20 26 73 74 62 75 66 29  >pw_dir, &stbuf)
3810: 3b 0a 09 69 66 20 28 73 74 61 74 5f 72 65 74 20  ;..if (stat_ret 
3820: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
3830: 44 45 42 55 47 28 22 73 74 61 74 28 25 73 29 20  DEBUG("stat(%s) 
3840: 72 65 74 75 72 6e 65 64 20 69 6e 20 66 61 69 6c  returned in fail
3850: 75 72 65 22 2c 20 72 65 73 75 6c 74 2d 3e 70 77  ure", result->pw
3860: 5f 64 69 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e  _dir);....return
3870: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20  (NULL);..}...if 
3880: 28 73 74 62 75 66 2e 73 74 5f 75 69 64 20 21 3d  (stbuf.st_uid !=
3890: 20 66 73 75 69 64 29 20 7b 0a 09 09 41 50 50 46   fsuid) {...APPF
38a0: 53 5f 44 45 42 55 47 28 22 55 49 44 20 6d 69 73  S_DEBUG("UID mis
38b0: 2d 6d 61 74 63 68 20 6f 6e 20 75 73 65 72 20 25  -match on user %
38c0: 6c 6c 75 27 73 20 68 6f 6d 65 20 64 69 72 65 63  llu's home direc
38d0: 74 6f 72 79 20 28 25 73 29 2e 20 20 49 74 27 73  tory (%s).  It's
38e0: 20 6f 77 6e 65 64 20 62 79 20 25 6c 6c 75 2e 22   owned by %llu."
38f0: 2c 0a 09 09 20 20 20 20 28 75 6e 73 69 67 6e 65  ,...    (unsigne
3900: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75  d long long) fsu
3910: 69 64 2c 0a 09 09 20 20 20 20 72 65 73 75 6c 74  id,...    result
3920: 2d 3e 70 77 5f 64 69 72 2c 0a 09 09 20 20 20 20  ->pw_dir,...    
3930: 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c  (unsigned long l
3940: 6f 6e 67 29 20 73 74 62 75 66 2e 73 74 5f 75 69  ong) stbuf.st_ui
3950: 64 0a 09 09 29 3b 0a 0a 09 09 72 65 74 75 72 6e  d...);....return
3960: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74  (NULL);..}...ret
3970: 76 61 6c 20 3d 20 73 74 72 64 75 70 28 72 65 73  val = strdup(res
3980: 75 6c 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09  ult->pw_dir);...
3990: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a  return(retval);.
39a0: 7d 0a 0a 2f 2a 0a 20 2a 20 47 65 6e 65 72 61 74  }../*. * Generat
39b0: 65 20 61 6e 20 69 6e 6f 64 65 20 66 6f 72 20 61  e an inode for a
39c0: 20 67 69 76 65 6e 20 70 61 74 68 2e 20 20 54 68   given path.  Th
39d0: 65 20 69 6e 6f 64 65 20 73 68 6f 75 6c 64 20 62  e inode should b
39e0: 65 20 63 6f 6d 70 75 74 65 64 20 69 6e 20 73 75  e computed in su
39f0: 63 68 0a 20 2a 20 61 20 77 61 79 20 74 68 61 74  ch. * a way that
3a00: 20 69 74 20 69 73 20 75 6e 6c 69 6b 65 6c 79 20   it is unlikely 
3a10: 74 6f 20 62 65 20 64 75 70 6c 69 63 61 74 65 64  to be duplicated
3a20: 20 61 6e 64 20 72 65 6d 61 69 6e 73 20 74 68 65   and remains the
3a30: 20 73 61 6d 65 20 66 6f 72 20 61 20 67 69 76 65   same for a give
3a40: 6e 0a 20 2a 20 66 69 6c 65 0a 20 2a 0a 20 2a 20  n. * file. *. * 
3a50: 43 75 72 72 65 6e 74 20 69 6d 70 6c 65 6d 65 6e  Current implemen
3a60: 74 61 74 69 6f 6e 20 69 73 20 61 6e 20 46 4e 56  tation is an FNV
3a70: 2d 31 61 20 33 32 2d 62 69 74 0a 20 2a 2f 0a 23  -1a 32-bit. */.#
3a80: 69 66 20 55 49 4e 54 5f 4d 41 58 20 3c 20 34 32  if UINT_MAX < 42
3a90: 39 34 39 36 37 32 39 35 0a 23 65 72 72 6f 72 20  94967295.#error 
3aa0: 49 6e 74 65 67 65 72 20 73 69 7a 65 20 69 73 20  Integer size is 
3ab0: 74 6f 6f 20 73 6d 61 6c 6c 20 0a 23 65 6e 64 69  too small .#endi
3ac0: 66 0a 73 74 61 74 69 63 20 75 6e 73 69 67 6e 65  f.static unsigne
3ad0: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 20 61 70 70 66  d long long appf
3ae0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65  s_get_path_inode
3af0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
3b00: 68 2c 20 69 6e 74 20 75 69 64 29 20 7b 0a 09 75  h, int uid) {..u
3b10: 6e 73 69 67 6e 65 64 20 69 6e 74 20 72 65 74 76  nsigned int retv
3b20: 61 6c 3b 0a 09 63 6f 6e 73 74 20 75 6e 73 69 67  al;..const unsig
3b30: 6e 65 64 20 63 68 61 72 20 2a 70 3b 0a 0a 09 72  ned char *p;...r
3b40: 65 74 76 61 6c 20 3d 20 32 31 36 36 31 33 36 32  etval = 21661362
3b50: 36 31 3b 20 2f 2a 20 46 4e 56 2d 31 61 20 33 32  61; /* FNV-1a 32
3b60: 2d 62 69 74 20 6f 66 66 73 65 74 5f 62 61 73 69  -bit offset_basi
3b70: 73 20 2a 2f 0a 0a 09 66 6f 72 20 28 70 20 3d 20  s */...for (p = 
3b80: 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a  (unsigned char *
3b90: 29 20 70 61 74 68 3b 20 2a 70 3b 20 70 2b 2b 29  ) path; *p; p++)
3ba0: 20 7b 0a 09 09 72 65 74 76 61 6c 20 5e 3d 20 28   {...retval ^= (
3bb0: 69 6e 74 29 20 2a 70 3b 0a 23 69 66 20 30 0a 09  int) *p;.#if 0..
3bc0: 09 72 65 74 76 61 6c 20 2a 3d 20 31 36 37 37 37  .retval *= 16777
3bd0: 36 31 39 3b 20 2f 2a 20 46 4e 56 2d 31 61 20 33  619; /* FNV-1a 3
3be0: 32 2d 62 69 74 20 70 72 69 6d 65 20 2a 2f 0a 23  2-bit prime */.#
3bf0: 65 6c 73 65 0a 09 09 2f 2a 20 47 43 43 20 4f 70  else.../* GCC Op
3c00: 74 69 6d 69 7a 65 64 20 72 65 70 6c 61 63 65 6d  timized replacem
3c10: 65 6e 74 20 2a 2f 0a 09 09 72 65 74 76 61 6c 20  ent */...retval 
3c20: 2b 3d 20 28 72 65 74 76 61 6c 20 3c 3c 20 31 29  += (retval << 1)
3c30: 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 34 29   + (retval << 4)
3c40: 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 37 29   + (retval << 7)
3c50: 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 38 29   + (retval << 8)
3c60: 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 32 34   + (retval << 24
3c70: 29 3b 0a 23 65 6e 64 69 66 0a 09 7d 0a 0a 09 69  );.#endif..}...i
3c80: 66 20 28 75 69 64 20 3e 3d 20 30 29 20 7b 0a 09  f (uid >= 0) {..
3c90: 09 72 65 74 76 61 6c 20 2b 3d 20 75 69 64 3b 0a  .retval += uid;.
3ca0: 09 09 72 65 74 76 61 6c 2b 2b 3b 0a 09 7d 0a 0a  ..retval++;..}..
3cb0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 4c 6f  .APPFS_DEBUG("Lo
3cc0: 6f 6b 65 64 20 75 70 20 69 6e 6f 64 65 20 6e 75  oked up inode nu
3cd0: 6d 62 65 72 20 66 6f 72 20 70 61 74 68 3d 25 73  mber for path=%s
3ce0: 2c 75 69 64 3d 25 69 3a 20 25 75 22 2c 20 70 61  ,uid=%i: %u", pa
3cf0: 74 68 2c 20 75 69 64 2c 20 72 65 74 76 61 6c 29  th, uid, retval)
3d00: 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61  ;...return(retva
3d10: 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 61 63  l);.}../*. * Cac
3d20: 68 65 20 47 65 74 20 50 61 74 68 20 49 6e 66 6f  he Get Path Info
3d30: 20 6c 6f 6f 6b 75 70 73 20 66 6f 72 20 73 70 65   lookups for spe
3d40: 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ed. */.static in
3d50: 74 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  t appfs_get_path
3d60: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28  _info_cache_get(
3d70: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
3d80: 2c 20 75 69 64 5f 74 20 75 69 64 2c 20 73 74 72  , uid_t uid, str
3d90: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e  uct appfs_pathin
3da0: 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a  fo *pathinfo) {.
3db0: 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61  .unsigned int ha
3dc0: 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68  sh_idx;..int pth
3dd0: 72 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20 72  read_ret;..int r
3de0: 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20  etval;...retval 
3df0: 3d 20 31 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72  = 1;...pthread_r
3e00: 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74  et = pthread_mut
3e10: 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70  ex_lock(&appfs_p
3e20: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d  ath_info_cache_m
3e30: 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72  utex);..if (pthr
3e40: 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  ead_ret != 0) {.
3e50: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55  ..APPFS_DEBUG("U
3e60: 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61  nable to lock pa
3e70: 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75  th_info cache mu
3e80: 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75  tex !");....retu
3e90: 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 41 50 50  rn(-1);..}...APP
3ea0: 46 53 5f 44 45 42 55 47 28 22 4c 6f 6f 6b 69 6e  FS_DEBUG("Lookin
3eb0: 67 20 75 70 20 63 61 63 68 65 20 65 6e 74 72 79  g up cache entry
3ec0: 20 66 6f 72 20 70 61 74 68 3d 25 73 2c 75 69 64   for path=%s,uid
3ed0: 3d 25 6c 6c 69 2e 2e 2e 22 2c 20 70 61 74 68 2c  =%lli...", path,
3ee0: 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69 64   (long long) uid
3ef0: 29 3b 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70  );...if (appfs_p
3f00: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 21  ath_info_cache !
3f10: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 61 73 68  = NULL) {...hash
3f20: 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f 67 65  _idx = (appfs_ge
3f30: 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74  t_path_inode(pat
3f40: 68 2c 20 75 69 64 29 29 20 25 20 61 70 70 66 73  h, uid)) % appfs
3f50: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
3f60: 5f 73 69 7a 65 3b 0a 0a 09 09 69 66 20 28 61 70  _size;....if (ap
3f70: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
3f80: 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63  che[hash_idx]._c
3f90: 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e 55 4c  ache_path != NUL
3fa0: 4c 29 20 7b 0a 09 09 09 69 66 20 28 73 74 72 63  L) {....if (strc
3fb0: 6d 70 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  mp(appfs_path_in
3fc0: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
3fd0: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 2c 20  x]._cache_path, 
3fe0: 70 61 74 68 29 20 3d 3d 20 30 20 26 26 20 61 70  path) == 0 && ap
3ff0: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4000: 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63  che[hash_idx]._c
4010: 61 63 68 65 5f 75 69 64 20 3d 3d 20 75 69 64 29  ache_uid == uid)
4020: 20 7b 0a 09 09 09 09 72 65 74 76 61 6c 20 3d 20   {.....retval = 
4030: 30 3b 0a 0a 09 09 09 09 6d 65 6d 63 70 79 28 70  0;......memcpy(p
4040: 61 74 68 69 6e 66 6f 2c 20 26 61 70 70 66 73 5f  athinfo, &appfs_
4050: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
4060: 68 61 73 68 5f 69 64 78 5d 2c 20 73 69 7a 65 6f  hash_idx], sizeo
4070: 66 28 2a 70 61 74 68 69 6e 66 6f 29 29 3b 0a 09  f(*pathinfo));..
4080: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 5f 63 61  ...pathinfo->_ca
4090: 63 68 65 5f 70 61 74 68 20 3d 20 4e 55 4c 4c 3b  che_path = NULL;
40a0: 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a 0a 09 70  ....}...}..}...p
40b0: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68  thread_ret = pth
40c0: 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63  read_mutex_unloc
40d0: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  k(&appfs_path_in
40e0: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b  fo_cache_mutex);
40f0: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
4100: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  t != 0) {...APPF
4110: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20  S_DEBUG("Unable 
4120: 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69  to unlock path_i
4130: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20  nfo cache mutex 
4140: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d  !");....return(-
4150: 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65 74  1);..}...if (ret
4160: 76 61 6c 20 3d 3d 20 30 29 20 7b 0a 09 09 41 50  val == 0) {...AP
4170: 50 46 53 5f 44 45 42 55 47 28 22 43 61 63 68 65  PFS_DEBUG("Cache
4180: 20 68 69 74 20 6f 6e 20 70 61 74 68 3d 25 73 2c   hit on path=%s,
4190: 75 69 64 3d 25 6c 6c 69 22 2c 20 70 61 74 68 2c  uid=%lli", path,
41a0: 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69 64   (long long) uid
41b0: 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 41  );..} else {...A
41c0: 50 50 46 53 5f 44 45 42 55 47 28 22 43 61 63 68  PPFS_DEBUG("Cach
41d0: 65 20 6d 69 73 73 20 6f 6e 20 70 61 74 68 3d 25  e miss on path=%
41e0: 73 2c 75 69 64 3d 25 6c 6c 69 22 2c 20 70 61 74  s,uid=%lli", pat
41f0: 68 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75  h, (long long) u
4200: 69 64 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  id);..}...return
4210: 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61  (retval);.}..sta
4220: 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 67  tic void appfs_g
4230: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
4240: 68 65 5f 61 64 64 28 63 6f 6e 73 74 20 63 68 61  he_add(const cha
4250: 72 20 2a 70 61 74 68 2c 20 75 69 64 5f 74 20 75  r *path, uid_t u
4260: 69 64 2c 20 73 74 72 75 63 74 20 61 70 70 66 73  id, struct appfs
4270: 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61 74 68 69  _pathinfo *pathi
4280: 6e 66 6f 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64  nfo) {..unsigned
4290: 20 69 6e 74 20 68 61 73 68 5f 69 64 78 3b 0a 09   int hash_idx;..
42a0: 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b  int pthread_ret;
42b0: 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d  ...pthread_ret =
42c0: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c   pthread_mutex_l
42d0: 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f  ock(&appfs_path_
42e0: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
42f0: 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f  );..if (pthread_
4300: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ret != 0) {...AP
4310: 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c  PFS_DEBUG("Unabl
4320: 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69  e to lock path_i
4330: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20  nfo cache mutex 
4340: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a  !");....return;.
4350: 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70  .}...if (appfs_p
4360: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d  ath_info_cache =
4370: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 61 70 70 66  = NULL) {...appf
4380: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4390: 65 20 3d 20 63 61 6c 6c 6f 63 28 61 70 70 66 73  e = calloc(appfs
43a0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
43b0: 5f 73 69 7a 65 2c 20 73 69 7a 65 6f 66 28 2a 61  _size, sizeof(*a
43c0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
43d0: 61 63 68 65 29 29 3b 0a 09 7d 0a 0a 09 68 61 73  ache));..}...has
43e0: 68 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f 67  h_idx = (appfs_g
43f0: 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61  et_path_inode(pa
4400: 74 68 2c 20 75 69 64 29 29 20 25 20 61 70 70 66  th, uid)) % appf
4410: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4420: 65 5f 73 69 7a 65 3b 0a 0a 09 69 66 20 28 61 70  e_size;...if (ap
4430: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4440: 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63  che[hash_idx]._c
4450: 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e 55 4c  ache_path != NUL
4460: 4c 29 20 7b 0a 09 09 66 72 65 65 28 61 70 70 66  L) {...free(appf
4470: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4480: 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63  e[hash_idx]._cac
4490: 68 65 5f 70 61 74 68 29 3b 0a 09 7d 0a 0a 09 6d  he_path);..}...m
44a0: 65 6d 63 70 79 28 26 61 70 70 66 73 5f 70 61 74  emcpy(&appfs_pat
44b0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73  h_info_cache[has
44c0: 68 5f 69 64 78 5d 2c 20 70 61 74 68 69 6e 66 6f  h_idx], pathinfo
44d0: 2c 20 73 69 7a 65 6f 66 28 2a 70 61 74 68 69 6e  , sizeof(*pathin
44e0: 66 6f 29 29 3b 0a 0a 09 61 70 70 66 73 5f 70 61  fo));...appfs_pa
44f0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61  th_info_cache[ha
4500: 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70  sh_idx]._cache_p
4510: 61 74 68 20 3d 20 73 74 72 64 75 70 28 70 61 74  ath = strdup(pat
4520: 68 29 3b 0a 09 61 70 70 66 73 5f 70 61 74 68 5f  h);..appfs_path_
4530: 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f  info_cache[hash_
4540: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64 20  idx]._cache_uid 
4550: 20 3d 20 75 69 64 3b 0a 0a 09 70 74 68 72 65 61   = uid;...pthrea
4560: 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f  d_ret = pthread_
4570: 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70  mutex_unlock(&ap
4580: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4590: 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20  che_mutex);..if 
45a0: 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20  (pthread_ret != 
45b0: 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  0) {...APPFS_DEB
45c0: 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e  UG("Unable to un
45d0: 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63  lock path_info c
45e0: 61 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a  ache mutex !");.
45f0: 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09  ...return;..}...
4600: 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69  return;.}..stati
4610: 63 20 76 6f 69 64 20 61 70 70 66 73 5f 67 65 74  c void appfs_get
4620: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4630: 5f 72 6d 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  _rm(const char *
4640: 70 61 74 68 2c 20 75 69 64 5f 74 20 75 69 64 29  path, uid_t uid)
4650: 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74   {..unsigned int
4660: 20 68 61 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20   hash_idx;..int 
4670: 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 70  pthread_ret;...p
4680: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68  thread_ret = pth
4690: 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28  read_mutex_lock(
46a0: 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  &appfs_path_info
46b0: 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09  _cache_mutex);..
46c0: 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20  if (pthread_ret 
46d0: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
46e0: 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f  DEBUG("Unable to
46f0: 20 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20   lock path_info 
4700: 63 61 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b  cache mutex !");
4710: 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a  ....return;..}..
4720: 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f  .if (appfs_path_
4730: 69 6e 66 6f 5f 63 61 63 68 65 20 21 3d 20 4e 55  info_cache != NU
4740: 4c 4c 29 20 7b 0a 09 09 68 61 73 68 5f 69 64 78  LL) {...hash_idx
4750: 20 3d 20 28 61 70 70 66 73 5f 67 65 74 5f 70 61   = (appfs_get_pa
4760: 74 68 5f 69 6e 6f 64 65 28 70 61 74 68 2c 20 75  th_inode(path, u
4770: 69 64 29 29 20 25 20 61 70 70 66 73 5f 70 61 74  id)) % appfs_pat
4780: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a  h_info_cache_siz
4790: 65 3b 0a 0a 09 09 69 66 20 28 61 70 70 66 73 5f  e;....if (appfs_
47a0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
47b0: 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65  hash_idx]._cache
47c0: 5f 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b  _path != NULL) {
47d0: 0a 09 09 09 66 72 65 65 28 61 70 70 66 73 5f 70  ....free(appfs_p
47e0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68  ath_info_cache[h
47f0: 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f  ash_idx]._cache_
4800: 70 61 74 68 29 3b 0a 0a 09 09 09 61 70 70 66 73  path);.....appfs
4810: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4820: 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68  [hash_idx]._cach
4830: 65 5f 70 61 74 68 20 3d 20 4e 55 4c 4c 3b 0a 09  e_path = NULL;..
4840: 09 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f  .}..}...pthread_
4850: 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75  ret = pthread_mu
4860: 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66  tex_unlock(&appf
4870: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4880: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70  e_mutex);..if (p
4890: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
48a0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
48b0: 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f  ("Unable to unlo
48c0: 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63  ck path_info cac
48d0: 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09  he mutex !");...
48e0: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65  .return;..}...re
48f0: 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  turn;.}..static 
4900: 76 6f 69 64 20 61 70 70 66 73 5f 67 65 74 5f 70  void appfs_get_p
4910: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66  ath_info_cache_f
4920: 6c 75 73 68 28 75 69 64 5f 74 20 75 69 64 2c 20  lush(uid_t uid, 
4930: 69 6e 74 20 6e 65 77 5f 73 69 7a 65 29 20 7b 0a  int new_size) {.
4940: 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 64  .unsigned int id
4950: 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f  x;..int pthread_
4960: 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42  ret;...APPFS_DEB
4970: 55 47 28 22 46 6c 75 73 68 69 6e 67 20 41 70 70  UG("Flushing App
4980: 46 53 20 63 61 63 68 65 20 28 75 69 64 20 3d 20  FS cache (uid = 
4990: 25 6c 6c 69 2c 20 6e 65 77 5f 73 69 7a 65 20 3d  %lli, new_size =
49a0: 20 25 69 29 22 2c 20 28 6c 6f 6e 67 20 6c 6f 6e   %i)", (long lon
49b0: 67 29 20 75 69 64 2c 20 6e 65 77 5f 73 69 7a 65  g) uid, new_size
49c0: 29 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74  );...pthread_ret
49d0: 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78   = pthread_mutex
49e0: 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74  _lock(&appfs_pat
49f0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74  h_info_cache_mut
4a00: 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61  ex);..if (pthrea
4a10: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
4a20: 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61  APPFS_DEBUG("Una
4a30: 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68  ble to lock path
4a40: 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65  _info cache mute
4a50: 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  x !");....return
4a60: 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73  ;..}...if (appfs
4a70: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4a80: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 6f   != NULL) {...fo
4a90: 72 20 28 69 64 78 20 3d 20 30 3b 20 69 64 78 20  r (idx = 0; idx 
4aa0: 3c 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  < appfs_path_inf
4ab0: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 20 69 64  o_cache_size; id
4ac0: 78 2b 2b 29 20 7b 0a 09 09 09 69 66 20 28 61 70  x++) {....if (ap
4ad0: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4ae0: 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f  che[idx]._cache_
4af0: 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  path != NULL) {.
4b00: 09 09 09 09 69 66 20 28 75 69 64 20 21 3d 20 28  ....if (uid != (
4b10: 28 75 69 64 5f 74 29 20 2d 31 29 29 20 7b 0a 09  (uid_t) -1)) {..
4b20: 09 09 09 09 69 66 20 28 61 70 70 66 73 5f 70 61  ....if (appfs_pa
4b30: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64  th_info_cache[id
4b40: 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64 20 21 3d  x]._cache_uid !=
4b50: 20 75 69 64 29 20 7b 0a 09 09 09 09 09 09 63 6f   uid) {.......co
4b60: 6e 74 69 6e 75 65 3b 0a 09 09 09 09 09 7d 0a 09  ntinue;......}..
4b70: 09 09 09 7d 0a 0a 09 09 09 09 66 72 65 65 28 61  ...}......free(a
4b80: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4b90: 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65  ache[idx]._cache
4ba0: 5f 70 61 74 68 29 3b 0a 0a 09 09 09 09 61 70 70  _path);......app
4bb0: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4bc0: 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70  he[idx]._cache_p
4bd0: 61 74 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 09 7d  ath = NULL;....}
4be0: 0a 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 75 69  ...}..}...if (ui
4bf0: 64 20 3d 3d 20 28 28 75 69 64 5f 74 29 20 2d 31  d == ((uid_t) -1
4c00: 29 29 20 7b 0a 09 09 66 72 65 65 28 61 70 70 66  )) {...free(appf
4c10: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4c20: 65 29 3b 0a 0a 09 09 61 70 70 66 73 5f 70 61 74  e);....appfs_pat
4c30: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20 4e  h_info_cache = N
4c40: 55 4c 4c 3b 0a 0a 09 09 69 66 20 28 6e 65 77 5f  ULL;....if (new_
4c50: 73 69 7a 65 20 21 3d 20 2d 31 29 20 7b 0a 09 09  size != -1) {...
4c60: 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  .appfs_path_info
4c70: 5f 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 6e 65  _cache_size = ne
4c80: 77 5f 73 69 7a 65 3b 0a 09 09 7d 0a 09 7d 0a 0a  w_size;...}..}..
4c90: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
4ca0: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c  thread_mutex_unl
4cb0: 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f  ock(&appfs_path_
4cc0: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
4cd0: 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f  );..if (pthread_
4ce0: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ret != 0) {...AP
4cf0: 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c  PFS_DEBUG("Unabl
4d00: 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68  e to unlock path
4d10: 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65  _info cache mute
4d20: 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  x !");....return
4d30: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d  ;..}...return;.}
4d40: 0a 0a 2f 2a 20 47 65 74 20 69 6e 66 6f 72 6d 61  ../* Get informa
4d50: 74 69 6f 6e 20 61 62 6f 75 74 20 61 20 70 61 74  tion about a pat
4d60: 68 2c 20 61 6e 64 20 6f 70 74 69 6f 6e 61 6c 6c  h, and optionall
4d70: 79 20 6c 69 73 74 20 63 68 69 6c 64 72 65 6e 20  y list children 
4d80: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  */.static int ap
4d90: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
4da0: 6f 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  o(const char *pa
4db0: 74 68 2c 20 73 74 72 75 63 74 20 61 70 70 66 73  th, struct appfs
4dc0: 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61 74 68 69  _pathinfo *pathi
4dd0: 6e 66 6f 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  nfo) {..Tcl_Inte
4de0: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c  rp *interp;..Tcl
4df0: 5f 4f 62 6a 20 2a 61 74 74 72 73 5f 64 69 63 74  _Obj *attrs_dict
4e00: 2c 20 2a 61 74 74 72 5f 76 61 6c 75 65 3b 0a 09  , *attr_value;..
4e10: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 74 74 72  const char *attr
4e20: 5f 76 61 6c 75 65 5f 73 74 72 2c 20 2a 61 74 74  _value_str, *att
4e30: 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 3b 0a 09  r_value_str_i;..
4e40: 54 63 6c 5f 57 69 64 65 49 6e 74 20 61 74 74 72  Tcl_WideInt attr
4e50: 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 69 6e  _value_wide;..in
4e60: 74 20 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74  t attr_value_int
4e70: 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65  ;..static __thre
4e80: 61 64 20 54 63 6c 5f 4f 62 6a 20 2a 61 74 74 72  ad Tcl_Obj *attr
4e90: 5f 6b 65 79 5f 74 79 70 65 20 3d 20 4e 55 4c 4c  _key_type = NULL
4ea0: 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d  , *attr_key_perm
4eb0: 73 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f  s = NULL, *attr_
4ec0: 6b 65 79 5f 73 69 7a 65 20 3d 20 4e 55 4c 4c 2c  key_size = NULL,
4ed0: 20 2a 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 20   *attr_key_time 
4ee0: 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65  = NULL, *attr_ke
4ef0: 79 5f 73 6f 75 72 63 65 20 3d 20 4e 55 4c 4c 2c  y_source = NULL,
4f00: 20 2a 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64   *attr_key_child
4f10: 63 6f 75 6e 74 20 3d 20 4e 55 4c 4c 2c 20 2a 61  count = NULL, *a
4f20: 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64  ttr_key_packaged
4f30: 20 3d 20 4e 55 4c 4c 3b 0a 09 69 6e 74 20 63 61   = NULL;..int ca
4f40: 63 68 65 5f 72 65 74 3b 0a 09 69 6e 74 20 74 63  che_ret;..int tc
4f50: 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65 74 76  l_ret;..int retv
4f60: 61 6c 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64  al;..uid_t fsuid
4f70: 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a  ;...retval = 0;.
4f80: 0a 09 66 73 75 69 64 20 3d 20 61 70 70 66 73 5f  ..fsuid = appfs_
4f90: 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 0a 09 63  get_fsuid();...c
4fa0: 61 63 68 65 5f 72 65 74 20 3d 20 61 70 70 66 73  ache_ret = appfs
4fb0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
4fc0: 61 63 68 65 5f 67 65 74 28 70 61 74 68 2c 20 66  ache_get(path, f
4fd0: 73 75 69 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b  suid, pathinfo);
4fe0: 0a 09 69 66 20 28 63 61 63 68 65 5f 72 65 74 20  ..if (cache_ret 
4ff0: 3d 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 70 61  == 0) {...if (pa
5000: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d 20  thinfo->type == 
5010: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44  APPFS_PATHTYPE_D
5020: 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 29 20 7b  OES_NOT_EXIST) {
5030: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
5040: 22 52 65 74 75 72 6e 69 6e 67 20 66 72 6f 6d 20  "Returning from 
5050: 63 61 63 68 65 3a 20 64 6f 65 73 20 6e 6f 74 20  cache: does not 
5060: 65 78 69 73 74 20 5c 22 25 73 5c 22 22 2c 20 70  exist \"%s\"", p
5070: 61 74 68 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e  ath);.....return
5080: 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09 09 7d 0a 0a  (-ENOENT);...}..
5090: 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2d 3e  ..if (pathinfo->
50a0: 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50 41  type == APPFS_PA
50b0: 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 29 20  THTYPE_INVALID) 
50c0: 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  {....APPFS_DEBUG
50d0: 28 22 52 65 74 75 72 6e 69 6e 67 20 66 72 6f 6d  ("Returning from
50e0: 20 63 61 63 68 65 3a 20 69 6e 76 61 6c 69 64 20   cache: invalid 
50f0: 6f 62 6a 65 63 74 20 5c 22 25 73 5c 22 22 2c 20  object \"%s\"", 
5100: 70 61 74 68 29 3b 0a 0a 09 09 09 72 65 74 75 72  path);.....retur
5110: 6e 28 2d 45 49 4f 29 3b 0a 09 09 7d 0a 0a 09 09  n(-EIO);...}....
5120: 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09  return(0);..}...
5130: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54  interp = appfs_T
5140: 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20  clInterp();..if 
5150: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
5160: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
5170: 28 22 65 72 72 6f 72 3a 20 55 6e 61 62 6c 65 20  ("error: Unable 
5180: 74 6f 20 67 65 74 20 61 6e 20 69 6e 74 65 72 70  to get an interp
5190: 72 65 74 65 72 22 29 3b 0a 0a 09 09 72 65 74 75  reter");....retu
51a0: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
51b0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
51c0: 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e  (Tcl_Preserve(in
51d0: 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72 65  terp);)...tcl_re
51e0: 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76  t = appfs_Tcl_Ev
51f0: 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a  al(interp, 2, ":
5200: 3a 61 70 70 66 73 3a 3a 67 65 74 61 74 74 72 22  :appfs::getattr"
5210: 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28 74 63  , path);..if (tc
5220: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
5230: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
5240: 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61 74  ("::appfs::getat
5250: 74 72 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c  tr(%s) failed.",
5260: 20 70 61 74 68 29 3b 0a 09 09 61 70 70 66 73 5f   path);...appfs_
5270: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
5280: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c  APPFS_DEBUG("Tcl
5290: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20   Error is: %s", 
52a0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
52b0: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
52c0: 29 0a 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  )....pathinfo->t
52d0: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48  ype = APPFS_PATH
52e0: 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58  TYPE_DOES_NOT_EX
52f0: 49 53 54 3b 0a 0a 09 09 61 70 70 66 73 5f 67 65  IST;....appfs_ge
5300: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
5310: 65 5f 61 64 64 28 70 61 74 68 2c 20 66 73 75 69  e_add(path, fsui
5320: 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a 0a 09  d, pathinfo);...
5330: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
5340: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
5350: 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75  nterp);)....retu
5360: 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09 7d 0a  rn(-ENOENT);..}.
5370: 0a 09 69 66 20 28 61 74 74 72 5f 6b 65 79 5f 74  ..if (attr_key_t
5380: 79 70 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ype == NULL) {..
5390: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
53a0: 63 6c 28 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f  cl(....attr_key_
53b0: 74 79 70 65 20 20 20 20 20 20 20 3d 20 54 63 6c  type       = Tcl
53c0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 74  _NewStringObj("t
53d0: 79 70 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74  ype", -1);....at
53e0: 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20 20 20 20  tr_key_perms    
53f0: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e    = Tcl_NewStrin
5400: 67 4f 62 6a 28 22 70 65 72 6d 73 22 2c 20 2d 31  gObj("perms", -1
5410: 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 73  );....attr_key_s
5420: 69 7a 65 20 20 20 20 20 20 20 3d 20 54 63 6c 5f  ize       = Tcl_
5430: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 73 69  NewStringObj("si
5440: 7a 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74  ze", -1);....att
5450: 72 5f 6b 65 79 5f 74 69 6d 65 20 20 20 20 20 20  r_key_time      
5460: 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67   = Tcl_NewString
5470: 4f 62 6a 28 22 74 69 6d 65 22 2c 20 2d 31 29 3b  Obj("time", -1);
5480: 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 73 6f 75  ....attr_key_sou
5490: 72 63 65 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65  rce     = Tcl_Ne
54a0: 77 53 74 72 69 6e 67 4f 62 6a 28 22 73 6f 75 72  wStringObj("sour
54b0: 63 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74  ce", -1);....att
54c0: 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74  r_key_childcount
54d0: 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67   = Tcl_NewString
54e0: 4f 62 6a 28 22 63 68 69 6c 64 63 6f 75 6e 74 22  Obj("childcount"
54f0: 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b  , -1);....attr_k
5500: 65 79 5f 70 61 63 6b 61 67 65 64 20 20 20 3d 20  ey_packaged   = 
5510: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
5520: 28 22 70 61 63 6b 61 67 65 64 22 2c 20 2d 31 29  ("packaged", -1)
5530: 3b 0a 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65  ;.....Tcl_IncrRe
5540: 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f  fCount(attr_key_
5550: 74 79 70 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e  type);....Tcl_In
5560: 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f  crRefCount(attr_
5570: 6b 65 79 5f 70 65 72 6d 73 29 3b 0a 09 09 09 54  key_perms);....T
5580: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
5590: 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 29 3b 0a  attr_key_size);.
55a0: 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f  ...Tcl_IncrRefCo
55b0: 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 74 69 6d  unt(attr_key_tim
55c0: 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52  e);....Tcl_IncrR
55d0: 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79  efCount(attr_key
55e0: 5f 73 6f 75 72 63 65 29 3b 0a 09 09 09 54 63 6c  _source);....Tcl
55f0: 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74  _IncrRefCount(at
5600: 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e  tr_key_childcoun
5610: 74 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52  t);....Tcl_IncrR
5620: 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79  efCount(attr_key
5630: 5f 70 61 63 6b 61 67 65 64 29 3b 0a 09 09 29 0a  _packaged);...).
5640: 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .}...appfs_call_
5650: 6c 69 62 74 63 6c 28 0a 09 09 61 74 74 72 73 5f  libtcl(...attrs_
5660: 64 69 63 74 20 3d 20 54 63 6c 5f 47 65 74 4f 62  dict = Tcl_GetOb
5670: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  jResult(interp);
5680: 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
5690: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
56a0: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
56b0: 61 74 74 72 5f 6b 65 79 5f 74 79 70 65 2c 20 26  attr_key_type, &
56c0: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 29 0a  attr_value);..).
56d0: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
56e0: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
56f0: 53 5f 44 45 42 55 47 28 22 5b 64 69 63 74 20 67  S_DEBUG("[dict g
5700: 65 74 20 5c 22 74 79 70 65 5c 22 5d 20 66 61 69  et \"type\"] fai
5710: 6c 65 64 22 29 3b 0a 09 09 61 70 70 66 73 5f 63  led");...appfs_c
5720: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41  all_libtcl(....A
5730: 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20  PPFS_DEBUG("Tcl 
5740: 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54  Error is: %s", T
5750: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
5760: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29  lt(interp));...)
5770: 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
5780: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
5790: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72  e(interp);)....r
57a0: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
57b0: 0a 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65  ..if (attr_value
57c0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50   == NULL) {...AP
57d0: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
57e0: 3a 20 55 6e 61 62 6c 65 20 74 6f 20 67 65 74 20  : Unable to get 
57f0: 74 79 70 65 20 66 6f 72 20 5c 22 25 73 5c 22 20  type for \"%s\" 
5800: 66 72 6f 6d 20 54 63 6c 22 2c 20 70 61 74 68 29  from Tcl", path)
5810: 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  ;....appfs_call_
5820: 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61  libtcl(Tcl_Relea
5830: 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09  se(interp);)....
5840: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
5850: 0a 0a 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63  ...pathinfo->pac
5860: 6b 61 67 65 64 20 3d 20 30 3b 0a 0a 09 61 70 70  kaged = 0;...app
5870: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
5880: 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72  ..attr_value_str
5890: 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67   = Tcl_GetString
58a0: 28 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 0a 09  (attr_value);...
58b0: 09 73 77 69 74 63 68 20 28 61 74 74 72 5f 76 61  .switch (attr_va
58c0: 6c 75 65 5f 73 74 72 5b 30 5d 29 20 7b 0a 09 09  lue_str[0]) {...
58d0: 09 63 61 73 65 20 27 64 27 3a 20 2f 2a 20 64 69  .case 'd': /* di
58e0: 72 65 63 74 6f 72 79 20 2a 2f 0a 09 09 09 09 70  rectory */.....p
58f0: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20  athinfo->type = 
5900: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44  APPFS_PATHTYPE_D
5910: 49 52 45 43 54 4f 52 59 3b 0a 09 09 09 09 70 61  IRECTORY;.....pa
5920: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
5930: 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20  .dir.childcount 
5940: 3d 20 30 3b 0a 0a 09 09 09 09 54 63 6c 5f 44 69  = 0;......Tcl_Di
5950: 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c  ctObjGet(interp,
5960: 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74   attrs_dict, att
5970: 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74  r_key_childcount
5980: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a  , &attr_value);.
5990: 09 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c  ....if (attr_val
59a0: 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  ue != NULL) {...
59b0: 09 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
59c0: 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f  _GetWideIntFromO
59d0: 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61  bj(NULL, attr_va
59e0: 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  lue, &attr_value
59f0: 5f 77 69 64 65 29 3b 0a 09 09 09 09 09 69 66 20  _wide);......if 
5a00: 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f  (tcl_ret == TCL_
5a10: 4f 4b 29 20 7b 0a 09 09 09 09 09 09 70 61 74 68  OK) {.......path
5a20: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64  info->typeinfo.d
5a30: 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20  ir.childcount = 
5a40: 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b  attr_value_wide;
5a50: 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a 09  ......}.....}...
5a60: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73  ...break;....cas
5a70: 65 20 27 66 27 3a 20 2f 2a 20 66 69 6c 65 20 2a  e 'f': /* file *
5a80: 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  /.....pathinfo->
5a90: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
5aa0: 48 54 59 50 45 5f 46 49 4c 45 3b 0a 09 09 09 09  HTYPE_FILE;.....
5ab0: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
5ac0: 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 3d 20 30  fo.file.size = 0
5ad0: 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  ;.....pathinfo->
5ae0: 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 65 78  typeinfo.file.ex
5af0: 65 63 75 74 61 62 6c 65 20 3d 20 30 3b 0a 09 09  ecutable = 0;...
5b00: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
5b10: 69 6e 66 6f 2e 66 69 6c 65 2e 73 75 69 64 52 6f  info.file.suidRo
5b20: 6f 74 20 3d 20 30 3b 0a 09 09 09 09 70 61 74 68  ot = 0;.....path
5b30: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66  info->typeinfo.f
5b40: 69 6c 65 2e 77 6f 72 6c 64 61 63 63 65 73 73 69  ile.worldaccessi
5b50: 62 6c 65 20 3d 20 30 3b 0a 0a 09 09 09 09 54 63  ble = 0;......Tc
5b60: 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74  l_DictObjGet(int
5b70: 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c  erp, attrs_dict,
5b80: 20 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 2c 20   attr_key_size, 
5b90: 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09  &attr_value);...
5ba0: 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65  ..if (attr_value
5bb0: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09   != NULL) {.....
5bc0: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47  .tcl_ret = Tcl_G
5bd0: 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a  etWideIntFromObj
5be0: 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75  (NULL, attr_valu
5bf0: 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77  e, &attr_value_w
5c00: 69 64 65 29 3b 0a 09 09 09 09 09 69 66 20 28 74  ide);......if (t
5c10: 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b  cl_ret == TCL_OK
5c20: 29 20 7b 0a 09 09 09 09 09 09 70 61 74 68 69 6e  ) {.......pathin
5c30: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  fo->typeinfo.fil
5c40: 65 2e 73 69 7a 65 20 3d 20 61 74 74 72 5f 76 61  e.size = attr_va
5c50: 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09 09 09 7d  lue_wide;......}
5c60: 0a 09 09 09 09 7d 0a 0a 09 09 09 09 54 63 6c 5f  .....}......Tcl_
5c70: 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72  DictObjGet(inter
5c80: 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61  p, attrs_dict, a
5c90: 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 2c 20 26  ttr_key_perms, &
5ca0: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09  attr_value);....
5cb0: 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20  .if (attr_value 
5cc0: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 09  != NULL) {......
5cd0: 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 20 3d  attr_value_str =
5ce0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 61   Tcl_GetString(a
5cf0: 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09  ttr_value);.....
5d00: 09 66 6f 72 20 28 61 74 74 72 5f 76 61 6c 75 65  .for (attr_value
5d10: 5f 73 74 72 5f 69 20 3d 20 26 61 74 74 72 5f 76  _str_i = &attr_v
5d20: 61 6c 75 65 5f 73 74 72 5b 30 5d 3b 20 2a 61 74  alue_str[0]; *at
5d30: 74 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 20 21  tr_value_str_i !
5d40: 3d 20 27 5c 30 27 3b 20 61 74 74 72 5f 76 61 6c  = '\0'; attr_val
5d50: 75 65 5f 73 74 72 5f 69 2b 2b 29 20 7b 0a 09 09  ue_str_i++) {...
5d60: 09 09 09 09 73 77 69 74 63 68 20 28 2a 61 74 74  ....switch (*att
5d70: 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 29 20 7b  r_value_str_i) {
5d80: 0a 09 09 09 09 09 09 09 63 61 73 65 20 27 78 27  ........case 'x'
5d90: 3a 0a 09 09 09 09 09 09 09 09 70 61 74 68 69 6e  :.........pathin
5da0: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  fo->typeinfo.fil
5db0: 65 2e 65 78 65 63 75 74 61 62 6c 65 20 3d 20 31  e.executable = 1
5dc0: 3b 0a 0a 09 09 09 09 09 09 09 09 62 72 65 61 6b  ;..........break
5dd0: 3b 0a 09 09 09 09 09 09 09 63 61 73 65 20 27 55  ;........case 'U
5de0: 27 3a 0a 09 09 09 09 09 09 09 09 70 61 74 68 69  ':.........pathi
5df0: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69  nfo->typeinfo.fi
5e00: 6c 65 2e 73 75 69 64 52 6f 6f 74 20 3d 20 31 3b  le.suidRoot = 1;
5e10: 0a 0a 09 09 09 09 09 09 09 09 62 72 65 61 6b 3b  ..........break;
5e20: 0a 09 09 09 09 09 09 09 63 61 73 65 20 27 2d 27  ........case '-'
5e30: 3a 0a 09 09 09 09 09 09 09 09 70 61 74 68 69 6e  :.........pathin
5e40: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  fo->typeinfo.fil
5e50: 65 2e 77 6f 72 6c 64 61 63 63 65 73 73 69 62 6c  e.worldaccessibl
5e60: 65 20 3d 20 31 3b 0a 0a 09 09 09 09 09 09 09 09  e = 1;..........
5e70: 62 72 65 61 6b 3b 0a 09 09 09 09 09 09 7d 0a 09  break;.......}..
5e80: 09 09 09 09 7d 0a 09 09 09 09 7d 0a 09 09 09 09  ....}.....}.....
5e90: 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27  break;....case '
5ea0: 73 27 3a 20 2f 2a 20 73 79 6d 6c 69 6e 6b 20 2a  s': /* symlink *
5eb0: 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  /.....pathinfo->
5ec0: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
5ed0: 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3b 0a 09  HTYPE_SYMLINK;..
5ee0: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
5ef0: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69  einfo.symlink.si
5f00: 7a 65 20 3d 20 30 3b 0a 09 09 09 09 70 61 74 68  ze = 0;.....path
5f10: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73  info->typeinfo.s
5f20: 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b 30 5d  ymlink.source[0]
5f30: 20 3d 20 27 5c 30 27 3b 0a 0a 09 09 09 09 54 63   = '\0';......Tc
5f40: 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74  l_DictObjGet(int
5f50: 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c  erp, attrs_dict,
5f60: 20 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65   attr_key_source
5f70: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a  , &attr_value);.
5f80: 09 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c  ....if (attr_val
5f90: 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  ue != NULL) {...
5fa0: 09 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73 74  ...attr_value_st
5fb0: 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  r = Tcl_GetStrin
5fc0: 67 46 72 6f 6d 4f 62 6a 28 61 74 74 72 5f 76 61  gFromObj(attr_va
5fd0: 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  lue, &attr_value
5fe0: 5f 69 6e 74 29 3b 20 0a 0a 09 09 09 09 09 69 66  _int); .......if
5ff0: 20 28 28 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e   ((attr_value_in
6000: 74 20 2b 20 31 29 20 3c 3d 20 73 69 7a 65 6f 66  t + 1) <= sizeof
6010: 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  (pathinfo->typei
6020: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72  nfo.symlink.sour
6030: 63 65 29 29 20 7b 0a 09 09 09 09 09 09 70 61 74  ce)) {.......pat
6040: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
6050: 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20 61  symlink.size = a
6060: 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a 09  ttr_value_int;..
6070: 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
6080: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e  ypeinfo.symlink.
6090: 73 6f 75 72 63 65 5b 61 74 74 72 5f 76 61 6c 75  source[attr_valu
60a0: 65 5f 69 6e 74 5d 20 3d 20 27 5c 30 27 3b 0a 0a  e_int] = '\0';..
60b0: 09 09 09 09 09 09 6d 65 6d 63 70 79 28 70 61 74  ......memcpy(pat
60c0: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
60d0: 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c 20  symlink.source, 
60e0: 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 2c 20  attr_value_str, 
60f0: 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b  attr_value_int);
6100: 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 09 09  ......}.....}...
6110: 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65  ..break;....case
6120: 20 27 46 27 3a 20 2f 2a 20 70 69 70 65 2f 66 69   'F': /* pipe/fi
6130: 66 6f 20 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e  fo */.....pathin
6140: 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53  fo->type = APPFS
6150: 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3b 0a  _PATHTYPE_FIFO;.
6160: 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61  ....break;....ca
6170: 73 65 20 27 53 27 3a 20 2f 2a 20 55 4e 49 58 20  se 'S': /* UNIX 
6180: 64 6f 6d 61 69 6e 20 73 6f 63 6b 65 74 20 2a 2f  domain socket */
6190: 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
61a0: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48  ype = APPFS_PATH
61b0: 54 59 50 45 5f 53 4f 43 4b 45 54 3b 0a 09 09 09  TYPE_SOCKET;....
61c0: 09 62 72 65 61 6b 3b 0a 09 09 09 64 65 66 61 75  .break;....defau
61d0: 6c 74 3a 0a 09 09 09 09 72 65 74 76 61 6c 20 3d  lt:.....retval =
61e0: 20 2d 45 49 4f 3b 0a 09 09 7d 0a 0a 09 09 54 63   -EIO;...}....Tc
61f0: 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74  l_DictObjGet(int
6200: 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c  erp, attrs_dict,
6210: 20 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67   attr_key_packag
6220: 65 64 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29  ed, &attr_value)
6230: 3b 0a 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c  ;...if (attr_val
6240: 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  ue != NULL) {...
6250: 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61  .pathinfo->packa
6260: 67 65 64 20 3d 20 31 3b 0a 09 09 7d 0a 0a 09 09  ged = 1;...}....
6270: 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69  Tcl_DictObjGet(i
6280: 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63  nterp, attrs_dic
6290: 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65  t, attr_key_time
62a0: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a  , &attr_value);.
62b0: 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65  ..if (attr_value
62c0: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 74   != NULL) {....t
62d0: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74  cl_ret = Tcl_Get
62e0: 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e  WideIntFromObj(N
62f0: 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c  ULL, attr_value,
6300: 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64   &attr_value_wid
6310: 65 29 3b 0a 09 09 09 69 66 20 28 74 63 6c 5f 72  e);....if (tcl_r
6320: 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et == TCL_OK) {.
6330: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 69  ....pathinfo->ti
6340: 6d 65 20 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f  me = attr_value_
6350: 77 69 64 65 3b 0a 09 09 09 7d 0a 09 09 7d 20 65  wide;....}...} e
6360: 6c 73 65 20 7b 0a 09 09 09 70 61 74 68 69 6e 66  lse {....pathinf
6370: 6f 2d 3e 74 69 6d 65 20 3d 20 61 70 70 66 73 5f  o->time = appfs_
6380: 62 6f 6f 74 74 69 6d 65 3b 0a 09 09 7d 0a 0a 09  boottime;...}...
6390: 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  .Tcl_Release(int
63a0: 65 72 70 29 3b 0a 09 29 0a 0a 09 69 66 20 28 70  erp);..)...if (p
63b0: 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67 65  athinfo->package
63c0: 64 29 20 7b 0a 09 09 70 61 74 68 69 6e 66 6f 2d  d) {...pathinfo-
63d0: 3e 69 6e 6f 64 65 20 3d 20 61 70 70 66 73 5f 67  >inode = appfs_g
63e0: 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61  et_path_inode(pa
63f0: 74 68 2c 20 2d 31 29 3b 0a 09 7d 20 65 6c 73 65  th, -1);..} else
6400: 20 7b 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e 69   {...pathinfo->i
6410: 6e 6f 64 65 20 3d 20 61 70 70 66 73 5f 67 65 74  node = appfs_get
6420: 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74 68  _path_inode(path
6430: 2c 20 66 73 75 69 64 29 3b 0a 09 7d 0a 0a 09 41  , fsuid);..}...A
6440: 50 50 46 53 5f 44 45 42 55 47 28 22 43 61 63 68  PPFS_DEBUG("Cach
6450: 69 6e 67 20 69 6e 6f 64 65 20 66 6f 72 20 70 61  ing inode for pa
6460: 74 68 3d 25 73 2c 75 69 64 3d 25 6c 6c 69 20 61  th=%s,uid=%lli a
6470: 73 20 25 6c 6c 75 20 28 70 61 63 6b 61 67 65 64  s %llu (packaged
6480: 20 3d 20 25 69 29 22 2c 20 70 61 74 68 2c 20 28   = %i)", path, (
6490: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64  long long) fsuid
64a0: 2c 20 70 61 74 68 69 6e 66 6f 2d 3e 69 6e 6f 64  , pathinfo->inod
64b0: 65 2c 20 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63  e, pathinfo->pac
64c0: 6b 61 67 65 64 29 3b 0a 0a 09 69 66 20 28 72 65  kaged);...if (re
64d0: 74 76 61 6c 20 3d 3d 20 30 29 20 7b 0a 09 09 61  tval == 0) {...a
64e0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
64f0: 66 6f 5f 63 61 63 68 65 5f 61 64 64 28 70 61 74  fo_cache_add(pat
6500: 68 2c 20 66 73 75 69 64 2c 20 70 61 74 68 69 6e  h, fsuid, pathin
6510: 66 6f 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09  fo);..} else {..
6520: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72  .APPFS_DEBUG("er
6530: 72 6f 72 3a 20 49 6e 76 61 6c 69 64 20 74 79 70  ror: Invalid typ
6540: 65 20 66 6f 72 20 5c 22 25 73 5c 22 20 66 72 6f  e for \"%s\" fro
6550: 6d 20 54 63 6c 22 2c 20 70 61 74 68 29 3b 0a 09  m Tcl", path);..
6560: 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61  }...return(retva
6570: 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68  l);.}..static ch
6580: 61 72 20 2a 61 70 70 66 73 5f 70 72 65 70 61 72  ar *appfs_prepar
6590: 65 5f 74 6f 5f 63 72 65 61 74 65 28 63 6f 6e 73  e_to_create(cons
65a0: 74 20 63 68 61 72 20 2a 70 61 74 68 29 20 7b 0a  t char *path) {.
65b0: 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  .Tcl_Interp *int
65c0: 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72  erp;..const char
65d0: 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e   *real_path;..in
65e0: 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 61 70 70  t tcl_ret;...app
65f0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
6600: 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70  _cache_flush(app
6610: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20  fs_get_fsuid(), 
6620: 2d 31 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20  -1);...interp = 
6630: 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28  appfs_TclInterp(
6640: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  );..if (interp =
6650: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
6660: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61  rn(NULL);..}...a
6670: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
6680: 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e  (Tcl_Preserve(in
6690: 74 65 72 70 29 3b 29 0a 0a 09 61 70 70 66 73 5f  terp);)...appfs_
66a0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74  call_libtcl(...t
66b0: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
66c0: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
66d0: 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65  2, "::appfs::pre
66e0: 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 22 2c  pare_to_create",
66f0: 20 70 61 74 68 29 3b 0a 09 29 0a 09 69 66 20 28   path);..)..if (
6700: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
6710: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
6720: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65  UG("::appfs::pre
6730: 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 25  pare_to_create(%
6740: 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  s) failed.", pat
6750: 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  h);...appfs_call
6760: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46  _libtcl(....APPF
6770: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72  S_DEBUG("Tcl Err
6780: 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f  or is: %s", Tcl_
6790: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
67a0: 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09  interp));...)...
67b0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
67c0: 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  cl(Tcl_Release(i
67d0: 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75  nterp);)....retu
67e0: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61  rn(NULL);..}...a
67f0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
6800: 28 0a 09 09 72 65 61 6c 5f 70 61 74 68 20 3d 20  (...real_path = 
6810: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
6820: 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a  ult(interp);..).
6830: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
6840: 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28  tcl(Tcl_Release(
6850: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 69 66 20 28  interp);)...if (
6860: 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c  real_path == NUL
6870: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55  L) {...return(NU
6880: 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  LL);..}...return
6890: 28 73 74 72 64 75 70 28 72 65 61 6c 5f 70 61 74  (strdup(real_pat
68a0: 68 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63  h));.}..static c
68b0: 68 61 72 20 2a 61 70 70 66 73 5f 6c 6f 63 61 6c  har *appfs_local
68c0: 70 61 74 68 28 63 6f 6e 73 74 20 63 68 61 72 20  path(const char 
68d0: 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e  *path) {..Tcl_In
68e0: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63  terp *interp;..c
68f0: 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f  onst char *real_
6900: 70 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72  path;..int tcl_r
6910: 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61  et;...interp = a
6920: 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29  ppfs_TclInterp()
6930: 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ;..if (interp ==
6940: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
6950: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70  n(NULL);..}...ap
6960: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
6970: 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74  Tcl_Preserve(int
6980: 65 72 70 29 3b 29 0a 0a 09 61 70 70 66 73 5f 63  erp);)...appfs_c
6990: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63  all_libtcl(...tc
69a0: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
69b0: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32  l_Eval(interp, 2
69c0: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63 61  , "::appfs::loca
69d0: 6c 70 61 74 68 22 2c 20 70 61 74 68 29 3b 0a 09  lpath", path);..
69e0: 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  )..if (tcl_ret !
69f0: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50  = TCL_OK) {...AP
6a00: 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70  PFS_DEBUG("::app
6a10: 66 73 3a 3a 6c 6f 63 61 6c 70 61 74 68 28 25 73  fs::localpath(%s
6a20: 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68  ) failed.", path
6a30: 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  );...appfs_call_
6a40: 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53  libtcl(....APPFS
6a50: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
6a60: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
6a70: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
6a80: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
6a90: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
6aa0: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
6ab0: 62 74 63 6c 28 0a 09 09 72 65 61 6c 5f 70 61 74  btcl(...real_pat
6ac0: 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  h = Tcl_GetStrin
6ad0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  gResult(interp);
6ae0: 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..)...appfs_call
6af0: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
6b00: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
6b10: 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d  if (real_path ==
6b20: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
6b30: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65  n(NULL);..}...re
6b40: 74 75 72 6e 28 73 74 72 64 75 70 28 72 65 61 6c  turn(strdup(real
6b50: 5f 70 61 74 68 29 29 3b 0a 7d 0a 0a 23 69 66 20  _path));.}..#if 
6b60: 28 64 65 66 69 6e 65 64 28 44 45 42 55 47 29 20  (defined(DEBUG) 
6b70: 26 26 20 64 65 66 69 6e 65 64 28 41 50 50 46 53  && defined(APPFS
6b80: 5f 45 58 49 54 5f 50 41 54 48 29 29 20 7c 7c 20  _EXIT_PATH)) || 
6b90: 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58  defined(APPFS_EX
6ba0: 49 54 5f 50 41 54 48 5f 45 4e 41 42 4c 45 5f 4d  IT_PATH_ENABLE_M
6bb0: 41 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f 48 4f  AJOR_SECURITY_HO
6bc0: 4c 45 29 0a 73 74 61 74 69 63 20 76 6f 69 64 20  LE).static void 
6bd0: 61 70 70 66 73 5f 65 78 69 74 28 76 6f 69 64 29  appfs_exit(void)
6be0: 20 7b 0a 09 69 6e 74 20 67 6c 6f 62 61 6c 5f 69   {..int global_i
6bf0: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 3b  nterp_reset_key;
6c00: 0a 0a 09 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70  ...global_interp
6c10: 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 5f 5f 73  _reset_key = __s
6c20: 79 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 61 64  ync_fetch_and_ad
6c30: 64 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  d(&interp_reset_
6c40: 6b 65 79 2c 20 30 29 3b 0a 09 5f 5f 73 79 6e 63  key, 0);..__sync
6c50: 5f 66 65 74 63 68 5f 61 6e 64 5f 73 75 62 28 26  _fetch_and_sub(&
6c60: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
6c70: 2c 20 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f  , global_interp_
6c80: 72 65 73 65 74 5f 6b 65 79 29 3b 0a 0a 09 77 68  reset_key);...wh
6c90: 69 6c 65 20 28 5f 5f 73 79 6e 63 5f 73 75 62 5f  ile (__sync_sub_
6ca0: 61 6e 64 5f 66 65 74 63 68 28 26 69 6e 74 65 72  and_fetch(&inter
6cb0: 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 31 29 20  p_reset_key, 1) 
6cc0: 3e 3d 20 30 29 20 7b 0a 09 09 2f 2a 20 42 75 73  >= 0) {.../* Bus
6cd0: 79 20 4c 6f 6f 70 20 2a 2f 0a 09 7d 0a 0a 09 67  y Loop */..}...g
6ce0: 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73  lobal_interp_res
6cf0: 65 74 5f 6b 65 79 20 3d 20 5f 5f 73 79 6e 63 5f  et_key = __sync_
6d00: 66 65 74 63 68 5f 61 6e 64 5f 61 64 64 28 26 69  fetch_and_add(&i
6d10: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c  nterp_reset_key,
6d20: 20 30 29 3b 0a 09 69 66 20 28 67 6c 6f 62 61 6c   0);..if (global
6d30: 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65  _interp_reset_ke
6d40: 79 20 21 3d 20 2d 31 29 20 7b 0a 09 09 41 50 50  y != -1) {...APP
6d50: 46 53 5f 44 45 42 55 47 28 22 45 72 72 6f 72 20  FS_DEBUG("Error 
6d60: 73 65 6e 64 69 6e 67 20 6b 69 6c 6c 20 73 69 67  sending kill sig
6d70: 6e 61 6c 20 74 6f 20 61 6c 6c 20 74 68 72 65 61  nal to all threa
6d80: 64 73 2c 20 61 62 6f 72 74 69 6e 67 20 61 6e 79  ds, aborting any
6d90: 77 61 79 2e 22 29 3b 0a 09 7d 0a 0a 09 61 70 70  way.");..}...app
6da0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
6db0: 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c  _cache_flush(-1,
6dc0: 20 2d 31 29 3b 0a 0a 09 66 75 73 65 5f 65 78 69   -1);...fuse_exi
6dd0: 74 28 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65  t(fuse_get_conte
6de0: 78 74 28 29 2d 3e 66 75 73 65 29 3b 0a 0a 09 72  xt()->fuse);...r
6df0: 65 74 75 72 6e 3b 0a 7d 0a 23 65 6e 64 69 66 0a  eturn;.}.#endif.
6e00: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
6e10: 73 5f 66 75 73 65 5f 72 65 61 64 6c 69 6e 6b 28  s_fuse_readlink(
6e20: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
6e30: 2c 20 63 68 61 72 20 2a 62 75 66 2c 20 73 69 7a  , char *buf, siz
6e40: 65 5f 74 20 73 69 7a 65 29 20 7b 0a 09 73 74 72  e_t size) {..str
6e50: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e  uct appfs_pathin
6e60: 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69 6e  fo pathinfo;..in
6e70: 74 20 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09  t retval = 0;...
6e80: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
6e90: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
6ea0: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 70  ..)", path);...p
6eb0: 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41  athinfo.type = A
6ec0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e  PPFS_PATHTYPE_IN
6ed0: 56 41 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20  VALID;...retval 
6ee0: 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  = appfs_get_path
6ef0: 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74  _info(path, &pat
6f00: 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65 74  hinfo);..if (ret
6f10: 76 61 6c 20 21 3d 20 30 29 20 7b 0a 09 09 72 65  val != 0) {...re
6f20: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d  turn(retval);..}
6f30: 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e  ...if (pathinfo.
6f40: 74 79 70 65 20 21 3d 20 41 50 50 46 53 5f 50 41  type != APPFS_PA
6f50: 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 29 20  THTYPE_SYMLINK) 
6f60: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4e 56  {...return(-EINV
6f70: 41 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 73  AL);..}...if ((s
6f80: 74 72 6c 65 6e 28 70 61 74 68 69 6e 66 6f 2e 74  trlen(pathinfo.t
6f90: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e  ypeinfo.symlink.
6fa0: 73 6f 75 72 63 65 29 20 2b 20 31 29 20 3e 20 73  source) + 1) > s
6fb0: 69 7a 65 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ize) {...return(
6fc0: 2d 45 4e 41 4d 45 54 4f 4f 4c 4f 4e 47 29 3b 0a  -ENAMETOOLONG);.
6fd0: 09 7d 0a 0a 09 6d 65 6d 63 70 79 28 62 75 66 2c  .}...memcpy(buf,
6fe0: 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e   pathinfo.typein
6ff0: 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63  fo.symlink.sourc
7000: 65 2c 20 73 74 72 6c 65 6e 28 70 61 74 68 69 6e  e, strlen(pathin
7010: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c  fo.typeinfo.syml
7020: 69 6e 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31 29  ink.source) + 1)
7030: 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  ;...return(0);.}
7040: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
7050: 66 73 5f 66 75 73 65 5f 67 65 74 61 74 74 72 28  fs_fuse_getattr(
7060: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
7070: 2c 20 73 74 72 75 63 74 20 73 74 61 74 20 2a 73  , struct stat *s
7080: 74 62 75 66 29 20 7b 0a 09 73 74 72 75 63 74 20  tbuf) {..struct 
7090: 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70  appfs_pathinfo p
70a0: 61 74 68 69 6e 66 6f 3b 0a 09 69 6e 74 20 63 68  athinfo;..int ch
70b0: 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65 72 49  angeOwnerToUserI
70c0: 66 50 61 63 6b 61 67 65 64 3b 0a 09 69 6e 74 20  fPackaged;..int 
70d0: 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c  retval;...retval
70e0: 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45   = 0;...APPFS_DE
70f0: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
7100: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
7110: 74 68 29 3b 0a 0a 23 69 66 20 28 64 65 66 69 6e  th);..#if (defin
7120: 65 64 28 44 45 42 55 47 29 20 26 26 20 64 65 66  ed(DEBUG) && def
7130: 69 6e 65 64 28 41 50 50 46 53 5f 45 58 49 54 5f  ined(APPFS_EXIT_
7140: 50 41 54 48 29 29 20 7c 7c 20 64 65 66 69 6e 65  PATH)) || define
7150: 64 28 41 50 50 46 53 5f 45 58 49 54 5f 50 41 54  d(APPFS_EXIT_PAT
7160: 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f 53  H_ENABLE_MAJOR_S
7170: 45 43 55 52 49 54 59 5f 48 4f 4c 45 29 0a 09 2f  ECURITY_HOLE)../
7180: 2a 0a 09 20 2a 20 54 68 69 73 20 69 73 20 61 20  *.. * This is a 
7190: 6d 61 6a 6f 72 20 73 65 63 75 72 69 74 79 20 69  major security i
71a0: 73 73 75 65 20 73 6f 20 77 65 20 63 61 6e 6e 6f  ssue so we canno
71b0: 74 20 6c 65 74 20 69 74 20 62 65 20 63 6f 6d 70  t let it be comp
71c0: 69 6c 65 64 20 69 6e 74 6f 0a 09 20 2a 20 61 6e  iled into.. * an
71d0: 79 20 72 65 6c 65 61 73 65 0a 09 20 2a 2f 0a 0a  y release.. */..
71e0: 09 69 66 20 28 73 74 72 63 6d 70 28 70 61 74 68  .if (strcmp(path
71f0: 2c 20 22 2f 65 78 69 74 22 29 20 3d 3d 20 30 29  , "/exit") == 0)
7200: 20 7b 0a 09 09 61 70 70 66 73 5f 65 78 69 74 28   {...appfs_exit(
7210: 29 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 70  );..}.#endif...p
7220: 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41  athinfo.type = A
7230: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e  PPFS_PATHTYPE_IN
7240: 56 41 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20  VALID;...retval 
7250: 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  = appfs_get_path
7260: 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74  _info(path, &pat
7270: 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65 74  hinfo);..if (ret
7280: 76 61 6c 20 21 3d 20 30 29 20 7b 0a 09 09 69 66  val != 0) {...if
7290: 20 28 72 65 74 76 61 6c 20 3d 3d 20 2d 45 4e 4f   (retval == -ENO
72a0: 45 4e 54 29 20 7b 0a 09 09 09 41 50 50 46 53 5f  ENT) {....APPFS_
72b0: 44 45 42 55 47 28 22 67 65 74 5f 70 61 74 68 5f  DEBUG("get_path_
72c0: 69 6e 66 6f 20 72 65 74 75 72 6e 65 64 20 45 4e  info returned EN
72d0: 4f 45 4e 54 2c 20 72 65 74 75 72 6e 69 6e 67 20  OENT, returning 
72e0: 69 74 20 61 73 20 77 65 6c 6c 2e 22 29 3b 0a 09  it as well.");..
72f0: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 41 50 50  .} else {....APP
7300: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
7310: 20 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20 66   get_path_info f
7320: 61 69 6c 65 64 22 29 3b 0a 09 09 7d 0a 0a 09 09  ailed");...}....
7330: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a  return(retval);.
7340: 09 7d 0a 0a 09 6d 65 6d 73 65 74 28 73 74 62 75  .}...memset(stbu
7350: 66 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73 74 72  f, 0, sizeof(str
7360: 75 63 74 20 73 74 61 74 29 29 3b 0a 0a 09 73 74  uct stat));...st
7370: 62 75 66 2d 3e 73 74 5f 6d 74 69 6d 65 20 3d 20  buf->st_mtime = 
7380: 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09  pathinfo.time;..
7390: 73 74 62 75 66 2d 3e 73 74 5f 63 74 69 6d 65 20  stbuf->st_ctime 
73a0: 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b  = pathinfo.time;
73b0: 0a 09 73 74 62 75 66 2d 3e 73 74 5f 61 74 69 6d  ..stbuf->st_atim
73c0: 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d  e = pathinfo.tim
73d0: 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 69 6e  e;..stbuf->st_in
73e0: 6f 20 20 20 3d 20 70 61 74 68 69 6e 66 6f 2e 69  o   = pathinfo.i
73f0: 6e 6f 64 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74  node;..stbuf->st
7400: 5f 6d 6f 64 65 20 20 3d 20 30 3b 0a 0a 09 63 68  _mode  = 0;...ch
7410: 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65 72 49  angeOwnerToUserI
7420: 66 50 61 63 6b 61 67 65 64 20 3d 20 31 3b 0a 0a  fPackaged = 1;..
7430: 09 73 77 69 74 63 68 20 28 70 61 74 68 69 6e 66  .switch (pathinf
7440: 6f 2e 74 79 70 65 29 20 7b 0a 09 09 63 61 73 65  o.type) {...case
7450: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
7460: 44 49 52 45 43 54 4f 52 59 3a 0a 09 09 09 73 74  DIRECTORY:....st
7470: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53  buf->st_mode = S
7480: 5f 49 46 44 49 52 20 7c 20 30 35 35 35 3b 0a 09  _IFDIR | 0555;..
7490: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e  ..stbuf->st_nlin
74a0: 6b 20 3d 20 32 20 2b 20 70 61 74 68 69 6e 66 6f  k = 2 + pathinfo
74b0: 2e 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68  .typeinfo.dir.ch
74c0: 69 6c 64 63 6f 75 6e 74 3b 0a 09 09 09 62 72 65  ildcount;....bre
74d0: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53  ak;...case APPFS
74e0: 5f 50 41 54 48 54 59 50 45 5f 46 49 4c 45 3a 0a  _PATHTYPE_FILE:.
74f0: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ...stbuf->st_mod
7500: 65 20 3d 20 53 5f 49 46 52 45 47 20 7c 20 30 34  e = S_IFREG | 04
7510: 34 34 3b 0a 0a 09 09 09 69 66 20 28 70 61 74 68  44;.....if (path
7520: 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69  info.typeinfo.fi
7530: 6c 65 2e 65 78 65 63 75 74 61 62 6c 65 29 20 7b  le.executable) {
7540: 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d  .....stbuf->st_m
7550: 6f 64 65 20 7c 3d 20 30 31 31 31 3b 0a 09 09 09  ode |= 0111;....
7560: 7d 0a 0a 09 09 09 69 66 20 28 70 61 74 68 69 6e  }.....if (pathin
7570: 66 6f 2e 70 61 63 6b 61 67 65 64 29 20 7b 0a 09  fo.packaged) {..
7580: 09 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e  ...if (pathinfo.
7590: 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 75  typeinfo.file.su
75a0: 69 64 52 6f 6f 74 29 20 7b 0a 09 09 09 09 09 63  idRoot) {......c
75b0: 68 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65 72  hangeOwnerToUser
75c0: 49 66 50 61 63 6b 61 67 65 64 20 3d 20 30 3b 0a  IfPackaged = 0;.
75d0: 0a 09 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  ......stbuf->st_
75e0: 6d 6f 64 65 20 7c 3d 20 30 34 30 30 30 3b 0a 09  mode |= 04000;..
75f0: 09 09 09 7d 0a 09 09 09 7d 0a 0a 09 09 09 69 66  ...}....}.....if
7600: 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69   (pathinfo.typei
7610: 6e 66 6f 2e 66 69 6c 65 2e 77 6f 72 6c 64 61 63  nfo.file.worldac
7620: 63 65 73 73 69 62 6c 65 29 20 7b 0a 09 09 09 09  cessible) {.....
7630: 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 26  stbuf->st_mode &
7640: 3d 20 7e 30 37 37 3b 0a 09 09 09 7d 0a 0a 09 09  = ~077;....}....
7650: 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b  .stbuf->st_nlink
7660: 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e   = 1;....stbuf->
7670: 73 74 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e  st_size = pathin
7680: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  fo.typeinfo.file
7690: 2e 73 69 7a 65 3b 0a 0a 09 09 09 62 72 65 61 6b  .size;.....break
76a0: 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50  ;...case APPFS_P
76b0: 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3a  ATHTYPE_SYMLINK:
76c0: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
76d0: 64 65 20 3d 20 53 5f 49 46 4c 4e 4b 20 7c 20 30  de = S_IFLNK | 0
76e0: 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  555;....stbuf->s
76f0: 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09  t_nlink = 1;....
7700: 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d  stbuf->st_size =
7710: 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e   pathinfo.typein
7720: 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 3b  fo.symlink.size;
7730: 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73  ....break;...cas
7740: 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  e APPFS_PATHTYPE
7750: 5f 53 4f 43 4b 45 54 3a 0a 09 09 09 73 74 62 75  _SOCKET:....stbu
7760: 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49  f->st_mode = S_I
7770: 46 53 4f 43 4b 20 7c 20 30 35 35 35 3b 0a 09 09  FSOCK | 0555;...
7780: 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b  .stbuf->st_nlink
7790: 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e   = 1;....stbuf->
77a0: 73 74 5f 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09  st_size = 0;....
77b0: 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50  break;...case AP
77c0: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49 46  PFS_PATHTYPE_FIF
77d0: 4f 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  O:....stbuf->st_
77e0: 6d 6f 64 65 20 3d 20 53 5f 49 46 49 46 4f 20 7c  mode = S_IFIFO |
77f0: 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d   0555;....stbuf-
7800: 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09  >st_nlink = 1;..
7810: 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65  ..stbuf->st_size
7820: 20 3d 20 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a   = 0;....break;.
7830: 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54  ..case APPFS_PAT
7840: 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45  HTYPE_DOES_NOT_E
7850: 58 49 53 54 3a 0a 09 09 09 72 65 74 76 61 6c 20  XIST:....retval 
7860: 3d 20 2d 45 4e 4f 45 4e 54 3b 0a 0a 09 09 09 62  = -ENOENT;.....b
7870: 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50  reak;...case APP
7880: 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41  FS_PATHTYPE_INVA
7890: 4c 49 44 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d  LID:....retval =
78a0: 20 2d 45 49 4f 3b 0a 0a 09 09 09 62 72 65 61 6b   -EIO;.....break
78b0: 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 70 61 74 68  ;..}...if ((path
78c0: 69 6e 66 6f 2e 70 61 63 6b 61 67 65 64 20 26 26  info.packaged &&
78d0: 20 63 68 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73   changeOwnerToUs
78e0: 65 72 49 66 50 61 63 6b 61 67 65 64 29 20 7c 7c  erIfPackaged) ||
78f0: 20 28 21 70 61 74 68 69 6e 66 6f 2e 70 61 63 6b   (!pathinfo.pack
7900: 61 67 65 64 29 29 20 7b 0a 09 09 73 74 62 75 66  aged)) {...stbuf
7910: 2d 3e 73 74 5f 75 69 64 20 20 20 3d 20 61 70 70  ->st_uid   = app
7920: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b 0a  fs_get_fsuid();.
7930: 09 09 73 74 62 75 66 2d 3e 73 74 5f 67 69 64 20  ..stbuf->st_gid 
7940: 20 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73    = appfs_get_fs
7950: 67 69 64 28 29 3b 0a 09 09 73 74 62 75 66 2d 3e  gid();...stbuf->
7960: 73 74 5f 6d 6f 64 65 20 7c 3d 20 30 32 30 30 3b  st_mode |= 0200;
7970: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74  ..}...return(ret
7980: 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  val);.}..static 
7990: 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72  int appfs_fuse_r
79a0: 65 61 64 64 69 72 28 63 6f 6e 73 74 20 63 68 61  eaddir(const cha
79b0: 72 20 2a 70 61 74 68 2c 20 76 6f 69 64 20 2a 62  r *path, void *b
79c0: 75 66 2c 20 66 75 73 65 5f 66 69 6c 6c 5f 64 69  uf, fuse_fill_di
79d0: 72 5f 74 20 66 69 6c 6c 65 72 2c 20 6f 66 66 5f  r_t filler, off_
79e0: 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63 74  t offset, struct
79f0: 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20   fuse_file_info 
7a00: 2a 66 69 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  *fi) {..Tcl_Inte
7a10: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c  rp *interp;..Tcl
7a20: 5f 4f 62 6a 20 2a 2a 63 68 69 6c 64 72 65 6e 3b  _Obj **children;
7a30: 0a 09 69 6e 74 20 63 68 69 6c 64 72 65 6e 5f 63  ..int children_c
7a40: 6f 75 6e 74 2c 20 69 64 78 3b 0a 09 69 6e 74 20  ount, idx;..int 
7a50: 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53  tcl_ret;...APPFS
7a60: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
7a70: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c  ath = %s, ...)",
7a80: 20 70 61 74 68 29 3b 0a 0a 09 69 6e 74 65 72 70   path);...interp
7a90: 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65   = appfs_TclInte
7aa0: 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72  rp();..if (inter
7ab0: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41  p == NULL) {...A
7ac0: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
7ad0: 72 3a 20 55 6e 61 62 6c 65 20 74 6f 20 67 65 74  r: Unable to get
7ae0: 20 61 6e 20 69 6e 74 65 72 70 72 65 74 65 72 22   an interpreter"
7af0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b  );....return(0);
7b00: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..}...appfs_call
7b10: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73  _libtcl(Tcl_Pres
7b20: 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  erve(interp);)..
7b30: 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e 22  .filler(buf, "."
7b40: 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 66 69 6c  , NULL, 0);..fil
7b50: 6c 65 72 28 62 75 66 2c 20 22 2e 2e 22 2c 20 4e  ler(buf, "..", N
7b60: 55 4c 4c 2c 20 30 29 3b 0a 0a 09 74 63 6c 5f 72  ULL, 0);...tcl_r
7b70: 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45  et = appfs_Tcl_E
7b80: 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22  val(interp, 2, "
7b90: 3a 3a 61 70 70 66 73 3a 3a 67 65 74 63 68 69 6c  ::appfs::getchil
7ba0: 64 72 65 6e 22 2c 20 70 61 74 68 29 3b 0a 09 69  dren", path);..i
7bb0: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
7bc0: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
7bd0: 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a  DEBUG("::appfs::
7be0: 67 65 74 63 68 69 6c 64 72 65 6e 28 25 73 29 20  getchildren(%s) 
7bf0: 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b  failed.", path);
7c00: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
7c10: 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44  btcl(....APPFS_D
7c20: 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20  EBUG("Tcl Error 
7c30: 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74  is: %s", Tcl_Get
7c40: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
7c50: 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70  erp));...)....ap
7c60: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
7c70: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
7c80: 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28  rp);)....return(
7c90: 30 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63  0);..}...appfs_c
7ca0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63  all_libtcl(...tc
7cb0: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 4c 69 73 74  l_ret = Tcl_List
7cc0: 4f 62 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28 69  ObjGetElements(i
7cd0: 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 4f 62  nterp, Tcl_GetOb
7ce0: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 2c  jResult(interp),
7cf0: 20 26 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74   &children_count
7d00: 2c 20 26 63 68 69 6c 64 72 65 6e 29 3b 0a 09 29  , &children);..)
7d10: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
7d20: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
7d30: 46 53 5f 44 45 42 55 47 28 22 50 61 72 73 69 6e  FS_DEBUG("Parsin
7d40: 67 20 6c 69 73 74 20 6f 66 20 63 68 69 6c 64 72  g list of childr
7d50: 65 6e 20 6f 6e 20 70 61 74 68 20 25 73 20 66 61  en on path %s fa
7d60: 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09  iled.", path);..
7d70: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
7d80: 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42  cl(....APPFS_DEB
7d90: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
7da0: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
7db0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
7dc0: 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66  p));...)....appf
7dd0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
7de0: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
7df0: 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 30 29  );)....return(0)
7e00: 3b 0a 09 7d 0a 0a 09 66 6f 72 20 28 69 64 78 20  ;..}...for (idx 
7e10: 3d 20 30 3b 20 69 64 78 20 3c 20 63 68 69 6c 64  = 0; idx < child
7e20: 72 65 6e 5f 63 6f 75 6e 74 3b 20 69 64 78 2b 2b  ren_count; idx++
7e30: 29 20 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  ) {...appfs_call
7e40: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 66 69 6c 6c  _libtcl(....fill
7e50: 65 72 28 62 75 66 2c 20 54 63 6c 5f 47 65 74 53  er(buf, Tcl_GetS
7e60: 74 72 69 6e 67 28 63 68 69 6c 64 72 65 6e 5b 69  tring(children[i
7e70: 64 78 5d 29 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a  dx]), NULL, 0);.
7e80: 09 09 29 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63  ..)..}...appfs_c
7e90: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
7ea0: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
7eb0: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a  ...return(0);.}.
7ec0: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
7ed0: 73 5f 66 75 73 65 5f 6f 70 65 6e 28 63 6f 6e 73  s_fuse_open(cons
7ee0: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74  t char *path, st
7ef0: 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69  ruct fuse_file_i
7f00: 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c 5f  nfo *fi) {..Tcl_
7f10: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
7f20: 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61  .struct appfs_pa
7f30: 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b  thinfo pathinfo;
7f40: 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72 65  ..const char *re
7f50: 61 6c 5f 70 61 74 68 2c 20 2a 6d 6f 64 65 3b 0a  al_path, *mode;.
7f60: 09 69 6e 74 20 67 70 69 5f 72 65 74 2c 20 74 63  .int gpi_ret, tc
7f70: 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 66 68 3b 0a  l_ret;..int fh;.
7f80: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45  ..APPFS_DEBUG("E
7f90: 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c  nter (path = %s,
7fa0: 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a   ...)", path);..
7fb0: 09 67 70 69 5f 72 65 74 20 3d 20 61 70 70 66 73  .gpi_ret = appfs
7fc0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70  _get_path_info(p
7fd0: 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b  ath, &pathinfo);
7fe0: 0a 0a 09 69 66 20 28 28 66 69 2d 3e 66 6c 61 67  ...if ((fi->flag
7ff0: 73 20 26 20 28 4f 5f 57 52 4f 4e 4c 59 7c 4f 5f  s & (O_WRONLY|O_
8000: 43 52 45 41 54 29 29 20 3d 3d 20 28 4f 5f 43 52  CREAT)) == (O_CR
8010: 45 41 54 7c 4f 5f 57 52 4f 4e 4c 59 29 29 20 7b  EAT|O_WRONLY)) {
8020: 0a 09 09 2f 2a 20 54 68 65 20 66 69 6c 65 20 77  .../* The file w
8030: 69 6c 6c 20 62 65 20 63 72 65 61 74 65 64 20 69  ill be created i
8040: 66 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 65 78  f it does not ex
8050: 69 73 74 20 2a 2f 0a 09 09 69 66 20 28 67 70 69  ist */...if (gpi
8060: 5f 72 65 74 20 21 3d 20 30 20 26 26 20 67 70 69  _ret != 0 && gpi
8070: 5f 72 65 74 20 21 3d 20 2d 45 4e 4f 45 4e 54 29  _ret != -ENOENT)
8080: 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55   {....APPFS_DEBU
8090: 47 28 22 65 72 72 6f 72 3a 20 67 65 74 5f 70 61  G("error: get_pa
80a0: 74 68 5f 69 6e 66 6f 20 66 61 69 6c 65 64 22 29  th_info failed")
80b0: 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 67 70 69  ;.....return(gpi
80c0: 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d 6f  _ret);...}....mo
80d0: 64 65 20 3d 20 22 63 72 65 61 74 65 22 3b 0a 0a  de = "create";..
80e0: 09 09 2f 2a 0a 09 09 20 2a 20 57 65 20 68 61 76  ../*... * We hav
80f0: 65 20 74 6f 20 63 6c 65 61 72 20 74 68 65 20 63  e to clear the c
8100: 61 63 68 65 20 68 65 72 65 20 73 6f 20 74 68 61  ache here so tha
8110: 74 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a  t the number of.
8120: 09 09 20 2a 20 6c 69 6e 6b 73 20 67 65 74 73 20  .. * links gets 
8130: 6d 61 69 6e 74 61 69 6e 65 64 20 6f 6e 20 74 68  maintained on th
8140: 65 20 70 61 72 65 6e 74 20 64 69 72 65 63 74 6f  e parent directo
8150: 72 79 0a 09 09 20 2a 2f 0a 09 09 61 70 70 66 73  ry... */...appfs
8160: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
8170: 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73  ache_flush(appfs
8180: 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31  _get_fsuid(), -1
8190: 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 2f  );..} else {.../
81a0: 2a 20 54 68 65 20 66 69 6c 65 20 6d 75 73 74 20  * The file must 
81b0: 61 6c 72 65 61 64 79 20 65 78 69 73 74 20 2a 2f  already exist */
81c0: 0a 09 09 69 66 20 28 67 70 69 5f 72 65 74 20 21  ...if (gpi_ret !
81d0: 3d 20 30 29 20 7b 0a 09 09 09 41 50 50 46 53 5f  = 0) {....APPFS_
81e0: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 67 65  DEBUG("error: ge
81f0: 74 5f 70 61 74 68 5f 69 6e 66 6f 20 66 61 69 6c  t_path_info fail
8200: 65 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e  ed");.....return
8210: 28 67 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a  (gpi_ret);...}..
8220: 09 09 6d 6f 64 65 20 3d 20 22 22 3b 0a 0a 09 09  ..mode = "";....
8230: 69 66 20 28 28 66 69 2d 3e 66 6c 61 67 73 20 26  if ((fi->flags &
8240: 20 4f 5f 57 52 4f 4e 4c 59 29 20 3d 3d 20 4f 5f   O_WRONLY) == O_
8250: 57 52 4f 4e 4c 59 29 20 7b 0a 09 09 09 6d 6f 64  WRONLY) {....mod
8260: 65 20 3d 20 22 77 72 69 74 65 22 3b 0a 09 09 7d  e = "write";...}
8270: 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e  ..}...if (pathin
8280: 66 6f 2e 74 79 70 65 20 3d 3d 20 41 50 50 46 53  fo.type == APPFS
8290: 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45 43 54  _PATHTYPE_DIRECT
82a0: 4f 52 59 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  ORY) {...APPFS_D
82b0: 45 42 55 47 28 22 65 72 72 6f 72 3a 20 41 73 6b  EBUG("error: Ask
82c0: 65 64 20 74 6f 20 6f 70 65 6e 20 61 20 64 69 72  ed to open a dir
82d0: 65 63 74 6f 72 79 2e 22 29 3b 0a 0a 09 09 72 65  ectory.");....re
82e0: 74 75 72 6e 28 2d 45 49 53 44 49 52 29 3b 0a 09  turn(-EISDIR);..
82f0: 7d 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  }...interp = app
8300: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a  fs_TclInterp();.
8310: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
8320: 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  ULL) {...APPFS_D
8330: 45 42 55 47 28 22 65 72 72 6f 72 3a 20 55 6e 61  EBUG("error: Una
8340: 62 6c 65 20 74 6f 20 67 65 74 20 61 6e 20 69 6e  ble to get an in
8350: 74 65 72 70 72 65 74 65 72 22 29 3b 0a 0a 09 09  terpreter");....
8360: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
8370: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
8380: 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76  btcl(Tcl_Preserv
8390: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63  e(interp);)...tc
83a0: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
83b0: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 33  l_Eval(interp, 3
83c0: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e  , "::appfs::open
83d0: 70 61 74 68 22 2c 20 70 61 74 68 2c 20 6d 6f 64  path", path, mod
83e0: 65 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  e);..if (tcl_ret
83f0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
8400: 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61  APPFS_DEBUG("::a
8410: 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28 25  ppfs::openpath(%
8420: 73 2c 20 25 73 29 20 66 61 69 6c 65 64 2e 22 2c  s, %s) failed.",
8430: 20 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 09 09   path, mode);...
8440: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
8450: 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55  l(....APPFS_DEBU
8460: 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  G("Tcl Error is:
8470: 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72   %s", Tcl_GetStr
8480: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
8490: 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73  ));...)....appfs
84a0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
84b0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
84c0: 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ;)....return(-EI
84d0: 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63  O);..}...appfs_c
84e0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65  all_libtcl(...re
84f0: 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65  al_path = Tcl_Ge
8500: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
8510: 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66  terp);..)...appf
8520: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
8530: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
8540: 29 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70  );)...if (real_p
8550: 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ath == NULL) {..
8560: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72  .APPFS_DEBUG("er
8570: 72 6f 72 3a 20 72 65 61 6c 5f 70 61 74 68 20 77  ror: real_path w
8580: 61 73 20 4e 55 4c 4c 2e 22 29 0a 0a 09 09 72 65  as NULL.")....re
8590: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
85a0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 72  .APPFS_DEBUG("Tr
85b0: 61 6e 73 6c 61 74 65 64 20 72 65 71 75 65 73 74  anslated request
85c0: 20 74 6f 20 6f 70 65 6e 20 25 73 20 74 6f 20 6f   to open %s to o
85d0: 70 65 6e 69 6e 67 20 25 73 20 28 6d 6f 64 65 20  pening %s (mode 
85e0: 3d 20 5c 22 25 73 5c 22 29 22 2c 20 70 61 74 68  = \"%s\")", path
85f0: 2c 20 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64  , real_path, mod
8600: 65 29 3b 0a 0a 09 66 68 20 3d 20 6f 70 65 6e 28  e);...fh = open(
8610: 72 65 61 6c 5f 70 61 74 68 2c 20 66 69 2d 3e 66  real_path, fi->f
8620: 6c 61 67 73 2c 20 30 36 30 30 29 3b 0a 0a 09 69  lags, 0600);...i
8630: 66 20 28 66 68 20 3c 20 30 29 20 7b 0a 09 09 41  f (fh < 0) {...A
8640: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
8650: 72 3a 20 6f 70 65 6e 20 66 61 69 6c 65 64 22 29  r: open failed")
8660: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e  ;....return(errn
8670: 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66 69  o * -1);..}...fi
8680: 2d 3e 66 68 20 3d 20 66 68 3b 0a 0a 09 41 50 50  ->fh = fh;...APP
8690: 46 53 5f 44 45 42 55 47 28 22 4f 70 65 6e 65 64  FS_DEBUG("Opened
86a0: 20 5c 22 25 73 5c 22 20 28 66 6f 72 20 5c 22 25   \"%s\" (for \"%
86b0: 73 5c 22 29 20 77 69 74 68 20 66 69 6c 65 20 64  s\") with file d
86c0: 65 73 63 72 69 70 74 6f 72 20 25 69 22 2c 20 72  escriptor %i", r
86d0: 65 61 6c 5f 70 61 74 68 2c 20 70 61 74 68 2c 20  eal_path, path, 
86e0: 66 68 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29  fh);...return(0)
86f0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
8700: 61 70 70 66 73 5f 66 75 73 65 5f 63 6c 6f 73 65  appfs_fuse_close
8710: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
8720: 68 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66  h, struct fuse_f
8730: 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a  ile_info *fi) {.
8740: 09 69 6e 74 20 63 6c 6f 73 65 5f 72 65 74 3b 0a  .int close_ret;.
8750: 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  ..appfs_get_path
8760: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70  _info_cache_rm(p
8770: 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66  ath, appfs_get_f
8780: 73 75 69 64 28 29 29 3b 0a 0a 09 63 6c 6f 73 65  suid());...close
8790: 5f 72 65 74 20 3d 20 63 6c 6f 73 65 28 66 69 2d  _ret = close(fi-
87a0: 3e 66 68 29 3b 0a 09 69 66 20 28 63 6c 6f 73 65  >fh);..if (close
87b0: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41  _ret != 0) {...A
87c0: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
87d0: 72 3a 20 63 6c 6f 73 65 20 66 61 69 6c 65 64 22  r: close failed"
87e0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 65 72 72  );....return(err
87f0: 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72  no * -1);..}...r
8800: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61  eturn(0);.}..sta
8810: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
8820: 73 65 5f 72 65 61 64 28 63 6f 6e 73 74 20 63 68  se_read(const ch
8830: 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72 20 2a  ar *path, char *
8840: 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65  buf, size_t size
8850: 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20  , off_t offset, 
8860: 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65  struct fuse_file
8870: 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 73 73  _info *fi) {..ss
8880: 69 7a 65 5f 74 20 72 65 61 64 5f 72 65 74 3b 0a  ize_t read_ret;.
8890: 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09 41  .int retval;...A
88a0: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
88b0: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 62 75  r (path = %s, bu
88c0: 66 2c 20 73 69 7a 65 20 3d 20 25 6c 6c 69 2c 20  f, size = %lli, 
88d0: 6f 66 66 73 65 74 20 3d 20 25 6c 6c 69 2c 20 66  offset = %lli, f
88e0: 64 20 3d 20 25 6c 6c 69 29 22 2c 20 70 61 74 68  d = %lli)", path
88f0: 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 69  , (long long) si
8900: 7a 65 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20  ze, (long long) 
8910: 6f 66 66 73 65 74 2c 20 28 6c 6f 6e 67 20 6c 6f  offset, (long lo
8920: 6e 67 29 20 66 69 2d 3e 66 68 29 3b 0a 0a 09 72  ng) fi->fh);...r
8930: 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 77 68 69  etval = 0;...whi
8940: 6c 65 20 28 73 69 7a 65 20 21 3d 20 30 29 20 7b  le (size != 0) {
8950: 0a 09 09 72 65 61 64 5f 72 65 74 20 3d 20 70 72  ...read_ret = pr
8960: 65 61 64 28 66 69 2d 3e 66 68 2c 20 62 75 66 2c  ead(fi->fh, buf,
8970: 20 73 69 7a 65 2c 20 6f 66 66 73 65 74 29 3b 0a   size, offset);.
8980: 0a 09 09 69 66 20 28 72 65 61 64 5f 72 65 74 20  ...if (read_ret 
8990: 3c 20 30 29 20 7b 0a 09 09 09 41 50 50 46 53 5f  < 0) {....APPFS_
89a0: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 72 65  DEBUG("error: re
89b0: 61 64 20 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09  ad failed");....
89c0: 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20  .return(errno * 
89d0: 2d 31 29 3b 0a 09 09 7d 0a 0a 09 09 69 66 20 28  -1);...}....if (
89e0: 72 65 61 64 5f 72 65 74 20 3d 3d 20 30 29 20 7b  read_ret == 0) {
89f0: 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 7d 0a 0a  ....break;...}..
8a00: 09 09 73 69 7a 65 20 2d 3d 20 72 65 61 64 5f 72  ..size -= read_r
8a10: 65 74 3b 0a 09 09 62 75 66 20 20 2b 3d 20 72 65  et;...buf  += re
8a20: 61 64 5f 72 65 74 3b 0a 09 09 6f 66 66 73 65 74  ad_ret;...offset
8a30: 20 2b 3d 20 72 65 61 64 5f 72 65 74 3b 0a 09 09   += read_ret;...
8a40: 72 65 74 76 61 6c 20 2b 3d 20 72 65 61 64 5f 72  retval += read_r
8a50: 65 74 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 69 7a  et;..}...if (siz
8a60: 65 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  e != 0) {...APPF
8a70: 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20  S_DEBUG("error: 
8a80: 69 6e 63 6f 6d 70 6c 65 74 65 20 72 65 61 64 20  incomplete read 
8a90: 28 74 68 69 73 20 6d 69 67 68 74 20 62 65 20 61  (this might be a
8aa0: 6e 20 65 72 72 6f 72 20 62 65 63 61 75 73 65 20  n error because 
8ab0: 46 55 53 45 20 77 69 6c 6c 20 72 65 71 75 65 73  FUSE will reques
8ac0: 74 20 74 68 65 20 65 78 61 63 74 20 6c 65 6e 67  t the exact leng
8ad0: 74 68 20 6f 66 20 74 68 65 20 66 69 6c 65 29 22  th of the file)"
8ae0: 29 3b 0a 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45  );..}...APPFS_DE
8af0: 42 55 47 28 22 52 65 74 75 72 6e 69 6e 67 3a 20  BUG("Returning: 
8b00: 25 69 22 2c 20 72 65 74 76 61 6c 29 3b 0a 0a 09  %i", retval);...
8b10: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a  return(retval);.
8b20: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
8b30: 70 66 73 5f 66 75 73 65 5f 77 72 69 74 65 28 63  pfs_fuse_write(c
8b40: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
8b50: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 62 75 66   const char *buf
8b60: 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f  , size_t size, o
8b70: 66 66 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72  ff_t offset, str
8b80: 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e  uct fuse_file_in
8b90: 66 6f 20 2a 66 69 29 20 7b 0a 09 73 73 69 7a 65  fo *fi) {..ssize
8ba0: 5f 74 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 69  _t write_ret;..i
8bb0: 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09 41 50 50  nt retval;...APP
8bc0: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
8bd0: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
8be0: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66  ", path);...appf
8bf0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
8c00: 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61  cache_rm(path, a
8c10: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
8c20: 29 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 30 3b  );...retval = 0;
8c30: 0a 0a 09 77 68 69 6c 65 20 28 73 69 7a 65 20 21  ...while (size !
8c40: 3d 20 30 29 20 7b 0a 09 09 77 72 69 74 65 5f 72  = 0) {...write_r
8c50: 65 74 20 3d 20 70 77 72 69 74 65 28 66 69 2d 3e  et = pwrite(fi->
8c60: 66 68 2c 20 62 75 66 2c 20 73 69 7a 65 2c 20 6f  fh, buf, size, o
8c70: 66 66 73 65 74 29 3b 0a 0a 09 09 69 66 20 28 77  ffset);....if (w
8c80: 72 69 74 65 5f 72 65 74 20 3c 20 30 29 20 7b 0a  rite_ret < 0) {.
8c90: 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
8ca0: 65 72 72 6f 72 3a 20 77 72 69 74 65 20 66 61 69  error: write fai
8cb0: 6c 65 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72  led");.....retur
8cc0: 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09  n(errno * -1);..
8cd0: 09 7d 0a 0a 09 09 69 66 20 28 77 72 69 74 65 5f  .}....if (write_
8ce0: 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09 09 09 62  ret == 0) {....b
8cf0: 72 65 61 6b 3b 0a 09 09 7d 0a 0a 09 09 73 69 7a  reak;...}....siz
8d00: 65 20 2d 3d 20 77 72 69 74 65 5f 72 65 74 3b 0a  e -= write_ret;.
8d10: 09 09 62 75 66 20 20 2b 3d 20 77 72 69 74 65 5f  ..buf  += write_
8d20: 72 65 74 3b 0a 09 09 6f 66 66 73 65 74 20 2b 3d  ret;...offset +=
8d30: 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 09 72 65   write_ret;...re
8d40: 74 76 61 6c 20 2b 3d 20 77 72 69 74 65 5f 72 65  tval += write_re
8d50: 74 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 69 7a 65  t;..}...if (size
8d60: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53   != 0) {...APPFS
8d70: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 69  _DEBUG("error: i
8d80: 6e 63 6f 6d 70 6c 65 74 65 20 77 72 69 74 65 22  ncomplete write"
8d90: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72  );..}...return(r
8da0: 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69  etval);.}..stati
8db0: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
8dc0: 5f 6d 6b 6e 6f 64 28 63 6f 6e 73 74 20 63 68 61  _mknod(const cha
8dd0: 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20  r *path, mode_t 
8de0: 6d 6f 64 65 2c 20 64 65 76 5f 74 20 64 65 76 69  mode, dev_t devi
8df0: 63 65 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61  ce) {..char *rea
8e00: 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 6d 6b 6e  l_path;..int mkn
8e10: 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f  od_ret;...APPFS_
8e20: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
8e30: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
8e40: 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 28 6d 6f  path);...if ((mo
8e50: 64 65 20 26 20 53 5f 49 46 43 48 52 29 20 3d 3d  de & S_IFCHR) ==
8e60: 20 53 5f 49 46 43 48 52 29 20 7b 0a 09 09 72 65   S_IFCHR) {...re
8e70: 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d  turn(-EPERM);..}
8e80: 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53  ...if ((mode & S
8e90: 5f 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49 46 42  _IFBLK) == S_IFB
8ea0: 4c 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  LK) {...return(-
8eb0: 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61  EPERM);..}...rea
8ec0: 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70  l_path = appfs_p
8ed0: 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65  repare_to_create
8ee0: 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61  (path);..if (rea
8ef0: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
8f00: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
8f10: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d  ;..}...appfs_sim
8f20: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
8f30: 74 65 72 28 29 3b 0a 0a 09 6d 6b 6e 6f 64 5f 72  ter();...mknod_r
8f40: 65 74 20 3d 20 6d 6b 6e 6f 64 28 72 65 61 6c 5f  et = mknod(real_
8f50: 70 61 74 68 2c 20 6d 6f 64 65 2c 20 64 65 76 69  path, mode, devi
8f60: 63 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d  ce);...appfs_sim
8f70: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65  ulate_user_fs_le
8f80: 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65  ave();...free(re
8f90: 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28  al_path);...if (
8fa0: 6d 6b 6e 6f 64 5f 72 65 74 20 21 3d 20 30 29 20  mknod_ret != 0) 
8fb0: 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f  {...return(errno
8fc0: 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74   * -1);..}...ret
8fd0: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69  urn(0);.}..stati
8fe0: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
8ff0: 5f 63 72 65 61 74 65 28 63 6f 6e 73 74 20 63 68  _create(const ch
9000: 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74  ar *path, mode_t
9010: 20 6d 6f 64 65 2c 20 73 74 72 75 63 74 20 66 75   mode, struct fu
9020: 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69  se_file_info *fi
9030: 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f  ) {..char *real_
9040: 70 61 74 68 3b 0a 09 69 6e 74 20 66 64 3b 0a 0a  path;..int fd;..
9050: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
9060: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
9070: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09  ...)", path);...
9080: 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46  if ((mode & S_IF
9090: 43 48 52 29 20 3d 3d 20 53 5f 49 46 43 48 52 29  CHR) == S_IFCHR)
90a0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45   {...return(-EPE
90b0: 52 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 6d  RM);..}...if ((m
90c0: 6f 64 65 20 26 20 53 5f 49 46 42 4c 4b 29 20 3d  ode & S_IFBLK) =
90d0: 3d 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09 72  = S_IFBLK) {...r
90e0: 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09  eturn(-EPERM);..
90f0: 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20  }...real_path = 
9100: 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f  appfs_prepare_to
9110: 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09  _create(path);..
9120: 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d  if (real_path ==
9130: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
9140: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70  n(-EIO);..}...ap
9150: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
9160: 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09  r_fs_enter();...
9170: 66 64 20 3d 20 63 72 65 61 74 28 72 65 61 6c 5f  fd = creat(real_
9180: 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61  path, mode);...a
9190: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
91a0: 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a  er_fs_leave();..
91b0: 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29  .free(real_path)
91c0: 3b 0a 0a 09 69 66 20 28 66 64 20 3c 20 30 29 20  ;...if (fd < 0) 
91d0: 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f  {...return(errno
91e0: 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66 69 2d   * -1);..}...fi-
91f0: 3e 66 68 20 3d 20 66 64 3b 0a 0a 09 72 65 74 75  >fh = fd;...retu
9200: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn(0);.}..static
9210: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
9220: 74 72 75 6e 63 61 74 65 28 63 6f 6e 73 74 20 63  truncate(const c
9230: 68 61 72 20 2a 70 61 74 68 2c 20 6f 66 66 5f 74  har *path, off_t
9240: 20 73 69 7a 65 29 20 7b 0a 09 63 68 61 72 20 2a   size) {..char *
9250: 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20  real_path;..int 
9260: 74 72 75 6e 63 61 74 65 5f 72 65 74 3b 0a 0a 09  truncate_ret;...
9270: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
9280: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
9290: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 72  ..)", path);...r
92a0: 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73  eal_path = appfs
92b0: 5f 6c 6f 63 61 6c 70 61 74 68 28 70 61 74 68 29  _localpath(path)
92c0: 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68  ;..if (real_path
92d0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
92e0: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
92f0: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  .appfs_get_path_
9300: 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61  info_cache_rm(pa
9310: 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73  th, appfs_get_fs
9320: 75 69 64 28 29 29 3b 0a 0a 09 61 70 70 66 73 5f  uid());...appfs_
9330: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
9340: 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 74 72 75 6e  _enter();...trun
9350: 63 61 74 65 5f 72 65 74 20 3d 20 74 72 75 6e 63  cate_ret = trunc
9360: 61 74 65 28 72 65 61 6c 5f 70 61 74 68 2c 20 73  ate(real_path, s
9370: 69 7a 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  ize);...appfs_si
9380: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
9390: 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72  eave();...free(r
93a0: 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20  eal_path);...if 
93b0: 28 74 72 75 6e 63 61 74 65 5f 72 65 74 20 21 3d  (truncate_ret !=
93c0: 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 65   0) {...return(e
93d0: 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a  rrno * -1);..}..
93e0: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
93f0: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
9400: 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69  fuse_unlink_rmdi
9410: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  r(const char *pa
9420: 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  th) {..Tcl_Inter
9430: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 69 6e 74 20  p *interp;..int 
9440: 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53  tcl_ret;...APPFS
9450: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
9460: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c  ath = %s, ...)",
9470: 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f   path);...appfs_
9480: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
9490: 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73 5f  che_flush(appfs_
94a0: 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31 29  get_fsuid(), -1)
94b0: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  ;...interp = app
94c0: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a  fs_TclInterp();.
94d0: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
94e0: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
94f0: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  -EIO);..}...appf
9500: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
9510: 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72  l_Preserve(inter
9520: 70 29 3b 29 0a 0a 09 74 63 6c 5f 72 65 74 20 3d  p);)...tcl_ret =
9530: 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28   appfs_Tcl_Eval(
9540: 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70  interp, 2, "::ap
9550: 70 66 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68 22  pfs::unlinkpath"
9560: 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28 74 63  , path);..if (tc
9570: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
9580: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
9590: 28 22 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c 69 6e  ("::appfs::unlin
95a0: 6b 70 61 74 68 28 25 73 29 20 66 61 69 6c 65 64  kpath(%s) failed
95b0: 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61 70 70  .", path);...app
95c0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
95d0: 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
95e0: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
95f0: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
9600: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
9610: 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61  ...)....appfs_ca
9620: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
9630: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
9640: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
9650: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..}...appfs_call
9660: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
9670: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
9680: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74  return(0);.}..st
9690: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
96a0: 75 73 65 5f 6d 6b 64 69 72 28 63 6f 6e 73 74 20  use_mkdir(const 
96b0: 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65  char *path, mode
96c0: 5f 74 20 6d 6f 64 65 29 20 7b 0a 09 63 68 61 72  _t mode) {..char
96d0: 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e   *real_path;..in
96e0: 74 20 6d 6b 64 69 72 5f 72 65 74 3b 0a 0a 09 41  t mkdir_ret;...A
96f0: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
9700: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
9710: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 72 65  .)", path);...re
9720: 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f  al_path = appfs_
9730: 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74  prepare_to_creat
9740: 65 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65  e(path);..if (re
9750: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
9760: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f   {...return(-EIO
9770: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69  );..}...appfs_si
9780: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65  mulate_user_fs_e
9790: 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b 64 69 72 5f  nter();...mkdir_
97a0: 72 65 74 20 3d 20 6d 6b 64 69 72 28 72 65 61 6c  ret = mkdir(real
97b0: 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09  _path, mode);...
97c0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
97d0: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a  ser_fs_leave();.
97e0: 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68  ..free(real_path
97f0: 29 3b 0a 0a 09 69 66 20 28 6d 6b 64 69 72 5f 72  );...if (mkdir_r
9800: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 69 66 20  et != 0) {...if 
9810: 28 65 72 72 6e 6f 20 21 3d 20 45 45 58 49 53 54  (errno != EEXIST
9820: 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 65 72  ) {....return(er
9830: 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 09 7d 0a 09  rno * -1);...}..
9840: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  }...return(0);.}
9850: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
9860: 66 73 5f 66 75 73 65 5f 63 68 6d 6f 64 28 63 6f  fs_fuse_chmod(co
9870: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
9880: 6d 6f 64 65 5f 74 20 6d 6f 64 65 29 20 7b 0a 09  mode_t mode) {..
9890: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
98a0: 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20  rp;..const char 
98b0: 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74  *real_path;..int
98c0: 20 74 63 6c 5f 72 65 74 2c 20 63 68 6d 6f 64 5f   tcl_ret, chmod_
98d0: 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42  ret;...APPFS_DEB
98e0: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
98f0: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74  = %s, ...)", pat
9900: 68 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f  h);...appfs_get_
9910: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
9920: 72 6d 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67  rm(path, appfs_g
9930: 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 69  et_fsuid());...i
9940: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63  nterp = appfs_Tc
9950: 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28  lInterp();..if (
9960: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
9970: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
9980: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
9990: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65  l_libtcl(Tcl_Pre
99a0: 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a  serve(interp);).
99b0: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66  ..tcl_ret = appf
99c0: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  s_Tcl_Eval(inter
99d0: 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  p, 3, "::appfs::
99e0: 6f 70 65 6e 70 61 74 68 22 2c 20 70 61 74 68 2c  openpath", path,
99f0: 20 22 77 72 69 74 65 22 29 3b 0a 09 69 66 20 28   "write");..if (
9a00: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
9a10: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
9a20: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65  UG("::appfs::ope
9a30: 6e 70 61 74 68 28 25 73 2c 20 25 73 29 20 66 61  npath(%s, %s) fa
9a40: 69 6c 65 64 2e 22 2c 20 70 61 74 68 2c 20 22 77  iled.", path, "w
9a50: 72 69 74 65 22 29 3b 0a 09 09 61 70 70 66 73 5f  rite");...appfs_
9a60: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
9a70: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c  APPFS_DEBUG("Tcl
9a80: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20   Error is: %s", 
9a90: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
9aa0: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
9ab0: 29 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  )....appfs_call_
9ac0: 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61  libtcl(Tcl_Relea
9ad0: 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09  se(interp);)....
9ae0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
9af0: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
9b00: 62 74 63 6c 28 0a 09 09 72 65 61 6c 5f 70 61 74  btcl(...real_pat
9b10: 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  h = Tcl_GetStrin
9b20: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b  gResult(interp);
9b30: 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..)...appfs_call
9b40: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
9b50: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
9b60: 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d  if (real_path ==
9b70: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
9b80: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70  n(-EIO);..}...ap
9b90: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
9ba0: 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09  r_fs_enter();...
9bb0: 63 68 6d 6f 64 5f 72 65 74 20 3d 20 63 68 6d 6f  chmod_ret = chmo
9bc0: 64 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64  d(real_path, mod
9bd0: 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  e);...appfs_simu
9be0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
9bf0: 76 65 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 63  ve();...return(c
9c00: 68 6d 6f 64 5f 72 65 74 29 3b 0a 7d 0a 0a 73 74  hmod_ret);.}..st
9c10: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
9c20: 75 73 65 5f 73 79 6d 6c 69 6e 6b 28 63 6f 6e 73  use_symlink(cons
9c30: 74 20 63 68 61 72 20 2a 6f 6c 64 70 61 74 68 2c  t char *oldpath,
9c40: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 6e 65 77   const char *new
9c50: 70 61 74 68 29 20 7b 0a 09 63 68 61 72 20 2a 72  path) {..char *r
9c60: 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 73  eal_path;..int s
9c70: 79 6d 6c 69 6e 6b 5f 72 65 74 3b 0a 0a 09 41 50  ymlink_ret;...AP
9c80: 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72  PFS_DEBUG("Enter
9c90: 20 28 70 61 74 68 20 3d 20 25 73 2c 20 25 73 29   (path = %s, %s)
9ca0: 22 2c 20 6f 6c 64 70 61 74 68 2c 20 6e 65 77 70  ", oldpath, newp
9cb0: 61 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74  ath);...real_pat
9cc0: 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72  h = appfs_prepar
9cd0: 65 5f 74 6f 5f 63 72 65 61 74 65 28 6e 65 77 70  e_to_create(newp
9ce0: 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f  ath);..if (real_
9cf0: 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  path == NULL) {.
9d00: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
9d10: 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c  .}...appfs_simul
9d20: 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65  ate_user_fs_ente
9d30: 72 28 29 3b 0a 0a 09 73 79 6d 6c 69 6e 6b 5f 72  r();...symlink_r
9d40: 65 74 20 3d 20 73 79 6d 6c 69 6e 6b 28 6f 6c 64  et = symlink(old
9d50: 70 61 74 68 2c 20 72 65 61 6c 5f 70 61 74 68 29  path, real_path)
9d60: 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61  ;...appfs_simula
9d70: 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65  te_user_fs_leave
9d80: 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f  ();...free(real_
9d90: 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 73 79 6d  path);...if (sym
9da0: 6c 69 6e 6b 5f 72 65 74 20 21 3d 20 30 29 20 7b  link_ret != 0) {
9db0: 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20  ...return(errno 
9dc0: 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  * -1);..}...retu
9dd0: 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  rn(0);.}../*. * 
9de0: 53 51 4c 69 74 65 33 20 6d 6f 64 65 3a 20 45 78  SQLite3 mode: Ex
9df0: 65 63 75 74 65 20 72 61 77 20 53 51 4c 20 61 6e  ecute raw SQL an
9e00: 64 20 72 65 74 75 72 6e 20 73 75 63 63 65 73 73  d return success
9e10: 20 6f 72 20 66 61 69 6c 75 72 65 0a 20 2a 2f 0a   or failure. */.
9e20: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
9e30: 5f 73 71 6c 69 74 65 33 28 63 6f 6e 73 74 20 63  _sqlite3(const c
9e40: 68 61 72 20 2a 73 71 6c 29 20 7b 0a 09 54 63 6c  har *sql) {..Tcl
9e50: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
9e60: 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71  ..const char *sq
9e70: 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 74 63 6c 5f  l_ret;..int tcl_
9e80: 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20  ret;...interp = 
9e90: 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c  appfs_create_Tcl
9ea0: 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 09 69  Interp(NULL);..i
9eb0: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
9ec0: 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  L) {...fprintf(s
9ed0: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
9ee0: 6f 20 63 72 65 61 74 65 20 61 20 54 63 6c 20 69  o create a Tcl i
9ef0: 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41 62 6f  nterpreter.  Abo
9f00: 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72  rting.\n");....r
9f10: 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 74  eturn(1);..}...t
9f20: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
9f30: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
9f40: 35 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 64 62 22  5, "::appfs::db"
9f50: 2c 20 22 65 76 61 6c 22 2c 20 73 71 6c 2c 20 22  , "eval", sql, "
9f60: 72 6f 77 22 2c 20 22 75 6e 73 65 74 20 2d 6e 6f  row", "unset -no
9f70: 63 6f 6d 70 6c 61 69 6e 20 72 6f 77 28 2a 29 3b  complain row(*);
9f80: 20 70 61 72 72 61 79 20 72 6f 77 3b 20 70 75 74   parray row; put
9f90: 73 20 5c 22 2d 2d 2d 2d 5c 22 22 29 3b 0a 09 73  s \"----\"");..s
9fa0: 71 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74  ql_ret = Tcl_Get
9fb0: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
9fc0: 65 72 70 29 3b 0a 0a 09 69 66 20 28 74 63 6c 5f  erp);...if (tcl_
9fd0: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
9fe0: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
9ff0: 72 2c 20 22 5b 65 72 72 6f 72 5d 20 25 73 5c 6e  r, "[error] %s\n
a000: 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a 0a 09 09  ", sql_ret);....
a010: 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09  return(1);..}...
a020: 69 66 20 28 73 71 6c 5f 72 65 74 20 26 26 20 73  if (sql_ret && s
a030: 71 6c 5f 72 65 74 5b 30 5d 20 21 3d 20 27 5c 30  ql_ret[0] != '\0
a040: 27 29 20 7b 0a 09 09 70 72 69 6e 74 66 28 22 25  ') {...printf("%
a050: 73 5c 6e 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a  s\n", sql_ret);.
a060: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  .}...return(0);.
a070: 7d 0a 0a 2f 2a 0a 20 2a 20 54 63 6c 20 6d 6f 64  }../*. * Tcl mod
a080: 65 3a 20 45 78 65 63 75 74 65 20 72 61 77 20 54  e: Execute raw T
a090: 63 6c 20 61 6e 64 20 72 65 74 75 72 6e 20 73 75  cl and return su
a0a0: 63 63 65 73 73 20 6f 72 20 66 61 69 6c 75 72 65  ccess or failure
a0b0: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  . */.static int 
a0c0: 61 70 70 66 73 5f 74 63 6c 28 63 6f 6e 73 74 20  appfs_tcl(const 
a0d0: 63 68 61 72 20 2a 74 63 6c 29 20 7b 0a 09 54 63  char *tcl) {..Tc
a0e0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
a0f0: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 74  ;..const char *t
a100: 63 6c 5f 72 65 73 75 6c 74 3b 0a 09 69 6e 74 20  cl_result;..int 
a110: 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72  tcl_ret;...inter
a120: 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65  p = appfs_create
a130: 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29  _TclInterp(NULL)
a140: 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ;..if (interp ==
a150: 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e   NULL) {...fprin
a160: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
a170: 6c 65 20 74 6f 20 63 72 65 61 74 65 20 61 20 54  le to create a T
a180: 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20  cl interpreter. 
a190: 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a   Aborting.\n");.
a1a0: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
a1b0: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
a1c0: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 74 63  _Eval(interp, tc
a1d0: 6c 29 3b 0a 09 74 63 6c 5f 72 65 73 75 6c 74 20  l);..tcl_result 
a1e0: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  = Tcl_GetStringR
a1f0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a  esult(interp);..
a200: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
a210: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69  TCL_OK) {...fpri
a220: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 5b 65 72  ntf(stderr, "[er
a230: 72 6f 72 5d 20 25 73 5c 6e 22 2c 20 54 63 6c 5f  ror] %s\n", Tcl_
a240: 47 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22  GetVar(interp, "
a250: 65 72 72 6f 72 49 6e 66 6f 22 2c 20 54 43 4c 5f  errorInfo", TCL_
a260: 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 29 3b 0a 0a  GLOBAL_ONLY));..
a270: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
a280: 0a 09 69 66 20 28 74 63 6c 5f 72 65 73 75 6c 74  ..if (tcl_result
a290: 20 26 26 20 74 63 6c 5f 72 65 73 75 6c 74 5b 30   && tcl_result[0
a2a0: 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09 70  ] != '\0') {...p
a2b0: 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 74 63  rintf("%s\n", tc
a2c0: 6c 5f 72 65 73 75 6c 74 29 3b 0a 09 7d 0a 0a 09  l_result);..}...
a2d0: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a  return(0);.}../*
a2e0: 0a 20 2a 20 41 70 70 46 53 64 20 50 61 63 6b 61  . * AppFSd Packa
a2f0: 67 65 20 66 6f 72 20 54 63 6c 3a 0a 20 2a 20 20  ge for Tcl:. *  
a300: 20 20 20 20 20 20 20 42 72 69 64 67 65 20 66 6f         Bridge fo
a310: 72 20 49 2f 4f 20 6f 70 65 72 61 74 69 6f 6e 73  r I/O operations
a320: 20 74 6f 20 72 65 71 75 65 73 74 20 69 6e 66 6f   to request info
a330: 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 74 68  rmation about th
a340: 65 20 63 75 72 72 65 6e 74 0a 20 2a 20 20 20 20  e current. *    
a350: 20 20 20 20 20 74 72 61 6e 73 61 63 74 69 6f 6e       transaction
a360: 0a 20 2a 2f 0a 2f 2a 0a 20 2a 20 54 63 6c 20 69  . */./*. * Tcl i
a370: 6e 74 65 72 66 61 63 65 20 74 6f 20 67 65 74 20  nterface to get 
a380: 74 68 65 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  the home directo
a390: 72 79 20 66 6f 72 20 74 68 65 20 75 73 65 72 20  ry for the user 
a3a0: 6d 61 6b 69 6e 67 20 74 68 65 20 22 63 75 72 72  making the "curr
a3b0: 65 6e 74 22 0a 20 2a 20 46 55 53 45 20 49 2f 4f  ent". * FUSE I/O
a3c0: 20 72 65 71 75 65 73 74 0a 20 2a 2f 0a 73 74 61   request. */.sta
a3d0: 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66  tic int tcl_appf
a3e0: 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 43 6c  s_get_homedir(Cl
a3f0: 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c  ientData cd, Tcl
a400: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
a410: 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f   int objc, Tcl_O
a420: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
a430: 29 20 7b 0a 09 63 68 61 72 20 2a 68 6f 6d 65 64  ) {..char *homed
a440: 69 72 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 68 6f  ir;..Tcl_Obj *ho
a450: 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 75 69 64 5f  medir_obj;..uid_
a460: 74 20 66 73 75 69 64 3b 0a 09 73 74 61 74 69 63  t fsuid;..static
a470: 20 5f 5f 74 68 72 65 61 64 20 54 63 6c 5f 4f 62   __thread Tcl_Ob
a480: 6a 20 2a 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f  j *last_homedir_
a490: 6f 62 6a 20 3d 20 4e 55 4c 4c 3b 0a 09 73 74 61  obj = NULL;..sta
a4a0: 74 69 63 20 5f 5f 74 68 72 65 61 64 20 75 69 64  tic __thread uid
a4b0: 5f 74 20 6c 61 73 74 5f 66 73 75 69 64 20 3d 20  _t last_fsuid = 
a4c0: 2d 31 3b 0a 0a 20 20 20 20 20 20 20 20 69 66 20  -1;..        if 
a4d0: 28 6f 62 6a 63 20 21 3d 20 31 29 20 7b 0a 20 20  (objc != 1) {.  
a4e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 63                Tc
a4f0: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69  l_WrongNumArgs(i
a500: 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20  nterp, 1, objv, 
a510: 4e 55 4c 4c 29 3b 0a 20 20 20 20 20 20 20 20 20  NULL);.         
a520: 20 20 20 20 20 20 20 72 65 74 75 72 6e 28 54 43         return(TC
a530: 4c 5f 45 52 52 4f 52 29 3b 0a 20 20 20 20 20 20  L_ERROR);.      
a540: 20 20 7d 0a 0a 09 66 73 75 69 64 20 3d 20 61 70    }...fsuid = ap
a550: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b  pfs_get_fsuid();
a560: 0a 0a 09 69 66 20 28 66 73 75 69 64 20 3d 3d 20  ...if (fsuid == 
a570: 6c 61 73 74 5f 66 73 75 69 64 20 26 26 20 6c 61  last_fsuid && la
a580: 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 21  st_homedir_obj !
a590: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 6f 6d 65  = NULL) {...home
a5a0: 64 69 72 5f 6f 62 6a 20 3d 20 6c 61 73 74 5f 68  dir_obj = last_h
a5b0: 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 0a 09 09 54  omedir_obj;....T
a5c0: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
a5d0: 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 7d  homedir_obj);..}
a5e0: 20 65 6c 73 65 20 7b 0a 09 09 68 6f 6d 65 64 69   else {...homedi
a5f0: 72 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 68 6f  r = appfs_get_ho
a600: 6d 65 64 69 72 28 61 70 70 66 73 5f 67 65 74 5f  medir(appfs_get_
a610: 66 73 75 69 64 28 29 29 3b 0a 0a 09 09 69 66 20  fsuid());....if 
a620: 28 68 6f 6d 65 64 69 72 20 3d 3d 20 4e 55 4c 4c  (homedir == NULL
a630: 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 54 43  ) {....return(TC
a640: 4c 5f 45 52 52 4f 52 29 3b 0a 09 09 7d 0a 0a 09  L_ERROR);...}...
a650: 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 54  .homedir_obj = T
a660: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
a670: 68 6f 6d 65 64 69 72 2c 20 2d 31 29 3b 0a 0a 09  homedir, -1);...
a680: 09 66 72 65 65 28 68 6f 6d 65 64 69 72 29 3b 0a  .free(homedir);.
a690: 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f  ...Tcl_IncrRefCo
a6a0: 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29  unt(homedir_obj)
a6b0: 3b 0a 0a 09 09 69 66 20 28 6c 61 73 74 5f 68 6f  ;....if (last_ho
a6c0: 6d 65 64 69 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c  medir_obj != NUL
a6d0: 4c 29 20 7b 0a 09 09 09 54 63 6c 5f 44 65 63 72  L) {....Tcl_Decr
a6e0: 52 65 66 43 6f 75 6e 74 28 6c 61 73 74 5f 68 6f  RefCount(last_ho
a6f0: 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 09 7d 0a  medir_obj);...}.
a700: 0a 09 09 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f  ...last_homedir_
a710: 6f 62 6a 20 3d 20 68 6f 6d 65 64 69 72 5f 6f 62  obj = homedir_ob
a720: 6a 3b 0a 09 09 6c 61 73 74 5f 66 73 75 69 64 20  j;...last_fsuid 
a730: 3d 20 66 73 75 69 64 3b 0a 0a 09 09 54 63 6c 5f  = fsuid;....Tcl_
a740: 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 68 6f 6d  IncrRefCount(hom
a750: 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 7d 0a 0a 20  edir_obj);..}.. 
a760: 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74 4f 62        .Tcl_SetOb
a770: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  jResult(interp, 
a780: 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 0a 09  homedir_obj);...
a790: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74  Tcl_DecrRefCount
a7a0: 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 0a  (homedir_obj);..
a7b0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 28 54          return(T
a7c0: 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69  CL_OK);.}..stati
a7d0: 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f  c int tcl_appfs_
a7e0: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
a7f0: 5f 65 6e 74 65 72 28 43 6c 69 65 6e 74 44 61 74  _enter(ClientDat
a800: 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70  a cd, Tcl_Interp
a810: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62   *interp, int ob
a820: 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  jc, Tcl_Obj *CON
a830: 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70  ST objv[]) {..ap
a840: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
a850: 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09  r_fs_enter();...
a860: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a  return(TCL_OK);.
a870: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  }..static int tc
a880: 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  l_appfs_simulate
a890: 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 43  _user_fs_leave(C
a8a0: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63  lientData cd, Tc
a8b0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
a8c0: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f  , int objc, Tcl_
a8d0: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
a8e0: 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75  ]) {..appfs_simu
a8f0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
a900: 76 65 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54  ve();...return(T
a910: 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69  CL_OK);.}..stati
a920: 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f  c int tcl_appfs_
a930: 67 65 74 5f 66 73 75 69 64 28 43 6c 69 65 6e 74  get_fsuid(Client
a940: 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74  Data cd, Tcl_Int
a950: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74  erp *interp, int
a960: 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a   objc, Tcl_Obj *
a970: 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a  CONST objv[]) {.
a980: 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a 0a 09  .uid_t fsuid;...
a990: 66 73 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65  fsuid = appfs_ge
a9a0: 74 5f 66 73 75 69 64 28 29 3b 0a 0a 20 20 20 20  t_fsuid();..    
a9b0: 20 20 20 09 54 63 6c 5f 53 65 74 4f 62 6a 52 65     .Tcl_SetObjRe
a9c0: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c  sult(interp, Tcl
a9d0: 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 66  _NewWideIntObj(f
a9e0: 73 75 69 64 29 29 3b 0a 0a 09 72 65 74 75 72 6e  suid));...return
a9f0: 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61  (TCL_OK);.}..sta
aa00: 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66  tic int tcl_appf
aa10: 73 5f 67 65 74 5f 66 73 67 69 64 28 43 6c 69 65  s_get_fsgid(Clie
aa20: 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49  ntData cd, Tcl_I
aa30: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69  nterp *interp, i
aa40: 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a  nt objc, Tcl_Obj
aa50: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20   *CONST objv[]) 
aa60: 7b 0a 09 67 69 64 5f 74 20 66 73 67 69 64 3b 0a  {..gid_t fsgid;.
aa70: 0a 09 66 73 67 69 64 20 3d 20 61 70 70 66 73 5f  ..fsgid = appfs_
aa80: 67 65 74 5f 66 73 67 69 64 28 29 3b 0a 0a 20 20  get_fsgid();..  
aa90: 20 20 20 20 20 09 54 63 6c 5f 53 65 74 4f 62 6a       .Tcl_SetObj
aaa0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54  Result(interp, T
aab0: 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a  cl_NewWideIntObj
aac0: 28 66 73 67 69 64 29 29 3b 0a 0a 09 72 65 74 75  (fsgid));...retu
aad0: 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73  rn(TCL_OK);.}..s
aae0: 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70  tatic int tcl_ap
aaf0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
ab00: 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 43 6c  o_cache_flush(Cl
ab10: 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c  ientData cd, Tcl
ab20: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
ab30: 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f   int objc, Tcl_O
ab40: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
ab50: 29 20 7b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  ) {..int tcl_ret
ab60: 3b 0a 09 69 6e 74 20 6e 65 77 5f 73 69 7a 65 3b  ;..int new_size;
ab70: 0a 0a 09 6e 65 77 5f 73 69 7a 65 20 3d 20 2d 31  ...new_size = -1
ab80: 3b 0a 0a 09 69 66 20 28 6f 62 6a 63 20 3d 3d 20  ;...if (objc == 
ab90: 32 29 20 7b 0a 09 09 74 63 6c 5f 72 65 74 20 3d  2) {...tcl_ret =
aba0: 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f   Tcl_GetIntFromO
abb0: 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b  bj(interp, objv[
abc0: 31 5d 2c 20 26 6e 65 77 5f 73 69 7a 65 29 3b 0a  1], &new_size);.
abd0: 09 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
abe0: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 72 65   TCL_OK) {....re
abf0: 74 75 72 6e 28 74 63 6c 5f 72 65 74 29 3b 0a 09  turn(tcl_ret);..
ac00: 09 7d 0a 09 7d 20 65 6c 73 65 20 69 66 20 28 6f  .}..} else if (o
ac10: 62 6a 63 20 3e 20 32 20 7c 7c 20 6f 62 6a 63 20  bjc > 2 || objc 
ac20: 3c 20 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20  < 1) {.         
ac30: 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67         Tcl_Wrong
ac40: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
ac50: 31 2c 20 6f 62 6a 76 2c 20 22 3f 6e 65 77 5f 63  1, objv, "?new_c
ac60: 61 63 68 65 5f 73 69 7a 65 3f 22 29 3b 0a 09 09  ache_size?");...
ac70: 72 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52  return(TCL_ERROR
ac80: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67 65  );..}...appfs_ge
ac90: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
aca0: 65 5f 66 6c 75 73 68 28 2d 31 2c 20 6e 65 77 5f  e_flush(-1, new_
acb0: 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72 6e 28  size);...return(
acc0: 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74  TCL_OK);.}..stat
acd0: 69 63 20 69 6e 74 20 41 70 70 66 73 64 5f 49 6e  ic int Appfsd_In
ace0: 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  it(Tcl_Interp *i
acf0: 6e 74 65 72 70 29 20 7b 0a 23 69 66 64 65 66 20  nterp) {.#ifdef 
ad00: 55 53 45 5f 54 43 4c 5f 53 54 55 42 53 0a 09 69  USE_TCL_STUBS..i
ad10: 66 20 28 54 63 6c 5f 49 6e 69 74 53 74 75 62 73  f (Tcl_InitStubs
ad20: 28 69 6e 74 65 72 70 2c 20 54 43 4c 5f 56 45 52  (interp, TCL_VER
ad30: 53 49 4f 4e 2c 20 30 29 20 3d 3d 20 30 4c 29 20  SION, 0) == 0L) 
ad40: 7b 0a 09 09 72 65 74 75 72 6e 28 54 43 4c 5f 45  {...return(TCL_E
ad50: 52 52 4f 52 29 3b 0a 09 7d 0a 23 65 6e 64 69 66  RROR);..}.#endif
ad60: 0a 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a  ...Tcl_CreateObj
ad70: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
ad80: 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 68 6f 6d  "appfsd::get_hom
ad90: 65 64 69 72 22 2c 20 74 63 6c 5f 61 70 70 66 73  edir", tcl_appfs
ada0: 5f 67 65 74 5f 68 6f 6d 65 64 69 72 2c 20 4e 55  _get_homedir, NU
adb0: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f  LL, NULL);..Tcl_
adc0: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64  CreateObjCommand
add0: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
ade0: 3a 3a 67 65 74 5f 66 73 75 69 64 22 2c 20 74 63  ::get_fsuid", tc
adf0: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  l_appfs_get_fsui
ae00: 64 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  d, NULL, NULL);.
ae10: 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f  .Tcl_CreateObjCo
ae20: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61  mmand(interp, "a
ae30: 70 70 66 73 64 3a 3a 67 65 74 5f 66 73 67 69 64  ppfsd::get_fsgid
ae40: 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74  ", tcl_appfs_get
ae50: 5f 66 73 67 69 64 2c 20 4e 55 4c 4c 2c 20 4e 55  _fsgid, NULL, NU
ae60: 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65  LL);..Tcl_Create
ae70: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
ae80: 70 2c 20 22 61 70 70 66 73 64 3a 3a 73 69 6d 75  p, "appfsd::simu
ae90: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
aea0: 65 72 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 73  er", tcl_appfs_s
aeb0: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
aec0: 65 6e 74 65 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  enter, NULL, NUL
aed0: 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f  L);..Tcl_CreateO
aee0: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
aef0: 2c 20 22 61 70 70 66 73 64 3a 3a 73 69 6d 75 6c  , "appfsd::simul
af00: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76  ate_user_fs_leav
af10: 65 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 73 69  e", tcl_appfs_si
af20: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
af30: 65 61 76 65 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  eave, NULL, NULL
af40: 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62  );..Tcl_CreateOb
af50: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  jCommand(interp,
af60: 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 70 61   "appfsd::get_pa
af70: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c  th_info_cache_fl
af80: 75 73 68 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f  ush", tcl_appfs_
af90: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
afa0: 63 68 65 5f 66 6c 75 73 68 2c 20 4e 55 4c 4c 2c  che_flush, NULL,
afb0: 20 4e 55 4c 4c 29 3b 0a 0a 09 54 63 6c 5f 50 6b   NULL);...Tcl_Pk
afc0: 67 50 72 6f 76 69 64 65 28 69 6e 74 65 72 70 2c  gProvide(interp,
afd0: 20 22 61 70 70 66 73 64 22 2c 20 22 31 2e 30 22   "appfsd", "1.0"
afe0: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f  );...return(TCL_
aff0: 4f 4b 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 48 6f  OK);.}../*. * Ho
b000: 74 2d 72 65 73 74 61 72 74 20 73 75 70 70 6f 72  t-restart suppor
b010: 74 0a 20 2a 2f 0a 2f 2a 20 49 6e 69 74 69 61 74  t. */./* Initiat
b020: 65 20 61 20 68 6f 74 2d 72 65 73 74 61 72 74 20  e a hot-restart 
b030: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  */.static void a
b040: 70 70 66 73 5f 68 6f 74 5f 72 65 73 74 61 72 74  ppfs_hot_restart
b050: 28 76 6f 69 64 29 20 7b 0a 09 41 50 50 46 53 5f  (void) {..APPFS_
b060: 44 45 42 55 47 28 22 41 73 6b 65 64 20 74 6f 20  DEBUG("Asked to 
b070: 69 6e 69 74 69 61 74 65 20 68 6f 74 20 72 65 73  initiate hot res
b080: 74 61 72 74 22 29 3b 0a 0a 09 61 70 70 66 73 5f  tart");...appfs_
b090: 74 63 6c 5f 52 65 73 65 74 49 6e 74 65 72 70 73  tcl_ResetInterps
b0a0: 28 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f  ();...appfs_get_
b0b0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
b0c0: 66 6c 75 73 68 28 2d 31 2c 20 2d 31 29 3b 0a 0a  flush(-1, -1);..
b0d0: 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20  .return;.}../*. 
b0e0: 2a 20 53 69 67 6e 61 6c 20 68 61 6e 64 6c 65 72  * Signal handler
b0f0: 0a 20 2a 20 20 20 20 20 20 20 20 20 53 49 47 48  . *         SIGH
b100: 55 50 20 69 6e 69 74 69 61 74 65 73 20 61 20 68  UP initiates a h
b110: 6f 74 20 72 65 73 74 61 72 74 0a 20 2a 2f 0a 73  ot restart. */.s
b120: 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73  tatic void appfs
b130: 5f 73 69 67 6e 61 6c 5f 68 61 6e 64 6c 65 72 28  _signal_handler(
b140: 69 6e 74 20 73 69 67 29 20 7b 0a 09 2f 2a 20 44  int sig) {../* D
b150: 6f 20 6e 6f 74 20 68 61 6e 64 6c 65 20 73 69 67  o not handle sig
b160: 6e 61 6c 73 20 75 6e 74 69 6c 20 46 55 53 45 20  nals until FUSE 
b170: 68 61 73 20 62 65 65 6e 20 73 74 61 72 74 65 64  has been started
b180: 20 2a 2f 0a 09 69 66 20 28 21 61 70 70 66 73 5f   */..if (!appfs_
b190: 66 75 73 65 5f 73 74 61 72 74 65 64 29 20 7b 0a  fuse_started) {.
b1a0: 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 2f  ..return;..}.../
b1b0: 2a 20 52 65 71 75 65 73 74 20 74 6f 20 70 65 72  * Request to per
b1c0: 66 6f 72 6d 20 61 20 22 68 6f 74 22 20 72 65 73  form a "hot" res
b1d0: 74 61 72 74 20 2a 2f 0a 09 69 66 20 28 73 69 67  tart */..if (sig
b1e0: 20 3d 3d 20 53 49 47 48 55 50 29 20 7b 0a 09 09   == SIGHUP) {...
b1f0: 61 70 70 66 73 5f 68 6f 74 5f 72 65 73 74 61 72  appfs_hot_restar
b200: 74 28 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  t();..}...return
b210: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 65 72 6d 69  ;.}../*. * Termi
b220: 6e 61 74 65 20 61 20 74 68 72 65 61 64 0a 20 2a  nate a thread. *
b230: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  /.static void ap
b240: 70 66 73 5f 74 65 72 6d 69 6e 61 74 65 5f 69 6e  pfs_terminate_in
b250: 74 65 72 70 5f 61 6e 64 5f 74 68 72 65 61 64 28  terp_and_thread(
b260: 76 6f 69 64 20 2a 5f 69 6e 74 65 72 70 29 20 7b  void *_interp) {
b270: 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  ..Tcl_Interp *in
b280: 74 65 72 70 3b 0a 0a 09 41 50 50 46 53 5f 44 45  terp;...APPFS_DE
b290: 42 55 47 28 22 43 61 6c 6c 65 64 3a 20 5f 69 6e  BUG("Called: _in
b2a0: 74 65 72 70 20 3d 20 25 70 22 2c 20 5f 69 6e 74  terp = %p", _int
b2b0: 65 72 70 29 3b 0a 0a 09 69 66 20 28 5f 69 6e 74  erp);...if (_int
b2c0: 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  erp == NULL) {..
b2d0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 65  .APPFS_DEBUG("Te
b2e0: 72 6d 69 6e 61 74 69 6e 67 20 74 68 72 65 61 64  rminating thread
b2f0: 20 77 69 74 68 20 6e 6f 20 69 6e 74 65 72 70 72   with no interpr
b300: 65 74 65 72 22 29 3b 0a 0a 09 09 72 65 74 75 72  eter");....retur
b310: 6e 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72 70 20 3d  n;..}...interp =
b320: 20 5f 69 6e 74 65 72 70 3b 0a 0a 09 41 50 50 46   _interp;...APPF
b330: 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61  S_DEBUG("Termina
b340: 74 69 6e 67 20 69 6e 74 65 72 70 72 65 74 65 72  ting interpreter
b350: 20 64 75 65 20 74 6f 20 74 68 72 65 61 64 20 74   due to thread t
b360: 65 72 6d 69 6e 61 74 69 6f 6e 22 29 3b 0a 0a 09  ermination");...
b370: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
b380: 6c 28 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49  l(...Tcl_DeleteI
b390: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 09  nterp(interp);..
b3a0: 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  )...appfs_call_l
b3b0: 69 62 74 63 6c 28 0a 09 09 54 63 6c 5f 46 69 6e  ibtcl(...Tcl_Fin
b3c0: 61 6c 69 7a 65 54 68 72 65 61 64 28 29 3b 0a 09  alizeThread();..
b3d0: 29 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f  )...return;.}../
b3e0: 2a 0a 20 2a 20 43 6f 6d 6d 61 6e 64 2d 6c 69 6e  *. * Command-lin
b3f0: 65 20 70 61 72 73 69 6e 67 20 74 6f 6f 6c 73 0a  e parsing tools.
b400: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
b410: 61 70 70 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70  appfs_print_help
b420: 28 46 49 4c 45 20 2a 63 68 61 6e 6e 65 6c 29 20  (FILE *channel) 
b430: 7b 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e  {..fprintf(chann
b440: 65 6c 2c 20 22 55 73 61 67 65 3a 20 7b 61 70 70  el, "Usage: {app
b450: 66 73 64 7c 6d 6f 75 6e 74 2e 61 70 70 66 73 7d  fsd|mount.appfs}
b460: 20 5b 2d 6f 20 3c 6f 70 74 69 6f 6e 3e 5d 20 5b   [-o <option>] [
b470: 2d 64 66 73 68 5d 20 3c 63 61 63 68 65 64 69 72  -dfsh] <cachedir
b480: 3e 20 3c 6d 6f 75 6e 74 70 6f 69 6e 74 3e 5c 6e  > <mountpoint>\n
b490: 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61  ");..fprintf(cha
b4a0: 6e 6e 65 6c 2c 20 22 5c 6e 22 29 3b 0a 09 66 70  nnel, "\n");..fp
b4b0: 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22  rintf(channel, "
b4c0: 4f 70 74 69 6f 6e 73 3a 5c 6e 22 29 3b 0a 09 66  Options:\n");..f
b4d0: 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20  printf(channel, 
b4e0: 22 20 20 2d 64 20 20 20 20 20 20 20 20 20 20 20  "  -d           
b4f0: 20 20 20 45 6e 61 62 6c 65 20 46 55 53 45 20 64     Enable FUSE d
b500: 65 62 75 67 20 6d 6f 64 65 2e 5c 6e 22 29 3b 0a  ebug mode.\n");.
b510: 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c  .fprintf(channel
b520: 2c 20 22 20 20 2d 66 20 20 20 20 20 20 20 20 20  , "  -f         
b530: 20 20 20 20 20 52 75 6e 20 69 6e 20 66 6f 72 65       Run in fore
b540: 67 72 6f 75 6e 64 2e 5c 6e 22 29 3b 0a 09 66 70  ground.\n");..fp
b550: 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22  rintf(channel, "
b560: 20 20 2d 73 20 20 20 20 20 20 20 20 20 20 20 20    -s            
b570: 20 20 45 6e 61 62 6c 65 20 73 69 6e 67 6c 65 20    Enable single 
b580: 74 68 72 65 61 64 65 64 20 6d 6f 64 65 2e 5c 6e  threaded mode.\n
b590: 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61  ");..fprintf(cha
b5a0: 6e 6e 65 6c 2c 20 22 20 20 2d 68 20 20 20 20 20  nnel, "  -h     
b5b0: 20 20 20 20 20 20 20 20 20 47 69 76 65 20 74 68           Give th
b5c0: 69 73 20 68 65 6c 70 2e 5c 6e 22 29 3b 0a 09 66  is help.\n");..f
b5d0: 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20  printf(channel, 
b5e0: 22 20 20 2d 6f 20 6e 6f 74 68 72 65 61 64 73 20  "  -o nothreads 
b5f0: 20 20 20 45 6e 61 62 6c 65 20 73 69 6e 67 6c 65     Enable single
b600: 20 74 68 72 65 61 64 65 64 20 6d 6f 64 65 2e 5c   threaded mode.\
b610: 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68  n");..fprintf(ch
b620: 61 6e 6e 65 6c 2c 20 22 20 20 2d 6f 20 61 6c 6c  annel, "  -o all
b630: 6f 77 5f 6f 74 68 65 72 20 20 41 6c 6c 6f 77 20  ow_other  Allow 
b640: 6f 74 68 65 72 20 75 73 65 72 73 20 74 6f 20 61  other users to a
b650: 63 63 65 73 73 20 74 68 69 73 20 6d 6f 75 6e 74  ccess this mount
b660: 70 6f 69 6e 74 20 28 64 65 66 61 75 6c 74 5c 6e  point (default\n
b670: 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61  ");..fprintf(cha
b680: 6e 6e 65 6c 2c 20 22 20 20 20 20 20 20 20 20 20  nnel, "         
b690: 20 20 20 20 20 20 20 20 20 69 66 20 72 6f 6f 74           if root
b6a0: 29 2e 5c 6e 22 29 3b 0a 0a 09 72 65 74 75 72 6e  ).\n");...return
b6b0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
b6c0: 61 70 70 66 73 5f 6f 70 74 5f 70 61 72 73 65 28  appfs_opt_parse(
b6d0: 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a  int argc, char *
b6e0: 2a 61 72 67 76 2c 20 20 73 74 72 75 63 74 20 66  *argv,  struct f
b6f0: 75 73 65 5f 61 72 67 73 20 2a 61 72 67 73 29 20  use_args *args) 
b700: 7b 0a 09 69 6e 74 20 63 68 3b 0a 09 63 68 61 72  {..int ch;..char
b710: 20 2a 6f 70 74 73 74 72 2c 20 2a 6f 70 74 73 74   *optstr, *optst
b720: 72 5f 6e 65 78 74 2c 20 2a 6f 70 74 73 74 72 5f  r_next, *optstr_
b730: 73 3b 0a 09 63 68 61 72 20 66 61 6b 65 5f 61 72  s;..char fake_ar
b740: 67 5b 33 5d 20 3d 20 7b 27 2d 27 2c 20 30 2c 20  g[3] = {'-', 0, 
b750: 30 7d 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 44 65 66  0};.../*.. * Def
b760: 61 75 6c 74 20 76 61 6c 75 65 73 0a 09 20 2a 2f  ault values.. */
b770: 0a 23 69 66 64 65 66 20 54 43 4c 5f 54 48 52 45  .#ifdef TCL_THRE
b780: 41 44 53 0a 09 61 70 70 66 73 5f 74 68 72 65 61  ADS..appfs_threa
b790: 64 65 64 5f 74 63 6c 20 3d 20 31 3b 0a 23 65 6c  ded_tcl = 1;.#el
b7a0: 73 65 0a 09 61 70 70 66 73 5f 74 68 72 65 61 64  se..appfs_thread
b7b0: 65 64 5f 74 63 6c 20 3d 20 30 3b 0a 23 65 6e 64  ed_tcl = 0;.#end
b7c0: 69 66 0a 0a 09 2f 2a 2a 0a 09 20 2a 2a 20 41 64  if.../**.. ** Ad
b7d0: 64 20 46 55 53 45 20 61 72 67 75 6d 65 6e 74 73  d FUSE arguments
b7e0: 20 77 68 69 63 68 20 77 65 20 61 6c 77 61 79 73   which we always
b7f0: 20 73 75 70 70 6c 79 0a 09 20 2a 2a 2f 0a 09 66   supply.. **/..f
b800: 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28  use_opt_add_arg(
b810: 61 72 67 73 2c 20 22 2d 6f 64 65 66 61 75 6c 74  args, "-odefault
b820: 5f 70 65 72 6d 69 73 73 69 6f 6e 73 2c 66 73 6e  _permissions,fsn
b830: 61 6d 65 3d 61 70 70 66 73 2c 73 75 62 74 79 70  ame=appfs,subtyp
b840: 65 3d 61 70 70 66 73 64 2c 75 73 65 5f 69 6e 6f  e=appfsd,use_ino
b850: 2c 65 6e 74 72 79 5f 74 69 6d 65 6f 75 74 3d 30  ,entry_timeout=0
b860: 2c 61 74 74 72 5f 74 69 6d 65 6f 75 74 3d 30 2c  ,attr_timeout=0,
b870: 62 69 67 5f 77 72 69 74 65 73 2c 69 6e 74 72 2c  big_writes,intr,
b880: 68 61 72 64 5f 72 65 6d 6f 76 65 22 29 3b 0a 0a  hard_remove");..
b890: 09 69 66 20 28 67 65 74 75 69 64 28 29 20 3d 3d  .if (getuid() ==
b8a0: 20 30 29 20 7b 0a 09 09 66 75 73 65 5f 6f 70 74   0) {...fuse_opt
b8b0: 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c  _parse(args, NUL
b8c0: 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  L, NULL, NULL);.
b8d0: 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61  ..fuse_opt_add_a
b8e0: 72 67 28 61 72 67 73 2c 20 22 2d 6f 61 6c 6c 6f  rg(args, "-oallo
b8f0: 77 5f 6f 74 68 65 72 22 29 3b 0a 0a 09 09 2f 2a  w_other");..../*
b900: 0a 09 09 20 2a 20 54 68 69 73 20 73 68 6f 75 6c  ... * This shoul
b910: 64 20 67 65 6e 65 72 61 6c 6c 79 20 62 65 20 61  d generally be a
b920: 76 6f 69 64 65 64 2c 20 62 75 74 20 69 66 20 74  voided, but if t
b930: 68 65 72 65 20 61 72 65 20 73 65 63 75 72 69 74  here are securit
b940: 79 0a 09 09 20 2a 20 63 6f 6e 63 65 72 6e 73 20  y... * concerns 
b950: 73 75 69 64 20 63 61 6e 20 62 65 20 64 69 73 61  suid can be disa
b960: 62 6c 65 64 20 63 6f 6d 70 6c 65 74 65 6c 79 20  bled completely 
b970: 6f 6e 20 74 68 65 20 63 6f 6d 6d 61 6e 64 6c 69  on the commandli
b980: 6e 65 0a 09 09 20 2a 2f 0a 09 09 66 75 73 65 5f  ne... */...fuse_
b990: 6f 70 74 5f 70 61 72 73 65 28 61 72 67 73 2c 20  opt_parse(args, 
b9a0: 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  NULL, NULL, NULL
b9b0: 29 3b 0a 09 09 66 75 73 65 5f 6f 70 74 5f 61 64  );...fuse_opt_ad
b9c0: 64 5f 61 72 67 28 61 72 67 73 2c 20 22 2d 6f 73  d_arg(args, "-os
b9d0: 75 69 64 22 29 3b 0a 09 7d 0a 0a 09 77 68 69 6c  uid");..}...whil
b9e0: 65 20 28 28 63 68 20 3d 20 67 65 74 6f 70 74 28  e ((ch = getopt(
b9f0: 61 72 67 63 2c 20 61 72 67 76 2c 20 22 64 66 73  argc, argv, "dfs
ba00: 68 76 6f 3a 22 29 29 20 21 3d 20 2d 31 29 20 7b  hvo:")) != -1) {
ba10: 0a 09 09 73 77 69 74 63 68 20 28 63 68 29 20 7b  ...switch (ch) {
ba20: 0a 09 09 09 63 61 73 65 20 27 76 27 3a 0a 09 09  ....case 'v':...
ba30: 09 09 2f 2a 20 49 67 6e 6f 72 65 64 20 2a 2f 0a  ../* Ignored */.
ba40: 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61  ....break;....ca
ba50: 73 65 20 27 6f 27 3a 0a 09 09 09 09 6f 70 74 73  se 'o':.....opts
ba60: 74 72 5f 6e 65 78 74 20 3d 20 6f 70 74 73 74 72  tr_next = optstr
ba70: 20 3d 20 6f 70 74 73 74 72 5f 73 20 3d 20 73 74   = optstr_s = st
ba80: 72 64 75 70 28 6f 70 74 61 72 67 29 3b 0a 0a 09  rdup(optarg);...
ba90: 09 09 09 77 68 69 6c 65 20 28 31 29 20 7b 0a 09  ...while (1) {..
baa0: 09 09 09 09 6f 70 74 73 74 72 20 3d 20 6f 70 74  ....optstr = opt
bab0: 73 74 72 5f 6e 65 78 74 3b 0a 0a 09 09 09 09 09  str_next;.......
bac0: 69 66 20 28 21 6f 70 74 73 74 72 29 20 7b 0a 09  if (!optstr) {..
bad0: 09 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 09  .....break;.....
bae0: 09 7d 0a 0a 09 09 09 09 09 6f 70 74 73 74 72 5f  .}.......optstr_
baf0: 6e 65 78 74 20 3d 20 73 74 72 63 68 72 28 6f 70  next = strchr(op
bb00: 74 73 74 72 2c 20 27 2c 27 29 3b 0a 09 09 09 09  tstr, ',');.....
bb10: 09 69 66 20 28 6f 70 74 73 74 72 5f 6e 65 78 74  .if (optstr_next
bb20: 29 20 7b 0a 09 09 09 09 09 09 2a 6f 70 74 73 74  ) {.......*optst
bb30: 72 5f 6e 65 78 74 20 3d 20 27 5c 30 27 3b 0a 09  r_next = '\0';..
bb40: 09 09 09 09 09 6f 70 74 73 74 72 5f 6e 65 78 74  .....optstr_next
bb50: 2b 2b 3b 0a 09 09 09 09 09 7d 0a 0a 09 09 09 09  ++;......}......
bb60: 09 69 66 20 28 73 74 72 63 6d 70 28 6f 70 74 73  .if (strcmp(opts
bb70: 74 72 2c 20 22 6e 6f 74 68 72 65 61 64 73 22 29  tr, "nothreads")
bb80: 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09 09 41   == 0) {.......A
bb90: 50 50 46 53 5f 44 45 42 55 47 28 22 50 61 73 73  PPFS_DEBUG("Pass
bba0: 69 6e 67 20 6f 70 74 69 6f 6e 20 74 6f 20 46 55  ing option to FU
bbb0: 53 45 3a 20 2d 73 22 29 3b 0a 0a 09 09 09 09 09  SE: -s");.......
bbc0: 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28  .fuse_opt_parse(
bbd0: 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  args, NULL, NULL
bbe0: 2c 20 4e 55 4c 4c 29 3b 0a 09 09 09 09 09 09 66  , NULL);.......f
bbf0: 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28  use_opt_add_arg(
bc00: 61 72 67 73 2c 20 22 2d 73 22 29 3b 0a 0a 09 09  args, "-s");....
bc10: 09 09 09 09 61 70 70 66 73 5f 74 68 72 65 61 64  ....appfs_thread
bc20: 65 64 5f 74 63 6c 20 3d 20 30 3b 0a 09 09 09 09  ed_tcl = 0;.....
bc30: 09 7d 20 65 6c 73 65 20 69 66 20 28 73 74 72 63  .} else if (strc
bc40: 6d 70 28 6f 70 74 73 74 72 2c 20 22 61 6c 6c 6f  mp(optstr, "allo
bc50: 77 5f 6f 74 68 65 72 22 29 20 3d 3d 20 30 29 20  w_other") == 0) 
bc60: 7b 0a 09 09 09 09 09 09 41 50 50 46 53 5f 44 45  {.......APPFS_DE
bc70: 42 55 47 28 22 50 61 73 73 69 6e 67 20 6f 70 74  BUG("Passing opt
bc80: 69 6f 6e 20 74 6f 20 46 55 53 45 3a 20 2d 6f 20  ion to FUSE: -o 
bc90: 61 6c 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 0a  allow_other");..
bca0: 09 09 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 70  ......fuse_opt_p
bcb0: 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c  arse(args, NULL,
bcc0: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09   NULL, NULL);...
bcd0: 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64  ....fuse_opt_add
bce0: 5f 61 72 67 28 61 72 67 73 2c 20 22 2d 6f 61 6c  _arg(args, "-oal
bcf0: 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 09 09 09  low_other");....
bd00: 09 09 7d 20 65 6c 73 65 20 69 66 20 28 73 74 72  ..} else if (str
bd10: 63 6d 70 28 6f 70 74 73 74 72 2c 20 22 72 77 22  cmp(optstr, "rw"
bd20: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09 09  ) == 0) {.......
bd30: 2f 2a 20 49 67 6e 6f 72 65 64 20 2a 2f 0a 09 09  /* Ignored */...
bd40: 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09  ...} else {.....
bd50: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
bd60: 2c 20 22 61 70 70 66 73 64 3a 20 69 6e 76 61 6c  , "appfsd: inval
bd70: 69 64 20 6f 70 74 69 6f 6e 3a 20 5c 22 2d 6f 20  id option: \"-o 
bd80: 25 73 5c 22 5c 6e 22 2c 20 6f 70 74 73 74 72 29  %s\"\n", optstr)
bd90: 3b 0a 0a 09 09 09 09 09 09 66 72 65 65 28 6f 70  ;........free(op
bda0: 74 73 74 72 5f 73 29 3b 0a 0a 09 09 09 09 09 09  tstr_s);........
bdb0: 72 65 74 75 72 6e 28 31 29 3b 0a 09 09 09 09 09  return(1);......
bdc0: 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66 72 65  }.....}......fre
bdd0: 65 28 6f 70 74 73 74 72 5f 73 29 3b 0a 0a 09 09  e(optstr_s);....
bde0: 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65  ..break;....case
bdf0: 20 27 64 27 3a 0a 09 09 09 63 61 73 65 20 27 66   'd':....case 'f
be00: 27 3a 0a 09 09 09 63 61 73 65 20 27 73 27 3a 0a  ':....case 's':.
be10: 09 09 09 09 69 66 20 28 63 68 20 3d 3d 20 27 73  ....if (ch == 's
be20: 27 29 20 7b 0a 09 09 09 09 09 61 70 70 66 73 5f  ') {......appfs_
be30: 74 68 72 65 61 64 65 64 5f 74 63 6c 20 3d 20 30  threaded_tcl = 0
be40: 3b 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66 61 6b  ;.....}......fak
be50: 65 5f 61 72 67 5b 31 5d 20 3d 20 63 68 3b 0a 0a  e_arg[1] = ch;..
be60: 09 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
be70: 22 50 61 73 73 69 6e 67 20 6f 70 74 69 6f 6e 20  "Passing option 
be80: 74 6f 20 46 55 53 45 3a 20 25 73 22 2c 20 66 61  to FUSE: %s", fa
be90: 6b 65 5f 61 72 67 29 3b 0a 0a 09 09 09 09 66 75  ke_arg);......fu
bea0: 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67  se_opt_parse(arg
beb0: 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e  s, NULL, NULL, N
bec0: 55 4c 4c 29 3b 0a 09 09 09 09 66 75 73 65 5f 6f  ULL);.....fuse_o
bed0: 70 74 5f 61 64 64 5f 61 72 67 28 61 72 67 73 2c  pt_add_arg(args,
bee0: 20 66 61 6b 65 5f 61 72 67 29 3b 0a 09 09 09 09   fake_arg);.....
bef0: 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27  break;....case '
bf00: 68 27 3a 0a 09 09 09 09 61 70 70 66 73 5f 70 72  h':.....appfs_pr
bf10: 69 6e 74 5f 68 65 6c 70 28 73 74 64 6f 75 74 29  int_help(stdout)
bf20: 3b 0a 0a 09 09 09 09 72 65 74 75 72 6e 28 2d 31  ;......return(-1
bf30: 29 3b 0a 09 09 09 63 61 73 65 20 27 3a 27 3a 0a  );....case ':':.
bf40: 09 09 09 63 61 73 65 20 27 3f 27 3a 0a 09 09 09  ...case '?':....
bf50: 64 65 66 61 75 6c 74 3a 0a 09 09 09 09 61 70 70  default:.....app
bf60: 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28 73 74  fs_print_help(st
bf70: 64 65 72 72 29 3b 0a 0a 09 09 09 09 72 65 74 75  derr);......retu
bf80: 72 6e 28 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09  rn(1);...}..}...
bf90: 69 66 20 28 28 6f 70 74 69 6e 64 20 2b 20 32 29  if ((optind + 2)
bfa0: 20 21 3d 20 61 72 67 63 29 20 7b 0a 09 09 69 66   != argc) {...if
bfb0: 20 28 28 6f 70 74 69 6e 64 20 2b 20 32 29 20 3c   ((optind + 2) <
bfc0: 20 61 72 67 63 29 20 7b 0a 09 09 09 66 70 72 69   argc) {....fpri
bfd0: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54 6f 6f  ntf(stderr, "Too
bfe0: 20 6d 61 6e 79 20 61 72 67 75 6d 65 6e 74 73 5c   many arguments\
bff0: 6e 22 29 3b 0a 09 09 7d 20 65 6c 73 65 20 7b 0a  n");...} else {.
c000: 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
c010: 72 2c 20 22 4d 69 73 73 69 6e 67 20 63 61 63 68  r, "Missing cach
c020: 65 64 69 72 20 6f 72 20 6d 6f 75 6e 74 70 6f 69  edir or mountpoi
c030: 6e 74 5c 6e 22 29 3b 0a 09 09 7d 0a 0a 09 09 61  nt\n");...}....a
c040: 70 70 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28  ppfs_print_help(
c050: 73 74 64 65 72 72 29 3b 0a 0a 09 09 72 65 74 75  stderr);....retu
c060: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  rn(1);..}.../*..
c070: 20 2a 20 53 65 74 20 63 61 63 68 65 20 64 69 72   * Set cache dir
c080: 20 61 73 20 66 69 72 73 74 20 61 72 67 75 6d 65   as first argume
c090: 6e 74 20 28 74 68 65 20 22 64 65 76 69 63 65 22  nt (the "device"
c0a0: 2c 20 65 73 73 65 6e 74 69 61 6c 6c 79 29 0a 09  , essentially)..
c0b0: 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65   */..appfs_cache
c0c0: 64 69 72 20 3d 20 61 72 67 76 5b 6f 70 74 69 6e  dir = argv[optin
c0d0: 64 5d 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 50 61 73  d];.../*.. * Pas
c0e0: 73 20 74 68 65 20 72 65 6d 61 69 6e 69 6e 67 20  s the remaining 
c0f0: 61 72 67 75 6d 65 6e 74 20 74 6f 20 46 55 53 45  argument to FUSE
c100: 20 61 73 20 74 68 65 20 64 69 72 65 63 74 6f 72   as the director
c110: 79 0a 09 20 2a 2f 0a 09 66 75 73 65 5f 6f 70 74  y.. */..fuse_opt
c120: 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c  _parse(args, NUL
c130: 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  L, NULL, NULL);.
c140: 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72  .fuse_opt_add_ar
c150: 67 28 61 72 67 73 2c 20 61 72 67 76 5b 6f 70 74  g(args, argv[opt
c160: 69 6e 64 20 2b 20 31 5d 29 3b 0a 0a 09 72 65 74  ind + 1]);...ret
c170: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 20  urn(0);.}.../*. 
c180: 2a 20 46 55 53 45 20 6f 70 65 72 61 74 69 6f 6e  * FUSE operation
c190: 73 20 73 74 72 75 63 74 75 72 65 0a 20 2a 2f 0a  s structure. */.
c1a0: 73 74 61 74 69 63 20 73 74 72 75 63 74 20 66 75  static struct fu
c1b0: 73 65 5f 6f 70 65 72 61 74 69 6f 6e 73 20 61 70  se_operations ap
c1c0: 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 20 3d  pfs_operations =
c1d0: 20 7b 0a 09 2e 67 65 74 61 74 74 72 20 20 20 3d   {...getattr   =
c1e0: 20 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74 61   appfs_fuse_geta
c1f0: 74 74 72 2c 0a 09 2e 72 65 61 64 64 69 72 20 20  ttr,...readdir  
c200: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65   = appfs_fuse_re
c210: 61 64 64 69 72 2c 0a 09 2e 72 65 61 64 6c 69 6e  addir,...readlin
c220: 6b 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f  k  = appfs_fuse_
c230: 72 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f 70 65 6e  readlink,...open
c240: 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75        = appfs_fu
c250: 73 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65 6c 65 61  se_open,...relea
c260: 73 65 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73  se   = appfs_fus
c270: 65 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65 61 64 20  e_close,...read 
c280: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
c290: 65 5f 72 65 61 64 2c 0a 09 2e 77 72 69 74 65 20  e_read,...write 
c2a0: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
c2b0: 5f 77 72 69 74 65 2c 0a 09 2e 6d 6b 6e 6f 64 20  _write,...mknod 
c2c0: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
c2d0: 5f 6d 6b 6e 6f 64 2c 0a 09 2e 63 72 65 61 74 65  _mknod,...create
c2e0: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
c2f0: 5f 63 72 65 61 74 65 2c 0a 09 2e 74 72 75 6e 63  _create,...trunc
c300: 61 74 65 20 20 3d 20 61 70 70 66 73 5f 66 75 73  ate  = appfs_fus
c310: 65 5f 74 72 75 6e 63 61 74 65 2c 0a 09 2e 75 6e  e_truncate,...un
c320: 6c 69 6e 6b 20 20 20 20 3d 20 61 70 70 66 73 5f  link    = appfs_
c330: 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69  fuse_unlink_rmdi
c340: 72 2c 0a 09 2e 72 6d 64 69 72 20 20 20 20 20 3d  r,...rmdir     =
c350: 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69   appfs_fuse_unli
c360: 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 6d 6b 64 69  nk_rmdir,...mkdi
c370: 72 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  r     = appfs_fu
c380: 73 65 5f 6d 6b 64 69 72 2c 0a 09 2e 63 68 6d 6f  se_mkdir,...chmo
c390: 64 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  d     = appfs_fu
c3a0: 73 65 5f 63 68 6d 6f 64 2c 0a 09 2e 73 79 6d 6c  se_chmod,...syml
c3b0: 69 6e 6b 20 20 20 3d 20 61 70 70 66 73 5f 66 75  ink   = appfs_fu
c3c0: 73 65 5f 73 79 6d 6c 69 6e 6b 2c 0a 7d 3b 0a 0a  se_symlink,.};..
c3d0: 2f 2a 0a 20 2a 20 45 6e 74 72 79 20 70 6f 69 6e  /*. * Entry poin
c3e0: 74 20 69 6e 74 6f 20 74 68 69 73 20 70 72 6f 67  t into this prog
c3f0: 72 61 6d 2e 0a 20 2a 2f 0a 69 6e 74 20 6d 61 69  ram.. */.int mai
c400: 6e 28 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72  n(int argc, char
c410: 20 2a 2a 61 72 67 76 29 20 7b 0a 09 54 63 6c 5f   **argv) {..Tcl_
c420: 49 6e 74 65 72 70 20 2a 74 65 73 74 5f 69 6e 74  Interp *test_int
c430: 65 72 70 3b 0a 09 63 68 61 72 20 2a 74 65 73 74  erp;..char *test
c440: 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 3b 0a 09  _interp_error;..
c450: 73 74 72 75 63 74 20 66 75 73 65 5f 61 72 67 73  struct fuse_args
c460: 20 61 72 67 73 20 3d 20 46 55 53 45 5f 41 52 47   args = FUSE_ARG
c470: 53 5f 49 4e 49 54 28 30 2c 20 4e 55 4c 4c 29 3b  S_INIT(0, NULL);
c480: 0a 09 73 74 72 75 63 74 20 72 6c 69 6d 69 74 20  ..struct rlimit 
c490: 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65  number_open_file
c4a0: 73 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f  s;..int pthread_
c4b0: 72 65 74 2c 20 61 6f 70 5f 72 65 74 2c 20 72 6c  ret, aop_ret, rl
c4c0: 69 6d 69 74 5f 72 65 74 3b 0a 09 76 6f 69 64 20  imit_ret;..void 
c4d0: 2a 73 69 67 6e 61 6c 5f 72 65 74 3b 0a 09 63 68  *signal_ret;..ch
c4e0: 61 72 20 2a 61 72 67 76 30 3b 0a 09 72 6c 69 6d  ar *argv0;..rlim
c4f0: 5f 74 20 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66  _t number_open_f
c500: 69 6c 65 73 5f 6d 61 78 3b 0a 0a 09 2f 2a 0a 09  iles_max;.../*..
c510: 20 2a 20 53 6b 69 70 20 70 61 73 73 65 64 20 70   * Skip passed p
c520: 72 6f 67 72 61 6d 20 6e 61 6d 65 0a 09 20 2a 2f  rogram name.. */
c530: 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20 30 20  ..if (argc == 0 
c540: 7c 7c 20 61 72 67 76 20 3d 3d 20 4e 55 4c 4c 29  || argv == NULL)
c550: 20 7b 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a   {...return(1);.
c560: 09 7d 0a 0a 09 61 72 67 76 30 20 3d 20 61 72 67  .}...argv0 = arg
c570: 76 5b 30 5d 3b 0a 0a 09 61 72 67 63 2d 2d 3b 0a  v[0];...argc--;.
c580: 09 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09 20  .argv++;.../*.. 
c590: 2a 20 53 65 74 20 61 70 70 72 6f 70 72 69 61 74  * Set appropriat
c5a0: 65 20 75 6d 61 73 6b 0a 09 20 2a 2f 0a 09 75 6d  e umask.. */..um
c5b0: 61 73 6b 28 30 32 32 29 3b 0a 0a 09 2f 2a 0a 09  ask(022);.../*..
c5c0: 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61   * Set global va
c5d0: 72 69 61 62 6c 65 73 2c 20 74 68 65 73 65 20 73  riables, these s
c5e0: 68 6f 75 6c 64 20 62 65 20 63 6f 6e 66 69 67 75  hould be configu
c5f0: 72 61 74 69 6f 6e 20 6f 70 74 69 6f 6e 73 2e 0a  ration options..
c600: 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68  . */..appfs_cach
c610: 65 64 69 72 20 3d 20 41 50 50 46 53 5f 43 41 43  edir = APPFS_CAC
c620: 48 45 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20 2a 20  HEDIR;.../*.. * 
c630: 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69 61  Set global varia
c640: 62 6c 65 20 66 6f 72 20 22 62 6f 6f 74 20 74 69  ble for "boot ti
c650: 6d 65 22 20 74 6f 20 73 65 74 20 61 20 74 69 6d  me" to set a tim
c660: 65 20 6f 6e 20 64 69 72 65 63 74 6f 72 69 65 73  e on directories
c670: 0a 09 20 2a 20 74 68 61 74 20 77 65 20 66 61 6b  .. * that we fak
c680: 65 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 62  e... */..appfs_b
c690: 6f 6f 74 74 69 6d 65 20 3d 20 74 69 6d 65 28 4e  oottime = time(N
c6a0: 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52  ULL);.../*.. * R
c6b0: 65 67 69 73 74 65 72 20 22 73 68 61 31 22 20 61  egister "sha1" a
c6c0: 6e 64 20 22 61 70 70 66 73 64 22 20 70 61 63 6b  nd "appfsd" pack
c6d0: 61 67 65 20 77 69 74 68 20 6c 69 62 74 63 6c 20  age with libtcl 
c6e0: 73 6f 20 74 68 61 74 20 61 6e 79 20 6e 65 77 0a  so that any new.
c6f0: 09 20 2a 20 69 6e 74 65 72 70 72 65 74 65 72 73  . * interpreters
c700: 20 63 72 65 61 74 65 64 20 28 77 68 69 63 68 20   created (which 
c710: 61 72 65 20 64 6f 6e 65 20 64 79 6e 61 6d 69 63  are done dynamic
c720: 61 6c 6c 79 20 62 79 20 46 55 53 45 29 20 63 61  ally by FUSE) ca
c730: 6e 20 68 61 76 65 0a 09 20 2a 20 74 68 65 20 61  n have.. * the a
c740: 70 70 72 6f 70 72 69 61 74 65 20 63 6f 6e 66 69  ppropriate confi
c750: 67 75 72 61 74 69 6f 6e 20 64 6f 6e 65 20 61 75  guration done au
c760: 74 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 09 20 2a  tomatically... *
c770: 2f 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61 63  /..Tcl_StaticPac
c780: 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 73 68 61 31  kage(NULL, "sha1
c790: 22 2c 20 53 68 61 31 5f 49 6e 69 74 2c 20 4e 55  ", Sha1_Init, NU
c7a0: 4c 4c 29 3b 0a 09 54 63 6c 5f 53 74 61 74 69 63  LL);..Tcl_Static
c7b0: 50 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 61  Package(NULL, "a
c7c0: 70 70 66 73 64 22 2c 20 41 70 70 66 73 64 5f 49  ppfsd", Appfsd_I
c7d0: 6e 69 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a  nit, NULL);.../*
c7e0: 0a 09 20 2a 20 43 72 65 61 74 65 20 61 20 74 68  .. * Create a th
c7f0: 72 65 61 64 2d 73 70 65 63 69 66 69 63 2d 64 61  read-specific-da
c800: 74 61 20 28 54 53 44 29 20 6b 65 79 20 66 6f 72  ta (TSD) key for
c810: 20 65 61 63 68 20 74 68 72 65 61 64 20 74 6f 20   each thread to 
c820: 72 65 66 65 72 0a 09 20 2a 20 74 6f 20 69 74 73  refer.. * to its
c830: 20 6f 77 6e 20 54 63 6c 20 69 6e 74 65 72 70 72   own Tcl interpr
c840: 65 74 65 72 2e 20 20 54 63 6c 20 69 6e 74 65 72  eter.  Tcl inter
c850: 70 72 65 74 65 72 73 20 6d 75 73 74 20 62 65 20  preters must be 
c860: 75 6e 69 71 75 65 20 70 65 72 0a 09 20 2a 20 74  unique per.. * t
c870: 68 72 65 61 64 20 61 6e 64 20 6e 65 77 20 74 68  hread and new th
c880: 72 65 61 64 73 20 61 72 65 20 64 79 6e 61 6d 69  reads are dynami
c890: 63 61 6c 6c 79 20 63 72 65 61 74 65 64 20 62 79  cally created by
c8a0: 20 46 55 53 45 2e 0a 09 20 2a 2f 0a 09 70 74 68   FUSE... */..pth
c8b0: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
c8c0: 61 64 5f 6b 65 79 5f 63 72 65 61 74 65 28 26 69  ad_key_create(&i
c8d0: 6e 74 65 72 70 4b 65 79 2c 20 61 70 70 66 73 5f  nterpKey, appfs_
c8e0: 74 65 72 6d 69 6e 61 74 65 5f 69 6e 74 65 72 70  terminate_interp
c8f0: 5f 61 6e 64 5f 74 68 72 65 61 64 29 3b 0a 09 69  _and_thread);..i
c900: 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21  f (pthread_ret !
c910: 3d 20 30 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  = 0) {...fprintf
c920: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
c930: 20 74 6f 20 63 72 65 61 74 65 20 54 53 44 20 6b   to create TSD k
c940: 65 79 20 66 6f 72 20 54 63 6c 2e 20 20 41 62 6f  ey for Tcl.  Abo
c950: 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72  rting.\n");....r
c960: 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2f  eturn(1);..}.../
c970: 2a 0a 09 20 2a 20 4d 61 6e 75 61 6c 6c 79 20 73  *.. * Manually s
c980: 70 65 63 69 66 79 20 63 61 63 68 65 20 64 69 72  pecify cache dir
c990: 65 63 74 6f 72 79 2c 20 77 69 74 68 6f 75 74 20  ectory, without 
c9a0: 46 55 53 45 20 63 61 6c 6c 62 61 63 6b 0a 09 20  FUSE callback.. 
c9b0: 2a 20 54 68 69 73 20 6f 70 74 69 6f 6e 20 6f 6e  * This option on
c9c0: 6c 79 20 77 6f 72 6b 73 20 77 68 65 6e 20 6e 6f  ly works when no
c9d0: 74 20 75 73 69 6e 67 20 46 55 53 45 2c 20 73 69  t using FUSE, si
c9e0: 6e 63 65 20 77 65 0a 09 20 2a 20 64 6f 20 6e 6f  nce we.. * do no
c9f0: 74 20 70 72 6f 63 65 73 73 20 69 74 20 77 69 74  t process it wit
ca00: 68 20 46 55 53 45 73 20 6f 70 74 69 6f 6e 20 70  h FUSEs option p
ca10: 72 6f 63 65 73 73 69 6e 67 2e 0a 09 20 2a 2f 0a  rocessing... */.
ca20: 09 69 66 20 28 61 72 67 63 20 3e 3d 20 32 29 20  .if (argc >= 2) 
ca30: 7b 0a 09 09 69 66 20 28 73 74 72 63 6d 70 28 61  {...if (strcmp(a
ca40: 72 67 76 5b 30 5d 2c 20 22 2d 2d 63 61 63 68 65  rgv[0], "--cache
ca50: 64 69 72 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09  dir") == 0) {...
ca60: 09 61 70 70 66 73 5f 63 61 63 68 65 64 69 72 20  .appfs_cachedir 
ca70: 3d 20 73 74 72 64 75 70 28 61 72 67 76 5b 31 5d  = strdup(argv[1]
ca80: 29 3b 0a 0a 09 09 09 61 72 67 63 20 2d 3d 20 32  );.....argc -= 2
ca90: 3b 0a 09 09 09 61 72 67 76 20 2b 3d 20 32 3b 0a  ;....argv += 2;.
caa0: 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20  ..}..}.../*.. * 
cab0: 53 51 4c 69 74 65 33 20 6d 6f 64 65 2c 20 66 6f  SQLite3 mode, fo
cac0: 72 20 72 75 6e 6e 69 6e 67 20 72 61 77 20 53 51  r running raw SQ
cad0: 4c 20 61 67 61 69 6e 73 74 20 74 68 65 20 63 61  L against the ca
cae0: 63 68 65 20 64 61 74 61 62 61 73 65 0a 09 20 2a  che database.. *
caf0: 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20 32  /..if (argc == 2
cb00: 20 26 26 20 73 74 72 63 6d 70 28 61 72 67 76 5b   && strcmp(argv[
cb10: 30 5d 2c 20 22 2d 2d 73 71 6c 69 74 65 33 22 29  0], "--sqlite3")
cb20: 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72   == 0) {...retur
cb30: 6e 28 61 70 70 66 73 5f 73 71 6c 69 74 65 33 28  n(appfs_sqlite3(
cb40: 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 0a 09  argv[1]));..}...
cb50: 2f 2a 0a 09 20 2a 20 54 63 6c 20 6d 6f 64 65 2c  /*.. * Tcl mode,
cb60: 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77   for running raw
cb70: 20 54 63 6c 20 69 6e 20 74 68 65 20 73 61 6d 65   Tcl in the same
cb80: 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 41 70 70   environment App
cb90: 46 53 64 20 77 6f 75 6c 64 0a 09 20 2a 20 72 75  FSd would.. * ru
cba0: 6e 20 63 6f 64 65 2e 0a 09 20 2a 2f 0a 09 69 66  n code... */..if
cbb0: 20 28 61 72 67 63 20 3d 3d 20 32 20 26 26 20 73   (argc == 2 && s
cbc0: 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20 22  trcmp(argv[0], "
cbd0: 2d 2d 74 63 6c 22 29 20 3d 3d 20 30 29 20 7b 0a  --tcl") == 0) {.
cbe0: 09 09 72 65 74 75 72 6e 28 61 70 70 66 73 5f 74  ..return(appfs_t
cbf0: 63 6c 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d  cl(argv[1]));..}
cc00: 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 67 69 73 74  .../*.. * Regist
cc10: 65 72 20 61 20 73 69 67 6e 61 6c 20 68 61 6e 64  er a signal hand
cc20: 6c 65 72 20 66 6f 72 20 68 6f 74 2d 72 65 73 74  ler for hot-rest
cc30: 61 72 74 20 72 65 71 75 65 73 74 73 0a 09 20 2a  art requests.. *
cc40: 2f 0a 09 73 69 67 6e 61 6c 5f 72 65 74 20 3d 20  /..signal_ret = 
cc50: 73 69 67 6e 61 6c 28 53 49 47 48 55 50 2c 20 61  signal(SIGHUP, a
cc60: 70 70 66 73 5f 73 69 67 6e 61 6c 5f 68 61 6e 64  ppfs_signal_hand
cc70: 6c 65 72 29 3b 0a 09 69 66 20 28 73 69 67 6e 61  ler);..if (signa
cc80: 6c 5f 72 65 74 20 3d 3d 20 53 49 47 5f 45 52 52  l_ret == SIG_ERR
cc90: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
cca0: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f  derr, "Unable to
ccb0: 20 69 6e 73 74 61 6c 6c 20 73 69 67 6e 61 6c 20   install signal 
ccc0: 68 61 6e 64 6c 65 72 20 66 6f 72 20 68 6f 74 2d  handler for hot-
ccd0: 72 65 73 74 61 72 74 5c 6e 22 29 3b 0a 09 09 66  restart\n");...f
cce0: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
ccf0: 48 6f 74 2d 72 65 73 74 61 72 74 20 77 69 6c 6c  Hot-restart will
cd00: 20 6e 6f 74 20 62 65 20 61 76 61 69 6c 61 62 6c   not be availabl
cd10: 65 2e 5c 6e 22 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a  e.\n");..}.../*.
cd20: 09 20 2a 20 50 61 72 73 65 20 63 6f 6d 6d 61 6e  . * Parse comman
cd30: 64 20 6c 69 6e 65 20 61 72 67 75 6d 65 6e 74 73  d line arguments
cd40: 0a 09 20 2a 2f 0a 09 2f 2a 2a 0a 09 20 2a 2a 20  .. */../**.. ** 
cd50: 52 65 73 74 6f 72 65 20 61 72 67 63 2f 61 72 67  Restore argc/arg
cd60: 76 20 74 6f 20 6f 72 69 67 69 6e 61 6c 20 76 61  v to original va
cd70: 6c 75 65 73 2c 20 72 65 70 6c 61 63 69 6e 67 20  lues, replacing 
cd80: 61 72 67 76 5b 30 5d 20 69 6e 20 63 61 73 65 0a  argv[0] in case.
cd90: 09 20 2a 2a 20 69 74 20 77 61 73 20 6d 6f 69 66  . ** it was moif
cda0: 69 65 64 20 62 79 20 2d 2d 63 61 63 68 65 64 69  ied by --cachedi
cdb0: 72 20 6f 70 74 69 6f 6e 2e 0a 09 20 2a 2a 2f 0a  r option... **/.
cdc0: 09 61 72 67 63 2b 2b 3b 0a 09 61 72 67 76 2d 2d  .argc++;..argv--
cdd0: 3b 0a 09 61 72 67 76 5b 30 5d 20 3d 20 61 72 67  ;..argv[0] = arg
cde0: 76 30 3b 0a 0a 09 2f 2a 2a 0a 09 20 2a 2a 20 50  v0;.../**.. ** P
cdf0: 65 72 66 6f 72 6d 20 74 68 65 20 61 72 67 75 6d  erform the argum
ce00: 65 6e 74 20 70 61 72 73 69 6e 67 0a 09 20 2a 2a  ent parsing.. **
ce10: 2f 0a 09 61 6f 70 5f 72 65 74 20 3d 20 61 70 70  /..aop_ret = app
ce20: 66 73 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67  fs_opt_parse(arg
ce30: 63 2c 20 61 72 67 76 2c 20 26 61 72 67 73 29 3b  c, argv, &args);
ce40: 0a 09 69 66 20 28 61 6f 70 5f 72 65 74 20 21 3d  ..if (aop_ret !=
ce50: 20 30 29 20 7b 0a 09 09 69 66 20 28 61 6f 70 5f   0) {...if (aop_
ce60: 72 65 74 20 3c 20 30 29 20 7b 0a 09 09 09 72 65  ret < 0) {....re
ce70: 74 75 72 6e 28 30 29 3b 0a 09 09 7d 0a 0a 09 09  turn(0);...}....
ce80: 72 65 74 75 72 6e 28 61 6f 70 5f 72 65 74 29 3b  return(aop_ret);
ce90: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72 65  ..}.../*.. * Cre
cea0: 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70  ate a Tcl interp
ceb0: 72 65 74 65 72 20 6a 75 73 74 20 74 6f 20 76 65  reter just to ve
cec0: 72 69 66 79 20 74 68 61 74 20 74 68 69 6e 67 73  rify that things
ced0: 20 61 72 65 20 69 6e 20 77 6f 72 6b 69 6e 67 20   are in working 
cee0: 0a 09 20 2a 20 6f 72 64 65 72 20 62 65 66 6f 72  .. * order befor
cef0: 65 20 77 65 20 62 65 63 6f 6d 65 20 61 20 64 61  e we become a da
cf00: 65 6d 6f 6e 2e 0a 09 20 2a 2f 0a 09 74 65 73 74  emon... */..test
cf10: 5f 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f  _interp = appfs_
cf20: 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70  create_TclInterp
cf30: 28 26 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72  (&test_interp_er
cf40: 72 6f 72 29 3b 0a 09 69 66 20 28 74 65 73 74 5f  ror);..if (test_
cf50: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
cf60: 7b 0a 09 09 69 66 20 28 74 65 73 74 5f 69 6e 74  {...if (test_int
cf70: 65 72 70 5f 65 72 72 6f 72 20 3d 3d 20 4e 55 4c  erp_error == NUL
cf80: 4c 29 20 7b 0a 09 09 09 74 65 73 74 5f 69 6e 74  L) {....test_int
cf90: 65 72 70 5f 65 72 72 6f 72 20 3d 20 22 55 6e 6b  erp_error = "Unk
cfa0: 6e 6f 77 6e 20 65 72 72 6f 72 22 3b 0a 09 09 7d  nown error";...}
cfb0: 0a 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ....fprintf(stde
cfc0: 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69  rr, "Unable to i
cfd0: 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 69 6e  nitialize Tcl in
cfe0: 74 65 72 70 72 65 74 65 72 20 66 6f 72 20 41 70  terpreter for Ap
cff0: 70 46 53 64 3a 5c 6e 22 29 3b 0a 09 09 66 70 72  pFSd:\n");...fpr
d000: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25 73  intf(stderr, "%s
d010: 5c 6e 22 2c 20 74 65 73 74 5f 69 6e 74 65 72 70  \n", test_interp
d020: 5f 65 72 72 6f 72 29 3b 0a 0a 09 09 72 65 74 75  _error);....retu
d030: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f  rn(1);..}...Tcl_
d040: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 74 65 73  DeleteInterp(tes
d050: 74 5f 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20  t_interp);...if 
d060: 28 61 70 70 66 73 5f 74 68 72 65 61 64 65 64 5f  (appfs_threaded_
d070: 74 63 6c 29 20 7b 0a 09 09 54 63 6c 5f 46 69 6e  tcl) {...Tcl_Fin
d080: 61 6c 69 7a 65 4e 6f 74 69 66 69 65 72 28 4e 55  alizeNotifier(NU
d090: 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  LL);..}.../*.. *
d0a0: 20 49 6e 63 72 65 61 73 65 20 72 65 73 6f 75 72   Increase resour
d0b0: 63 65 20 6c 69 6d 69 74 73 20 66 6f 72 20 6e 75  ce limits for nu
d0c0: 6d 62 65 72 20 6f 66 20 6f 70 65 6e 20 66 69 6c  mber of open fil
d0d0: 65 73 0a 09 20 2a 20 74 6f 20 74 68 65 20 6d 61  es.. * to the ma
d0e0: 78 69 6d 75 6d 20 76 61 6c 75 65 73 2c 20 73 69  ximum values, si
d0f0: 6e 63 65 20 77 65 20 6d 61 79 20 62 65 20 61 73  nce we may be as
d100: 6b 65 64 20 74 6f 0a 09 20 2a 20 68 6f 6c 64 20  ked to.. * hold 
d110: 6f 70 65 6e 20 6d 61 6e 79 20 66 69 6c 65 73 20  open many files 
d120: 6f 6e 20 62 65 68 61 6c 66 20 6f 66 20 6d 61 6e  on behalf of man
d130: 79 20 6f 74 68 65 72 20 70 72 6f 63 65 73 73 65  y other processe
d140: 73 0a 09 20 2a 2f 0a 09 6e 75 6d 62 65 72 5f 6f  s.. */..number_o
d150: 70 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f 63  pen_files.rlim_c
d160: 75 72 20 3d 20 6e 75 6d 62 65 72 5f 6f 70 65 6e  ur = number_open
d170: 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f 6d 61 78 20  _files.rlim_max 
d180: 3d 20 52 4c 49 4d 5f 49 4e 46 49 4e 49 54 59 3b  = RLIM_INFINITY;
d190: 0a 0a 09 72 6c 69 6d 69 74 5f 72 65 74 20 3d 20  ...rlimit_ret = 
d1a0: 73 65 74 72 6c 69 6d 69 74 28 52 4c 49 4d 49 54  setrlimit(RLIMIT
d1b0: 5f 4e 4f 46 49 4c 45 2c 20 26 6e 75 6d 62 65 72  _NOFILE, &number
d1c0: 5f 6f 70 65 6e 5f 66 69 6c 65 73 29 3b 0a 0a 09  _open_files);...
d1d0: 69 66 20 28 72 6c 69 6d 69 74 5f 72 65 74 20 21  if (rlimit_ret !
d1e0: 3d 20 30 29 20 7b 0a 09 09 72 6c 69 6d 69 74 5f  = 0) {...rlimit_
d1f0: 72 65 74 20 3d 20 67 65 74 72 6c 69 6d 69 74 28  ret = getrlimit(
d200: 52 4c 49 4d 49 54 5f 4e 4f 46 49 4c 45 2c 20 26  RLIMIT_NOFILE, &
d210: 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65  number_open_file
d220: 73 29 3b 0a 09 09 69 66 20 28 72 6c 69 6d 69 74  s);...if (rlimit
d230: 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09 09 09  _ret == 0) {....
d240: 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65  number_open_file
d250: 73 5f 6d 61 78 20 3d 20 6e 75 6d 62 65 72 5f 6f  s_max = number_o
d260: 70 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f 6d  pen_files.rlim_m
d270: 61 78 3b 0a 0a 09 09 09 69 66 20 28 6e 75 6d 62  ax;.....if (numb
d280: 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 5f 6d 61  er_open_files_ma
d290: 78 20 3c 20 28 31 30 32 34 20 2a 20 31 30 32 34  x < (1024 * 1024
d2a0: 29 29 20 7b 0a 09 09 09 09 6e 75 6d 62 65 72 5f  )) {.....number_
d2b0: 6f 70 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f  open_files.rlim_
d2c0: 63 75 72 20 3d 20 6e 75 6d 62 65 72 5f 6f 70 65  cur = number_ope
d2d0: 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f 6d 61 78  n_files.rlim_max
d2e0: 20 3d 20 31 30 32 34 20 2a 20 31 30 32 34 3b 0a   = 1024 * 1024;.
d2f0: 0a 09 09 09 09 72 6c 69 6d 69 74 5f 72 65 74 20  .....rlimit_ret 
d300: 3d 20 73 65 74 72 6c 69 6d 69 74 28 52 4c 49 4d  = setrlimit(RLIM
d310: 49 54 5f 4e 4f 46 49 4c 45 2c 20 26 6e 75 6d 62  IT_NOFILE, &numb
d320: 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 29 3b 0a  er_open_files);.
d330: 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09  ...} else {.....
d340: 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65  number_open_file
d350: 73 2e 72 6c 69 6d 5f 63 75 72 20 3d 20 6e 75 6d  s.rlim_cur = num
d360: 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 2e 72  ber_open_files.r
d370: 6c 69 6d 5f 6d 61 78 3b 0a 09 09 09 7d 0a 0a 09  lim_max;....}...
d380: 09 09 72 6c 69 6d 69 74 5f 72 65 74 20 3d 20 73  ..rlimit_ret = s
d390: 65 74 72 6c 69 6d 69 74 28 52 4c 49 4d 49 54 5f  etrlimit(RLIMIT_
d3a0: 4e 4f 46 49 4c 45 2c 20 26 6e 75 6d 62 65 72 5f  NOFILE, &number_
d3b0: 6f 70 65 6e 5f 66 69 6c 65 73 29 3b 0a 0a 09 09  open_files);....
d3c0: 09 69 66 20 28 72 6c 69 6d 69 74 5f 72 65 74 20  .if (rlimit_ret 
d3d0: 21 3d 20 30 20 26 26 20 6e 75 6d 62 65 72 5f 6f  != 0 && number_o
d3e0: 70 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f 63  pen_files.rlim_c
d3f0: 75 72 20 21 3d 20 6e 75 6d 62 65 72 5f 6f 70 65  ur != number_ope
d400: 6e 5f 66 69 6c 65 73 5f 6d 61 78 29 20 7b 0a 09  n_files_max) {..
d410: 09 09 09 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66  ...number_open_f
d420: 69 6c 65 73 2e 72 6c 69 6d 5f 63 75 72 20 3d 20  iles.rlim_cur = 
d430: 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65  number_open_file
d440: 73 2e 72 6c 69 6d 5f 6d 61 78 20 3d 20 6e 75 6d  s.rlim_max = num
d450: 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 5f 6d  ber_open_files_m
d460: 61 78 3b 0a 0a 09 09 09 09 73 65 74 72 6c 69 6d  ax;......setrlim
d470: 69 74 28 52 4c 49 4d 49 54 5f 4e 4f 46 49 4c 45  it(RLIMIT_NOFILE
d480: 2c 20 26 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66  , &number_open_f
d490: 69 6c 65 73 29 3b 0a 09 09 09 7d 0a 09 09 7d 0a  iles);....}...}.
d4a0: 09 7d 0a 0a 0a 09 2f 2a 0a 09 20 2a 20 45 6e 74  .}..../*.. * Ent
d4b0: 65 72 20 74 68 65 20 46 55 53 45 20 6d 61 69 6e  er the FUSE main
d4c0: 20 6c 6f 6f 70 20 2d 2d 20 74 68 69 73 20 77 69   loop -- this wi
d4d0: 6c 6c 20 70 72 6f 63 65 73 73 20 61 6e 79 20 61  ll process any a
d4e0: 72 67 75 6d 65 6e 74 73 0a 09 20 2a 20 61 6e 64  rguments.. * and
d4f0: 20 73 74 61 72 74 20 73 65 72 76 69 63 69 6e 67   start servicing
d500: 20 72 65 71 75 65 73 74 73 2e 0a 09 20 2a 2f 0a   requests... */.
d510: 09 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72  .appfs_fuse_star
d520: 74 65 64 20 3d 20 31 3b 0a 09 72 65 74 75 72 6e  ted = 1;..return
d530: 28 66 75 73 65 5f 6d 61 69 6e 28 61 72 67 73 2e  (fuse_main(args.
d540: 61 72 67 63 2c 20 61 72 67 73 2e 61 72 67 76 2c  argc, args.argv,
d550: 20 26 61 70 70 66 73 5f 6f 70 65 72 61 74 69 6f   &appfs_operatio
d560: 6e 73 2c 20 4e 55 4c 4c 29 29 3b 0a 7d 0a        ns, NULL));.}.