Hex Artifact Content

Artifact 33db21bdfd28c12f274c4253fc4719aaade9fb6e:


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 55 3b 20 2f 2a 20 46 4e 56 2d 31 61 20 33  61U; /* FNV-1a 3
3b60: 32 2d 62 69 74 20 6f 66 66 73 65 74 5f 62 61 73  2-bit offset_bas
3b70: 69 73 20 2a 2f 0a 0a 09 66 6f 72 20 28 70 20 3d  is */...for (p =
3b80: 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20   (unsigned char 
3b90: 2a 29 20 70 61 74 68 3b 20 2a 70 3b 20 70 2b 2b  *) path; *p; p++
3ba0: 29 20 7b 0a 09 09 72 65 74 76 61 6c 20 5e 3d 20  ) {...retval ^= 
3bb0: 28 69 6e 74 29 20 2a 70 3b 0a 23 69 66 20 30 0a  (int) *p;.#if 0.
3bc0: 09 09 72 65 74 76 61 6c 20 2a 3d 20 31 36 37 37  ..retval *= 1677
3bd0: 37 36 31 39 3b 20 2f 2a 20 46 4e 56 2d 31 61 20  7619; /* FNV-1a 
3be0: 33 32 2d 62 69 74 20 70 72 69 6d 65 20 2a 2f 0a  32-bit prime */.
3bf0: 23 65 6c 73 65 0a 09 09 2f 2a 20 47 43 43 20 4f  #else.../* GCC O
3c00: 70 74 69 6d 69 7a 65 64 20 72 65 70 6c 61 63 65  ptimized replace
3c10: 6d 65 6e 74 20 2a 2f 0a 09 09 72 65 74 76 61 6c  ment */...retval
3c20: 20 2b 3d 20 28 72 65 74 76 61 6c 20 3c 3c 20 31   += (retval << 1
3c30: 29 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 34  ) + (retval << 4
3c40: 29 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 37  ) + (retval << 7
3c50: 29 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 38  ) + (retval << 8
3c60: 29 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 32  ) + (retval << 2
3c70: 34 29 3b 0a 23 65 6e 64 69 66 0a 09 7d 0a 0a 09  4);.#endif..}...
3c80: 69 66 20 28 75 69 64 20 3e 3d 20 30 29 20 7b 0a  if (uid >= 0) {.
3c90: 09 09 72 65 74 76 61 6c 20 2b 3d 20 75 69 64 3b  ..retval += uid;
3ca0: 0a 09 09 72 65 74 76 61 6c 2b 2b 3b 0a 09 7d 0a  ...retval++;..}.
3cb0: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 4c  ..APPFS_DEBUG("L
3cc0: 6f 6f 6b 65 64 20 75 70 20 69 6e 6f 64 65 20 6e  ooked up inode n
3cd0: 75 6d 62 65 72 20 66 6f 72 20 70 61 74 68 3d 25  umber for path=%
3ce0: 73 2c 75 69 64 3d 25 69 3a 20 25 75 22 2c 20 70  s,uid=%i: %u", p
3cf0: 61 74 68 2c 20 75 69 64 2c 20 72 65 74 76 61 6c  ath, uid, retval
3d00: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76  );...return(retv
3d10: 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 61  al);.}../*. * Ca
3d20: 63 68 65 20 47 65 74 20 50 61 74 68 20 49 6e 66  che Get Path Inf
3d30: 6f 20 6c 6f 6f 6b 75 70 73 20 66 6f 72 20 73 70  o lookups for sp
3d40: 65 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69  eed. */.static i
3d50: 6e 74 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74  nt appfs_get_pat
3d60: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74  h_info_cache_get
3d70: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
3d80: 68 2c 20 75 69 64 5f 74 20 75 69 64 2c 20 73 74  h, uid_t uid, st
3d90: 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69  ruct appfs_pathi
3da0: 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b  nfo *pathinfo) {
3db0: 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68  ..unsigned int h
3dc0: 61 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74  ash_idx;..int pt
3dd0: 68 72 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20  hread_ret;..int 
3de0: 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c  retval;...retval
3df0: 20 3d 20 31 3b 0a 0a 09 70 74 68 72 65 61 64 5f   = 1;...pthread_
3e00: 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75  ret = pthread_mu
3e10: 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f  tex_lock(&appfs_
3e20: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
3e30: 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68  mutex);..if (pth
3e40: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  read_ret != 0) {
3e50: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
3e60: 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70  Unable to lock p
3e70: 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d  ath_info cache m
3e80: 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74  utex !");....ret
3e90: 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 41 50  urn(-1);..}...AP
3ea0: 50 46 53 5f 44 45 42 55 47 28 22 4c 6f 6f 6b 69  PFS_DEBUG("Looki
3eb0: 6e 67 20 75 70 20 63 61 63 68 65 20 65 6e 74 72  ng up cache entr
3ec0: 79 20 66 6f 72 20 70 61 74 68 3d 25 73 2c 75 69  y for path=%s,ui
3ed0: 64 3d 25 6c 6c 69 2e 2e 2e 22 2c 20 70 61 74 68  d=%lli...", path
3ee0: 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69  , (long long) ui
3ef0: 64 29 3b 0a 0a 09 69 66 20 28 61 70 70 66 73 5f  d);...if (appfs_
3f00: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20  path_info_cache 
3f10: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 61 73  != NULL) {...has
3f20: 68 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f 67  h_idx = (appfs_g
3f30: 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61  et_path_inode(pa
3f40: 74 68 2c 20 75 69 64 29 29 20 25 20 61 70 70 66  th, uid)) % appf
3f50: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
3f60: 65 5f 73 69 7a 65 3b 0a 0a 09 09 69 66 20 28 61  e_size;....if (a
3f70: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
3f80: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f  ache[hash_idx]._
3f90: 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e 55  cache_path != NU
3fa0: 4c 4c 29 20 7b 0a 09 09 09 69 66 20 28 73 74 72  LL) {....if (str
3fb0: 63 6d 70 28 61 70 70 66 73 5f 70 61 74 68 5f 69  cmp(appfs_path_i
3fc0: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69  nfo_cache[hash_i
3fd0: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 2c  dx]._cache_path,
3fe0: 20 70 61 74 68 29 20 3d 3d 20 30 20 26 26 20 61   path) == 0 && a
3ff0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4000: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f  ache[hash_idx]._
4010: 63 61 63 68 65 5f 75 69 64 20 3d 3d 20 75 69 64  cache_uid == uid
4020: 29 20 7b 0a 09 09 09 09 72 65 74 76 61 6c 20 3d  ) {.....retval =
4030: 20 30 3b 0a 0a 09 09 09 09 6d 65 6d 63 70 79 28   0;......memcpy(
4040: 70 61 74 68 69 6e 66 6f 2c 20 26 61 70 70 66 73  pathinfo, &appfs
4050: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4060: 5b 68 61 73 68 5f 69 64 78 5d 2c 20 73 69 7a 65  [hash_idx], size
4070: 6f 66 28 2a 70 61 74 68 69 6e 66 6f 29 29 3b 0a  of(*pathinfo));.
4080: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 5f 63  ....pathinfo->_c
4090: 61 63 68 65 5f 70 61 74 68 20 3d 20 4e 55 4c 4c  ache_path = NULL
40a0: 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a 0a 09  ;....}...}..}...
40b0: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
40c0: 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f  hread_mutex_unlo
40d0: 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69  ck(&appfs_path_i
40e0: 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29  nfo_cache_mutex)
40f0: 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72  ;..if (pthread_r
4100: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50  et != 0) {...APP
4110: 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65  FS_DEBUG("Unable
4120: 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f   to unlock path_
4130: 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78  info cache mutex
4140: 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28   !");....return(
4150: 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65  -1);..}...if (re
4160: 74 76 61 6c 20 3d 3d 20 30 29 20 7b 0a 09 09 41  tval == 0) {...A
4170: 50 50 46 53 5f 44 45 42 55 47 28 22 43 61 63 68  PPFS_DEBUG("Cach
4180: 65 20 68 69 74 20 6f 6e 20 70 61 74 68 3d 25 73  e hit on path=%s
4190: 2c 75 69 64 3d 25 6c 6c 69 22 2c 20 70 61 74 68  ,uid=%lli", path
41a0: 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69  , (long long) ui
41b0: 64 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09  d);..} else {...
41c0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 61 63  APPFS_DEBUG("Cac
41d0: 68 65 20 6d 69 73 73 20 6f 6e 20 70 61 74 68 3d  he miss on path=
41e0: 25 73 2c 75 69 64 3d 25 6c 6c 69 22 2c 20 70 61  %s,uid=%lli", pa
41f0: 74 68 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20  th, (long long) 
4200: 75 69 64 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  uid);..}...retur
4210: 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74  n(retval);.}..st
4220: 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f  atic void appfs_
4230: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
4240: 63 68 65 5f 61 64 64 28 63 6f 6e 73 74 20 63 68  che_add(const ch
4250: 61 72 20 2a 70 61 74 68 2c 20 75 69 64 5f 74 20  ar *path, uid_t 
4260: 75 69 64 2c 20 73 74 72 75 63 74 20 61 70 70 66  uid, struct appf
4270: 73 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61 74 68  s_pathinfo *path
4280: 69 6e 66 6f 29 20 7b 0a 09 75 6e 73 69 67 6e 65  info) {..unsigne
4290: 64 20 69 6e 74 20 68 61 73 68 5f 69 64 78 3b 0a  d int hash_idx;.
42a0: 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74  .int pthread_ret
42b0: 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20  ;...pthread_ret 
42c0: 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  = pthread_mutex_
42d0: 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68  lock(&appfs_path
42e0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65  _info_cache_mute
42f0: 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64  x);..if (pthread
4300: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41  _ret != 0) {...A
4310: 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62  PPFS_DEBUG("Unab
4320: 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f  le to lock path_
4330: 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78  info cache mutex
4340: 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b   !");....return;
4350: 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73 5f  ..}...if (appfs_
4360: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20  path_info_cache 
4370: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 61 70 70  == NULL) {...app
4380: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4390: 68 65 20 3d 20 63 61 6c 6c 6f 63 28 61 70 70 66  he = calloc(appf
43a0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
43b0: 65 5f 73 69 7a 65 2c 20 73 69 7a 65 6f 66 28 2a  e_size, sizeof(*
43c0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
43d0: 63 61 63 68 65 29 29 3b 0a 09 7d 0a 0a 09 68 61  cache));..}...ha
43e0: 73 68 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f  sh_idx = (appfs_
43f0: 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70  get_path_inode(p
4400: 61 74 68 2c 20 75 69 64 29 29 20 25 20 61 70 70  ath, uid)) % app
4410: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4420: 68 65 5f 73 69 7a 65 3b 0a 0a 09 69 66 20 28 61  he_size;...if (a
4430: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4440: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f  ache[hash_idx]._
4450: 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e 55  cache_path != NU
4460: 4c 4c 29 20 7b 0a 09 09 66 72 65 65 28 61 70 70  LL) {...free(app
4470: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4480: 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61  he[hash_idx]._ca
4490: 63 68 65 5f 70 61 74 68 29 3b 0a 09 7d 0a 0a 09  che_path);..}...
44a0: 6d 65 6d 63 70 79 28 26 61 70 70 66 73 5f 70 61  memcpy(&appfs_pa
44b0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61  th_info_cache[ha
44c0: 73 68 5f 69 64 78 5d 2c 20 70 61 74 68 69 6e 66  sh_idx], pathinf
44d0: 6f 2c 20 73 69 7a 65 6f 66 28 2a 70 61 74 68 69  o, sizeof(*pathi
44e0: 6e 66 6f 29 29 3b 0a 0a 09 61 70 70 66 73 5f 70  nfo));...appfs_p
44f0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68  ath_info_cache[h
4500: 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f  ash_idx]._cache_
4510: 70 61 74 68 20 3d 20 73 74 72 64 75 70 28 70 61  path = strdup(pa
4520: 74 68 29 3b 0a 09 61 70 70 66 73 5f 70 61 74 68  th);..appfs_path
4530: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
4540: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64  _idx]._cache_uid
4550: 20 20 3d 20 75 69 64 3b 0a 0a 09 70 74 68 72 65    = uid;...pthre
4560: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  ad_ret = pthread
4570: 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61  _mutex_unlock(&a
4580: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4590: 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66  ache_mutex);..if
45a0: 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d   (pthread_ret !=
45b0: 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45   0) {...APPFS_DE
45c0: 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 75  BUG("Unable to u
45d0: 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20  nlock path_info 
45e0: 63 61 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b  cache mutex !");
45f0: 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a  ....return;..}..
4600: 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74  .return;.}..stat
4610: 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 67 65  ic void appfs_ge
4620: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
4630: 65 5f 72 6d 28 63 6f 6e 73 74 20 63 68 61 72 20  e_rm(const char 
4640: 2a 70 61 74 68 2c 20 75 69 64 5f 74 20 75 69 64  *path, uid_t uid
4650: 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e  ) {..unsigned in
4660: 74 20 68 61 73 68 5f 69 64 78 3b 0a 09 69 6e 74  t hash_idx;..int
4670: 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09   pthread_ret;...
4680: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
4690: 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b  hread_mutex_lock
46a0: 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  (&appfs_path_inf
46b0: 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a  o_cache_mutex);.
46c0: 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74  .if (pthread_ret
46d0: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53   != 0) {...APPFS
46e0: 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74  _DEBUG("Unable t
46f0: 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f  o lock path_info
4700: 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22 29   cache mutex !")
4710: 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a  ;....return;..}.
4720: 0a 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68  ..if (appfs_path
4730: 5f 69 6e 66 6f 5f 63 61 63 68 65 20 21 3d 20 4e  _info_cache != N
4740: 55 4c 4c 29 20 7b 0a 09 09 68 61 73 68 5f 69 64  ULL) {...hash_id
4750: 78 20 3d 20 28 61 70 70 66 73 5f 67 65 74 5f 70  x = (appfs_get_p
4760: 61 74 68 5f 69 6e 6f 64 65 28 70 61 74 68 2c 20  ath_inode(path, 
4770: 75 69 64 29 29 20 25 20 61 70 70 66 73 5f 70 61  uid)) % appfs_pa
4780: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69  th_info_cache_si
4790: 7a 65 3b 0a 0a 09 09 69 66 20 28 61 70 70 66 73  ze;....if (appfs
47a0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
47b0: 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68  [hash_idx]._cach
47c0: 65 5f 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20  e_path != NULL) 
47d0: 7b 0a 09 09 09 66 72 65 65 28 61 70 70 66 73 5f  {....free(appfs_
47e0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
47f0: 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65  hash_idx]._cache
4800: 5f 70 61 74 68 29 3b 0a 0a 09 09 09 61 70 70 66  _path);.....appf
4810: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4820: 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63  e[hash_idx]._cac
4830: 68 65 5f 70 61 74 68 20 3d 20 4e 55 4c 4c 3b 0a  he_path = NULL;.
4840: 09 09 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64  ..}..}...pthread
4850: 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d  _ret = pthread_m
4860: 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70  utex_unlock(&app
4870: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4880: 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28  he_mutex);..if (
4890: 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30  pthread_ret != 0
48a0: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
48b0: 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c  G("Unable to unl
48c0: 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61  ock path_info ca
48d0: 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a  che mutex !");..
48e0: 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72  ..return;..}...r
48f0: 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63  eturn;.}..static
4900: 20 76 6f 69 64 20 61 70 70 66 73 5f 67 65 74 5f   void appfs_get_
4910: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
4920: 66 6c 75 73 68 28 75 69 64 5f 74 20 75 69 64 2c  flush(uid_t uid,
4930: 20 69 6e 74 20 6e 65 77 5f 73 69 7a 65 29 20 7b   int new_size) {
4940: 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69  ..unsigned int i
4950: 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64  dx;..int pthread
4960: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
4970: 42 55 47 28 22 46 6c 75 73 68 69 6e 67 20 41 70  BUG("Flushing Ap
4980: 70 46 53 20 63 61 63 68 65 20 28 75 69 64 20 3d  pFS cache (uid =
4990: 20 25 6c 6c 69 2c 20 6e 65 77 5f 73 69 7a 65 20   %lli, new_size 
49a0: 3d 20 25 69 29 22 2c 20 28 6c 6f 6e 67 20 6c 6f  = %i)", (long lo
49b0: 6e 67 29 20 75 69 64 2c 20 6e 65 77 5f 73 69 7a  ng) uid, new_siz
49c0: 65 29 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65  e);...pthread_re
49d0: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65  t = pthread_mute
49e0: 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61  x_lock(&appfs_pa
49f0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75  th_info_cache_mu
4a00: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65  tex);..if (pthre
4a10: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
4a20: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
4a30: 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74  able to lock pat
4a40: 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74  h_info cache mut
4a50: 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72  ex !");....retur
4a60: 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66  n;..}...if (appf
4a70: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4a80: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66  e != NULL) {...f
4a90: 6f 72 20 28 69 64 78 20 3d 20 30 3b 20 69 64 78  or (idx = 0; idx
4aa0: 20 3c 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e   < appfs_path_in
4ab0: 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 20 69  fo_cache_size; i
4ac0: 64 78 2b 2b 29 20 7b 0a 09 09 09 69 66 20 28 61  dx++) {....if (a
4ad0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4ae0: 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65  ache[idx]._cache
4af0: 5f 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b  _path != NULL) {
4b00: 0a 09 09 09 09 69 66 20 28 75 69 64 20 21 3d 20  .....if (uid != 
4b10: 28 28 75 69 64 5f 74 29 20 2d 31 29 29 20 7b 0a  ((uid_t) -1)) {.
4b20: 09 09 09 09 09 69 66 20 28 61 70 70 66 73 5f 70  .....if (appfs_p
4b30: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69  ath_info_cache[i
4b40: 64 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64 20 21  dx]._cache_uid !
4b50: 3d 20 75 69 64 29 20 7b 0a 09 09 09 09 09 09 63  = uid) {.......c
4b60: 6f 6e 74 69 6e 75 65 3b 0a 09 09 09 09 09 7d 0a  ontinue;......}.
4b70: 09 09 09 09 7d 0a 0a 09 09 09 09 66 72 65 65 28  ....}......free(
4b80: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4b90: 63 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68  cache[idx]._cach
4ba0: 65 5f 70 61 74 68 29 3b 0a 0a 09 09 09 09 61 70  e_path);......ap
4bb0: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4bc0: 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f  che[idx]._cache_
4bd0: 70 61 74 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 09  path = NULL;....
4be0: 7d 0a 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 75  }...}..}...if (u
4bf0: 69 64 20 3d 3d 20 28 28 75 69 64 5f 74 29 20 2d  id == ((uid_t) -
4c00: 31 29 29 20 7b 0a 09 09 66 72 65 65 28 61 70 70  1)) {...free(app
4c10: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4c20: 68 65 29 3b 0a 0a 09 09 61 70 70 66 73 5f 70 61  he);....appfs_pa
4c30: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20  th_info_cache = 
4c40: 4e 55 4c 4c 3b 0a 0a 09 09 69 66 20 28 6e 65 77  NULL;....if (new
4c50: 5f 73 69 7a 65 20 21 3d 20 2d 31 29 20 7b 0a 09  _size != -1) {..
4c60: 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  ..appfs_path_inf
4c70: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 6e  o_cache_size = n
4c80: 65 77 5f 73 69 7a 65 3b 0a 09 09 7d 0a 09 7d 0a  ew_size;...}..}.
4c90: 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20  ..pthread_ret = 
4ca0: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e  pthread_mutex_un
4cb0: 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68  lock(&appfs_path
4cc0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65  _info_cache_mute
4cd0: 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64  x);..if (pthread
4ce0: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41  _ret != 0) {...A
4cf0: 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62  PPFS_DEBUG("Unab
4d00: 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74  le to unlock pat
4d10: 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74  h_info cache mut
4d20: 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72  ex !");....retur
4d30: 6e 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a  n;..}...return;.
4d40: 7d 0a 0a 2f 2a 20 47 65 74 20 69 6e 66 6f 72 6d  }../* Get inform
4d50: 61 74 69 6f 6e 20 61 62 6f 75 74 20 61 20 70 61  ation about a pa
4d60: 74 68 2c 20 61 6e 64 20 6f 70 74 69 6f 6e 61 6c  th, and optional
4d70: 6c 79 20 6c 69 73 74 20 63 68 69 6c 64 72 65 6e  ly list children
4d80: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61   */.static int a
4d90: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
4da0: 66 6f 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  fo(const char *p
4db0: 61 74 68 2c 20 73 74 72 75 63 74 20 61 70 70 66  ath, struct appf
4dc0: 73 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61 74 68  s_pathinfo *path
4dd0: 69 6e 66 6f 29 20 7b 0a 09 54 63 6c 5f 49 6e 74  info) {..Tcl_Int
4de0: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63  erp *interp;..Tc
4df0: 6c 5f 4f 62 6a 20 2a 61 74 74 72 73 5f 64 69 63  l_Obj *attrs_dic
4e00: 74 2c 20 2a 61 74 74 72 5f 76 61 6c 75 65 3b 0a  t, *attr_value;.
4e10: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 74 74  .const char *att
4e20: 72 5f 76 61 6c 75 65 5f 73 74 72 2c 20 2a 61 74  r_value_str, *at
4e30: 74 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 3b 0a  tr_value_str_i;.
4e40: 09 54 63 6c 5f 57 69 64 65 49 6e 74 20 61 74 74  .Tcl_WideInt att
4e50: 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 69  r_value_wide;..i
4e60: 6e 74 20 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e  nt attr_value_in
4e70: 74 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72  t;..static __thr
4e80: 65 61 64 20 54 63 6c 5f 4f 62 6a 20 2a 61 74 74  ead Tcl_Obj *att
4e90: 72 5f 6b 65 79 5f 74 79 70 65 20 3d 20 4e 55 4c  r_key_type = NUL
4ea0: 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 70 65 72  L, *attr_key_per
4eb0: 6d 73 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72  ms = NULL, *attr
4ec0: 5f 6b 65 79 5f 73 69 7a 65 20 3d 20 4e 55 4c 4c  _key_size = NULL
4ed0: 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65  , *attr_key_time
4ee0: 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b   = NULL, *attr_k
4ef0: 65 79 5f 73 6f 75 72 63 65 20 3d 20 4e 55 4c 4c  ey_source = NULL
4f00: 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c  , *attr_key_chil
4f10: 64 63 6f 75 6e 74 20 3d 20 4e 55 4c 4c 2c 20 2a  dcount = NULL, *
4f20: 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65  attr_key_package
4f30: 64 20 3d 20 4e 55 4c 4c 3b 0a 09 69 6e 74 20 63  d = NULL;..int c
4f40: 61 63 68 65 5f 72 65 74 3b 0a 09 69 6e 74 20 74  ache_ret;..int t
4f50: 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65 74  cl_ret;..int ret
4f60: 76 61 6c 3b 0a 09 75 69 64 5f 74 20 66 73 75 69  val;..uid_t fsui
4f70: 64 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 30 3b  d;...retval = 0;
4f80: 0a 0a 09 66 73 75 69 64 20 3d 20 61 70 70 66 73  ...fsuid = appfs
4f90: 5f 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 0a 09  _get_fsuid();...
4fa0: 63 61 63 68 65 5f 72 65 74 20 3d 20 61 70 70 66  cache_ret = appf
4fb0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
4fc0: 63 61 63 68 65 5f 67 65 74 28 70 61 74 68 2c 20  cache_get(path, 
4fd0: 66 73 75 69 64 2c 20 70 61 74 68 69 6e 66 6f 29  fsuid, pathinfo)
4fe0: 3b 0a 09 69 66 20 28 63 61 63 68 65 5f 72 65 74  ;..if (cache_ret
4ff0: 20 3d 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 70   == 0) {...if (p
5000: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d  athinfo->type ==
5010: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
5020: 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 29 20  DOES_NOT_EXIST) 
5030: 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  {....APPFS_DEBUG
5040: 28 22 52 65 74 75 72 6e 69 6e 67 20 66 72 6f 6d  ("Returning from
5050: 20 63 61 63 68 65 3a 20 64 6f 65 73 20 6e 6f 74   cache: does not
5060: 20 65 78 69 73 74 20 5c 22 25 73 5c 22 22 2c 20   exist \"%s\"", 
5070: 70 61 74 68 29 3b 0a 0a 09 09 09 72 65 74 75 72  path);.....retur
5080: 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09 09 7d 0a  n(-ENOENT);...}.
5090: 0a 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2d  ...if (pathinfo-
50a0: 3e 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50  >type == APPFS_P
50b0: 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 29  ATHTYPE_INVALID)
50c0: 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55   {....APPFS_DEBU
50d0: 47 28 22 52 65 74 75 72 6e 69 6e 67 20 66 72 6f  G("Returning fro
50e0: 6d 20 63 61 63 68 65 3a 20 69 6e 76 61 6c 69 64  m cache: invalid
50f0: 20 6f 62 6a 65 63 74 20 5c 22 25 73 5c 22 22 2c   object \"%s\"",
5100: 20 70 61 74 68 29 3b 0a 0a 09 09 09 72 65 74 75   path);.....retu
5110: 72 6e 28 2d 45 49 4f 29 3b 0a 09 09 7d 0a 0a 09  rn(-EIO);...}...
5120: 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a  .return(0);..}..
5130: 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f  .interp = appfs_
5140: 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66  TclInterp();..if
5150: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
5160: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
5170: 47 28 22 65 72 72 6f 72 3a 20 55 6e 61 62 6c 65  G("error: Unable
5180: 20 74 6f 20 67 65 74 20 61 6e 20 69 6e 74 65 72   to get an inter
5190: 70 72 65 74 65 72 22 29 3b 0a 0a 09 09 72 65 74  preter");....ret
51a0: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
51b0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
51c0: 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69  l(Tcl_Preserve(i
51d0: 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72  nterp);)...tcl_r
51e0: 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45  et = appfs_Tcl_E
51f0: 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22  val(interp, 2, "
5200: 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61 74 74 72  ::appfs::getattr
5210: 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28 74  ", path);..if (t
5220: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
5230: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
5240: 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61  G("::appfs::geta
5250: 74 74 72 28 25 73 29 20 66 61 69 6c 65 64 2e 22  ttr(%s) failed."
5260: 2c 20 70 61 74 68 29 3b 0a 09 09 61 70 70 66 73  , path);...appfs
5270: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
5280: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63  .APPFS_DEBUG("Tc
5290: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c  l Error is: %s",
52a0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
52b0: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09  sult(interp));..
52c0: 09 29 0a 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e  .)....pathinfo->
52d0: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
52e0: 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45  HTYPE_DOES_NOT_E
52f0: 58 49 53 54 3b 0a 0a 09 09 61 70 70 66 73 5f 67  XIST;....appfs_g
5300: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
5310: 68 65 5f 61 64 64 28 70 61 74 68 2c 20 66 73 75  he_add(path, fsu
5320: 69 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a 0a  id, pathinfo);..
5330: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
5340: 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28  tcl(Tcl_Release(
5350: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74  interp);)....ret
5360: 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09 7d  urn(-ENOENT);..}
5370: 0a 0a 09 69 66 20 28 61 74 74 72 5f 6b 65 79 5f  ...if (attr_key_
5380: 74 79 70 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  type == NULL) {.
5390: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
53a0: 74 63 6c 28 0a 09 09 09 61 74 74 72 5f 6b 65 79  tcl(....attr_key
53b0: 5f 74 79 70 65 20 20 20 20 20 20 20 3d 20 54 63  _type       = Tc
53c0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
53d0: 74 79 70 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61  type", -1);....a
53e0: 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20 20 20  ttr_key_perms   
53f0: 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69     = Tcl_NewStri
5400: 6e 67 4f 62 6a 28 22 70 65 72 6d 73 22 2c 20 2d  ngObj("perms", -
5410: 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f  1);....attr_key_
5420: 73 69 7a 65 20 20 20 20 20 20 20 3d 20 54 63 6c  size       = Tcl
5430: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 73  _NewStringObj("s
5440: 69 7a 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74  ize", -1);....at
5450: 74 72 5f 6b 65 79 5f 74 69 6d 65 20 20 20 20 20  tr_key_time     
5460: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e    = Tcl_NewStrin
5470: 67 4f 62 6a 28 22 74 69 6d 65 22 2c 20 2d 31 29  gObj("time", -1)
5480: 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 73 6f  ;....attr_key_so
5490: 75 72 63 65 20 20 20 20 20 3d 20 54 63 6c 5f 4e  urce     = Tcl_N
54a0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 73 6f 75  ewStringObj("sou
54b0: 72 63 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74  rce", -1);....at
54c0: 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e  tr_key_childcoun
54d0: 74 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  t = Tcl_NewStrin
54e0: 67 4f 62 6a 28 22 63 68 69 6c 64 63 6f 75 6e 74  gObj("childcount
54f0: 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f  ", -1);....attr_
5500: 6b 65 79 5f 70 61 63 6b 61 67 65 64 20 20 20 3d  key_packaged   =
5510: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
5520: 6a 28 22 70 61 63 6b 61 67 65 64 22 2c 20 2d 31  j("packaged", -1
5530: 29 3b 0a 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52  );.....Tcl_IncrR
5540: 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79  efCount(attr_key
5550: 5f 74 79 70 65 29 3b 0a 09 09 09 54 63 6c 5f 49  _type);....Tcl_I
5560: 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72  ncrRefCount(attr
5570: 5f 6b 65 79 5f 70 65 72 6d 73 29 3b 0a 09 09 09  _key_perms);....
5580: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74  Tcl_IncrRefCount
5590: 28 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 29 3b  (attr_key_size);
55a0: 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43  ....Tcl_IncrRefC
55b0: 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 74 69  ount(attr_key_ti
55c0: 6d 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72  me);....Tcl_Incr
55d0: 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65  RefCount(attr_ke
55e0: 79 5f 73 6f 75 72 63 65 29 3b 0a 09 09 09 54 63  y_source);....Tc
55f0: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61  l_IncrRefCount(a
5600: 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75  ttr_key_childcou
5610: 6e 74 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72  nt);....Tcl_Incr
5620: 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65  RefCount(attr_ke
5630: 79 5f 70 61 63 6b 61 67 65 64 29 3b 0a 09 09 29  y_packaged);...)
5640: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..}...appfs_call
5650: 5f 6c 69 62 74 63 6c 28 0a 09 09 61 74 74 72 73  _libtcl(...attrs
5660: 5f 64 69 63 74 20 3d 20 54 63 6c 5f 47 65 74 4f  _dict = Tcl_GetO
5670: 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  bjResult(interp)
5680: 3b 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63  ;...tcl_ret = Tc
5690: 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74  l_DictObjGet(int
56a0: 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c  erp, attrs_dict,
56b0: 20 61 74 74 72 5f 6b 65 79 5f 74 79 70 65 2c 20   attr_key_type, 
56c0: 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 29  &attr_value);..)
56d0: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
56e0: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
56f0: 46 53 5f 44 45 42 55 47 28 22 5b 64 69 63 74 20  FS_DEBUG("[dict 
5700: 67 65 74 20 5c 22 74 79 70 65 5c 22 5d 20 66 61  get \"type\"] fa
5710: 69 6c 65 64 22 29 3b 0a 09 09 61 70 70 66 73 5f  iled");...appfs_
5720: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
5730: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c  APPFS_DEBUG("Tcl
5740: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20   Error is: %s", 
5750: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
5760: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
5770: 29 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  )....appfs_call_
5780: 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61  libtcl(Tcl_Relea
5790: 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09  se(interp);)....
57a0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
57b0: 0a 0a 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75  ...if (attr_valu
57c0: 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41  e == NULL) {...A
57d0: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
57e0: 72 3a 20 55 6e 61 62 6c 65 20 74 6f 20 67 65 74  r: Unable to get
57f0: 20 74 79 70 65 20 66 6f 72 20 5c 22 25 73 5c 22   type for \"%s\"
5800: 20 66 72 6f 6d 20 54 63 6c 22 2c 20 70 61 74 68   from Tcl", path
5810: 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  );....appfs_call
5820: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
5830: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
5840: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
5850: 7d 0a 0a 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61  }...pathinfo->pa
5860: 63 6b 61 67 65 64 20 3d 20 30 3b 0a 0a 09 61 70  ckaged = 0;...ap
5870: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
5880: 0a 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73 74  ...attr_value_st
5890: 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  r = Tcl_GetStrin
58a0: 67 28 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 0a  g(attr_value);..
58b0: 09 09 73 77 69 74 63 68 20 28 61 74 74 72 5f 76  ..switch (attr_v
58c0: 61 6c 75 65 5f 73 74 72 5b 30 5d 29 20 7b 0a 09  alue_str[0]) {..
58d0: 09 09 63 61 73 65 20 27 64 27 3a 20 2f 2a 20 64  ..case 'd': /* d
58e0: 69 72 65 63 74 6f 72 79 20 2a 2f 0a 09 09 09 09  irectory */.....
58f0: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d  pathinfo->type =
5900: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
5910: 44 49 52 45 43 54 4f 52 59 3b 0a 09 09 09 09 70  DIRECTORY;.....p
5920: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
5930: 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74  o.dir.childcount
5940: 20 3d 20 30 3b 0a 0a 09 09 09 09 54 63 6c 5f 44   = 0;......Tcl_D
5950: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
5960: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
5970: 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e  tr_key_childcoun
5980: 74 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  t, &attr_value);
5990: 0a 09 09 09 09 69 66 20 28 61 74 74 72 5f 76 61  .....if (attr_va
59a0: 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  lue != NULL) {..
59b0: 09 09 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63  ....tcl_ret = Tc
59c0: 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d  l_GetWideIntFrom
59d0: 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76  Obj(NULL, attr_v
59e0: 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  alue, &attr_valu
59f0: 65 5f 77 69 64 65 29 3b 0a 09 09 09 09 09 69 66  e_wide);......if
5a00: 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c   (tcl_ret == TCL
5a10: 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 09 70 61 74  _OK) {.......pat
5a20: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
5a30: 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d  dir.childcount =
5a40: 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65   attr_value_wide
5a50: 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a  ;......}.....}..
5a60: 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61  ....break;....ca
5a70: 73 65 20 27 66 27 3a 20 2f 2a 20 66 69 6c 65 20  se 'f': /* file 
5a80: 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  */.....pathinfo-
5a90: 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41  >type = APPFS_PA
5aa0: 54 48 54 59 50 45 5f 46 49 4c 45 3b 0a 09 09 09  THTYPE_FILE;....
5ab0: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  .pathinfo->typei
5ac0: 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 3d 20  nfo.file.size = 
5ad0: 30 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  0;.....pathinfo-
5ae0: 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 65  >typeinfo.file.e
5af0: 78 65 63 75 74 61 62 6c 65 20 3d 20 30 3b 0a 09  xecutable = 0;..
5b00: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
5b10: 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 75 69 64 52  einfo.file.suidR
5b20: 6f 6f 74 20 3d 20 30 3b 0a 09 09 09 09 70 61 74  oot = 0;.....pat
5b30: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
5b40: 66 69 6c 65 2e 77 6f 72 6c 64 61 63 63 65 73 73  file.worldaccess
5b50: 69 62 6c 65 20 3d 20 30 3b 0a 0a 09 09 09 09 54  ible = 0;......T
5b60: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
5b70: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
5b80: 2c 20 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 2c  , attr_key_size,
5b90: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
5ba0: 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75  ...if (attr_valu
5bb0: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  e != NULL) {....
5bc0: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
5bd0: 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62  GetWideIntFromOb
5be0: 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c  j(NULL, attr_val
5bf0: 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f  ue, &attr_value_
5c00: 77 69 64 65 29 3b 0a 09 09 09 09 09 69 66 20 28  wide);......if (
5c10: 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f  tcl_ret == TCL_O
5c20: 4b 29 20 7b 0a 09 09 09 09 09 09 70 61 74 68 69  K) {.......pathi
5c30: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69  nfo->typeinfo.fi
5c40: 6c 65 2e 73 69 7a 65 20 3d 20 61 74 74 72 5f 76  le.size = attr_v
5c50: 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09 09 09  alue_wide;......
5c60: 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 09 54 63 6c  }.....}......Tcl
5c70: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65  _DictObjGet(inte
5c80: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20  rp, attrs_dict, 
5c90: 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 2c 20  attr_key_perms, 
5ca0: 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09  &attr_value);...
5cb0: 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65  ..if (attr_value
5cc0: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09   != NULL) {.....
5cd0: 09 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 20  .attr_value_str 
5ce0: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  = Tcl_GetString(
5cf0: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09  attr_value);....
5d00: 09 09 66 6f 72 20 28 61 74 74 72 5f 76 61 6c 75  ..for (attr_valu
5d10: 65 5f 73 74 72 5f 69 20 3d 20 26 61 74 74 72 5f  e_str_i = &attr_
5d20: 76 61 6c 75 65 5f 73 74 72 5b 30 5d 3b 20 2a 61  value_str[0]; *a
5d30: 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 20  ttr_value_str_i 
5d40: 21 3d 20 27 5c 30 27 3b 20 61 74 74 72 5f 76 61  != '\0'; attr_va
5d50: 6c 75 65 5f 73 74 72 5f 69 2b 2b 29 20 7b 0a 09  lue_str_i++) {..
5d60: 09 09 09 09 09 73 77 69 74 63 68 20 28 2a 61 74  .....switch (*at
5d70: 74 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 29 20  tr_value_str_i) 
5d80: 7b 0a 09 09 09 09 09 09 09 63 61 73 65 20 27 78  {........case 'x
5d90: 27 3a 0a 09 09 09 09 09 09 09 09 70 61 74 68 69  ':.........pathi
5da0: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69  nfo->typeinfo.fi
5db0: 6c 65 2e 65 78 65 63 75 74 61 62 6c 65 20 3d 20  le.executable = 
5dc0: 31 3b 0a 0a 09 09 09 09 09 09 09 09 62 72 65 61  1;..........brea
5dd0: 6b 3b 0a 09 09 09 09 09 09 09 63 61 73 65 20 27  k;........case '
5de0: 55 27 3a 0a 09 09 09 09 09 09 09 09 70 61 74 68  U':.........path
5df0: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66  info->typeinfo.f
5e00: 69 6c 65 2e 73 75 69 64 52 6f 6f 74 20 3d 20 31  ile.suidRoot = 1
5e10: 3b 0a 0a 09 09 09 09 09 09 09 09 62 72 65 61 6b  ;..........break
5e20: 3b 0a 09 09 09 09 09 09 09 63 61 73 65 20 27 2d  ;........case '-
5e30: 27 3a 0a 09 09 09 09 09 09 09 09 70 61 74 68 69  ':.........pathi
5e40: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69  nfo->typeinfo.fi
5e50: 6c 65 2e 77 6f 72 6c 64 61 63 63 65 73 73 69 62  le.worldaccessib
5e60: 6c 65 20 3d 20 31 3b 0a 0a 09 09 09 09 09 09 09  le = 1;.........
5e70: 09 62 72 65 61 6b 3b 0a 09 09 09 09 09 09 7d 0a  .break;.......}.
5e80: 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 09 09 09  .....}.....}....
5e90: 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20  .break;....case 
5ea0: 27 73 27 3a 20 2f 2a 20 73 79 6d 6c 69 6e 6b 20  's': /* symlink 
5eb0: 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  */.....pathinfo-
5ec0: 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41  >type = APPFS_PA
5ed0: 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3b 0a  THTYPE_SYMLINK;.
5ee0: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
5ef0: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
5f00: 69 7a 65 20 3d 20 30 3b 0a 09 09 09 09 70 61 74  ize = 0;.....pat
5f10: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
5f20: 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b 30  symlink.source[0
5f30: 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09 09 09 09 54  ] = '\0';......T
5f40: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
5f50: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
5f60: 2c 20 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63  , attr_key_sourc
5f70: 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  e, &attr_value);
5f80: 0a 09 09 09 09 69 66 20 28 61 74 74 72 5f 76 61  .....if (attr_va
5f90: 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  lue != NULL) {..
5fa0: 09 09 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73  ....attr_value_s
5fb0: 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  tr = Tcl_GetStri
5fc0: 6e 67 46 72 6f 6d 4f 62 6a 28 61 74 74 72 5f 76  ngFromObj(attr_v
5fd0: 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  alue, &attr_valu
5fe0: 65 5f 69 6e 74 29 3b 20 0a 0a 09 09 09 09 09 69  e_int); .......i
5ff0: 66 20 28 28 61 74 74 72 5f 76 61 6c 75 65 5f 69  f ((attr_value_i
6000: 6e 74 20 2b 20 31 29 20 3c 3d 20 73 69 7a 65 6f  nt + 1) <= sizeo
6010: 66 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  f(pathinfo->type
6020: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75  info.symlink.sou
6030: 72 63 65 29 29 20 7b 0a 09 09 09 09 09 09 70 61  rce)) {.......pa
6040: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
6050: 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20  .symlink.size = 
6060: 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a  attr_value_int;.
6070: 09 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  ......pathinfo->
6080: 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b  typeinfo.symlink
6090: 2e 73 6f 75 72 63 65 5b 61 74 74 72 5f 76 61 6c  .source[attr_val
60a0: 75 65 5f 69 6e 74 5d 20 3d 20 27 5c 30 27 3b 0a  ue_int] = '\0';.
60b0: 0a 09 09 09 09 09 09 6d 65 6d 63 70 79 28 70 61  .......memcpy(pa
60c0: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
60d0: 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c  .symlink.source,
60e0: 20 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 2c   attr_value_str,
60f0: 20 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29   attr_value_int)
6100: 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 09  ;......}.....}..
6110: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73  ...break;....cas
6120: 65 20 27 46 27 3a 20 2f 2a 20 70 69 70 65 2f 66  e 'F': /* pipe/f
6130: 69 66 6f 20 2a 2f 0a 09 09 09 09 70 61 74 68 69  ifo */.....pathi
6140: 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46  nfo->type = APPF
6150: 53 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3b  S_PATHTYPE_FIFO;
6160: 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63  .....break;....c
6170: 61 73 65 20 27 53 27 3a 20 2f 2a 20 55 4e 49 58  ase 'S': /* UNIX
6180: 20 64 6f 6d 61 69 6e 20 73 6f 63 6b 65 74 20 2a   domain socket *
6190: 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  /.....pathinfo->
61a0: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
61b0: 48 54 59 50 45 5f 53 4f 43 4b 45 54 3b 0a 09 09  HTYPE_SOCKET;...
61c0: 09 09 62 72 65 61 6b 3b 0a 09 09 09 64 65 66 61  ..break;....defa
61d0: 75 6c 74 3a 0a 09 09 09 09 72 65 74 76 61 6c 20  ult:.....retval 
61e0: 3d 20 2d 45 49 4f 3b 0a 09 09 7d 0a 0a 09 09 54  = -EIO;...}....T
61f0: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
6200: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
6210: 2c 20 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61  , attr_key_packa
6220: 67 65 64 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  ged, &attr_value
6230: 29 3b 0a 09 09 69 66 20 28 61 74 74 72 5f 76 61  );...if (attr_va
6240: 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  lue != NULL) {..
6250: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b  ..pathinfo->pack
6260: 61 67 65 64 20 3d 20 31 3b 0a 09 09 7d 0a 0a 09  aged = 1;...}...
6270: 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28  .Tcl_DictObjGet(
6280: 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69  interp, attrs_di
6290: 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74 69 6d  ct, attr_key_tim
62a0: 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  e, &attr_value);
62b0: 0a 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75  ...if (attr_valu
62c0: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  e != NULL) {....
62d0: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65  tcl_ret = Tcl_Ge
62e0: 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28  tWideIntFromObj(
62f0: 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65  NULL, attr_value
6300: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69  , &attr_value_wi
6310: 64 65 29 3b 0a 09 09 09 69 66 20 28 74 63 6c 5f  de);....if (tcl_
6320: 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret == TCL_OK) {
6330: 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
6340: 69 6d 65 20 3d 20 61 74 74 72 5f 76 61 6c 75 65  ime = attr_value
6350: 5f 77 69 64 65 3b 0a 09 09 09 7d 0a 09 09 7d 20  _wide;....}...} 
6360: 65 6c 73 65 20 7b 0a 09 09 09 70 61 74 68 69 6e  else {....pathin
6370: 66 6f 2d 3e 74 69 6d 65 20 3d 20 61 70 70 66 73  fo->time = appfs
6380: 5f 62 6f 6f 74 74 69 6d 65 3b 0a 09 09 7d 0a 0a  _boottime;...}..
6390: 09 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  ..Tcl_Release(in
63a0: 74 65 72 70 29 3b 0a 09 29 0a 0a 09 69 66 20 28  terp);..)...if (
63b0: 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67  pathinfo->packag
63c0: 65 64 29 20 7b 0a 09 09 70 61 74 68 69 6e 66 6f  ed) {...pathinfo
63d0: 2d 3e 69 6e 6f 64 65 20 3d 20 61 70 70 66 73 5f  ->inode = appfs_
63e0: 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70  get_path_inode(p
63f0: 61 74 68 2c 20 2d 31 29 3b 0a 09 7d 20 65 6c 73  ath, -1);..} els
6400: 65 20 7b 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e  e {...pathinfo->
6410: 69 6e 6f 64 65 20 3d 20 61 70 70 66 73 5f 67 65  inode = appfs_ge
6420: 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74  t_path_inode(pat
6430: 68 2c 20 66 73 75 69 64 29 3b 0a 09 7d 0a 0a 09  h, fsuid);..}...
6440: 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 61 63  APPFS_DEBUG("Cac
6450: 68 69 6e 67 20 69 6e 6f 64 65 20 66 6f 72 20 70  hing inode for p
6460: 61 74 68 3d 25 73 2c 75 69 64 3d 25 6c 6c 69 20  ath=%s,uid=%lli 
6470: 61 73 20 25 6c 6c 75 20 28 70 61 63 6b 61 67 65  as %llu (package
6480: 64 20 3d 20 25 69 29 22 2c 20 70 61 74 68 2c 20  d = %i)", path, 
6490: 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69  (long long) fsui
64a0: 64 2c 20 70 61 74 68 69 6e 66 6f 2d 3e 69 6e 6f  d, pathinfo->ino
64b0: 64 65 2c 20 70 61 74 68 69 6e 66 6f 2d 3e 70 61  de, pathinfo->pa
64c0: 63 6b 61 67 65 64 29 3b 0a 0a 09 69 66 20 28 72  ckaged);...if (r
64d0: 65 74 76 61 6c 20 3d 3d 20 30 29 20 7b 0a 09 09  etval == 0) {...
64e0: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
64f0: 6e 66 6f 5f 63 61 63 68 65 5f 61 64 64 28 70 61  nfo_cache_add(pa
6500: 74 68 2c 20 66 73 75 69 64 2c 20 70 61 74 68 69  th, fsuid, pathi
6510: 6e 66 6f 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a  nfo);..} else {.
6520: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65  ..APPFS_DEBUG("e
6530: 72 72 6f 72 3a 20 49 6e 76 61 6c 69 64 20 74 79  rror: Invalid ty
6540: 70 65 20 66 6f 72 20 5c 22 25 73 5c 22 20 66 72  pe for \"%s\" fr
6550: 6f 6d 20 54 63 6c 22 2c 20 70 61 74 68 29 3b 0a  om Tcl", path);.
6560: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76  .}...return(retv
6570: 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63  al);.}..static c
6580: 68 61 72 20 2a 61 70 70 66 73 5f 70 72 65 70 61  har *appfs_prepa
6590: 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 63 6f 6e  re_to_create(con
65a0: 73 74 20 63 68 61 72 20 2a 70 61 74 68 29 20 7b  st char *path) {
65b0: 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  ..Tcl_Interp *in
65c0: 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61  terp;..const cha
65d0: 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69  r *real_path;..i
65e0: 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 61 70  nt tcl_ret;...ap
65f0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
6600: 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 61 70  o_cache_flush(ap
6610: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 2c  pfs_get_fsuid(),
6620: 20 2d 31 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d   -1);...interp =
6630: 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70   appfs_TclInterp
6640: 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  ();..if (interp 
6650: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
6660: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
6670: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
6680: 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69  l(Tcl_Preserve(i
6690: 6e 74 65 72 70 29 3b 29 0a 0a 09 61 70 70 66 73  nterp);)...appfs
66a0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
66b0: 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f  tcl_ret = appfs_
66c0: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
66d0: 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 70 72   2, "::appfs::pr
66e0: 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 22  epare_to_create"
66f0: 2c 20 70 61 74 68 29 3b 0a 09 29 0a 09 69 66 20  , path);..)..if 
6700: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
6710: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
6720: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 70 72  BUG("::appfs::pr
6730: 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28  epare_to_create(
6740: 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61  %s) failed.", pa
6750: 74 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c  th);...appfs_cal
6760: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50  l_libtcl(....APP
6770: 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72  FS_DEBUG("Tcl Er
6780: 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c  ror is: %s", Tcl
6790: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
67a0: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a  (interp));...)..
67b0: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
67c0: 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28  tcl(Tcl_Release(
67d0: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74  interp);)....ret
67e0: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
67f0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
6800: 6c 28 0a 09 09 72 65 61 6c 5f 70 61 74 68 20 3d  l(...real_path =
6810: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
6820: 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 29  sult(interp);..)
6830: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
6840: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
6850: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 69 66 20  (interp);)...if 
6860: 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55  (real_path == NU
6870: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e  LL) {...return(N
6880: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  ULL);..}...retur
6890: 6e 28 73 74 72 64 75 70 28 72 65 61 6c 5f 70 61  n(strdup(real_pa
68a0: 74 68 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  th));.}..static 
68b0: 63 68 61 72 20 2a 61 70 70 66 73 5f 6c 6f 63 61  char *appfs_loca
68c0: 6c 70 61 74 68 28 63 6f 6e 73 74 20 63 68 61 72  lpath(const char
68d0: 20 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49   *path) {..Tcl_I
68e0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09  nterp *interp;..
68f0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c  const char *real
6900: 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f  _path;..int tcl_
6910: 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20  ret;...interp = 
6920: 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28  appfs_TclInterp(
6930: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  );..if (interp =
6940: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
6950: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61  rn(NULL);..}...a
6960: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
6970: 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e  (Tcl_Preserve(in
6980: 74 65 72 70 29 3b 29 0a 0a 09 61 70 70 66 73 5f  terp);)...appfs_
6990: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74  call_libtcl(...t
69a0: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
69b0: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
69c0: 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63  2, "::appfs::loc
69d0: 61 6c 70 61 74 68 22 2c 20 70 61 74 68 29 3b 0a  alpath", path);.
69e0: 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  .)..if (tcl_ret 
69f0: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41  != TCL_OK) {...A
6a00: 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70  PPFS_DEBUG("::ap
6a10: 70 66 73 3a 3a 6c 6f 63 61 6c 70 61 74 68 28 25  pfs::localpath(%
6a20: 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  s) failed.", pat
6a30: 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  h);...appfs_call
6a40: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46  _libtcl(....APPF
6a50: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72  S_DEBUG("Tcl Err
6a60: 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f  or is: %s", Tcl_
6a70: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
6a80: 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09  interp));...)...
6a90: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
6aa0: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
6ab0: 69 62 74 63 6c 28 0a 09 09 72 65 61 6c 5f 70 61  ibtcl(...real_pa
6ac0: 74 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  th = Tcl_GetStri
6ad0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
6ae0: 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..)...appfs_cal
6af0: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
6b00: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
6b10: 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d  .if (real_path =
6b20: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
6b30: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72  rn(NULL);..}...r
6b40: 65 74 75 72 6e 28 73 74 72 64 75 70 28 72 65 61  eturn(strdup(rea
6b50: 6c 5f 70 61 74 68 29 29 3b 0a 7d 0a 0a 23 69 66  l_path));.}..#if
6b60: 20 28 64 65 66 69 6e 65 64 28 44 45 42 55 47 29   (defined(DEBUG)
6b70: 20 26 26 20 64 65 66 69 6e 65 64 28 41 50 50 46   && defined(APPF
6b80: 53 5f 45 58 49 54 5f 50 41 54 48 29 29 20 7c 7c  S_EXIT_PATH)) ||
6b90: 20 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45   defined(APPFS_E
6ba0: 58 49 54 5f 50 41 54 48 5f 45 4e 41 42 4c 45 5f  XIT_PATH_ENABLE_
6bb0: 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f 48  MAJOR_SECURITY_H
6bc0: 4f 4c 45 29 0a 73 74 61 74 69 63 20 76 6f 69 64  OLE).static void
6bd0: 20 61 70 70 66 73 5f 65 78 69 74 28 76 6f 69 64   appfs_exit(void
6be0: 29 20 7b 0a 09 69 6e 74 20 67 6c 6f 62 61 6c 5f  ) {..int global_
6bf0: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
6c00: 3b 0a 0a 09 67 6c 6f 62 61 6c 5f 69 6e 74 65 72  ;...global_inter
6c10: 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 5f 5f  p_reset_key = __
6c20: 73 79 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 61  sync_fetch_and_a
6c30: 64 64 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74  dd(&interp_reset
6c40: 5f 6b 65 79 2c 20 30 29 3b 0a 09 5f 5f 73 79 6e  _key, 0);..__syn
6c50: 63 5f 66 65 74 63 68 5f 61 6e 64 5f 73 75 62 28  c_fetch_and_sub(
6c60: 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65  &interp_reset_ke
6c70: 79 2c 20 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70  y, global_interp
6c80: 5f 72 65 73 65 74 5f 6b 65 79 29 3b 0a 0a 09 77  _reset_key);...w
6c90: 68 69 6c 65 20 28 5f 5f 73 79 6e 63 5f 73 75 62  hile (__sync_sub
6ca0: 5f 61 6e 64 5f 66 65 74 63 68 28 26 69 6e 74 65  _and_fetch(&inte
6cb0: 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 31 29  rp_reset_key, 1)
6cc0: 20 3e 3d 20 30 29 20 7b 0a 09 09 2f 2a 20 42 75   >= 0) {.../* Bu
6cd0: 73 79 20 4c 6f 6f 70 20 2a 2f 0a 09 7d 0a 0a 09  sy Loop */..}...
6ce0: 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65  global_interp_re
6cf0: 73 65 74 5f 6b 65 79 20 3d 20 5f 5f 73 79 6e 63  set_key = __sync
6d00: 5f 66 65 74 63 68 5f 61 6e 64 5f 61 64 64 28 26  _fetch_and_add(&
6d10: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
6d20: 2c 20 30 29 3b 0a 09 69 66 20 28 67 6c 6f 62 61  , 0);..if (globa
6d30: 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  l_interp_reset_k
6d40: 65 79 20 21 3d 20 2d 31 29 20 7b 0a 09 09 41 50  ey != -1) {...AP
6d50: 50 46 53 5f 44 45 42 55 47 28 22 45 72 72 6f 72  PFS_DEBUG("Error
6d60: 20 73 65 6e 64 69 6e 67 20 6b 69 6c 6c 20 73 69   sending kill si
6d70: 67 6e 61 6c 20 74 6f 20 61 6c 6c 20 74 68 72 65  gnal to all thre
6d80: 61 64 73 2c 20 61 62 6f 72 74 69 6e 67 20 61 6e  ads, aborting an
6d90: 79 77 61 79 2e 22 29 3b 0a 09 7d 0a 0a 09 61 70  yway.");..}...ap
6da0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
6db0: 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31  o_cache_flush(-1
6dc0: 2c 20 2d 31 29 3b 0a 0a 09 66 75 73 65 5f 65 78  , -1);...fuse_ex
6dd0: 69 74 28 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74  it(fuse_get_cont
6de0: 65 78 74 28 29 2d 3e 66 75 73 65 29 3b 0a 0a 09  ext()->fuse);...
6df0: 72 65 74 75 72 6e 3b 0a 7d 0a 23 65 6e 64 69 66  return;.}.#endif
6e00: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
6e10: 66 73 5f 66 75 73 65 5f 72 65 61 64 6c 69 6e 6b  fs_fuse_readlink
6e20: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
6e30: 68 2c 20 63 68 61 72 20 2a 62 75 66 2c 20 73 69  h, char *buf, si
6e40: 7a 65 5f 74 20 73 69 7a 65 29 20 7b 0a 09 73 74  ze_t size) {..st
6e50: 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69  ruct appfs_pathi
6e60: 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69  nfo pathinfo;..i
6e70: 6e 74 20 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a  nt retval = 0;..
6e80: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
6e90: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
6ea0: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09  ...)", path);...
6eb0: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20  pathinfo.type = 
6ec0: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49  APPFS_PATHTYPE_I
6ed0: 4e 56 41 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c  NVALID;...retval
6ee0: 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74   = appfs_get_pat
6ef0: 68 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26 70 61  h_info(path, &pa
6f00: 74 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65  thinfo);..if (re
6f10: 74 76 61 6c 20 21 3d 20 30 29 20 7b 0a 09 09 72  tval != 0) {...r
6f20: 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09  eturn(retval);..
6f30: 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f  }...if (pathinfo
6f40: 2e 74 79 70 65 20 21 3d 20 41 50 50 46 53 5f 50  .type != APPFS_P
6f50: 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 29  ATHTYPE_SYMLINK)
6f60: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4e   {...return(-EIN
6f70: 56 41 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28  VAL);..}...if ((
6f80: 73 74 72 6c 65 6e 28 70 61 74 68 69 6e 66 6f 2e  strlen(pathinfo.
6f90: 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b  typeinfo.symlink
6fa0: 2e 73 6f 75 72 63 65 29 20 2b 20 31 29 20 3e 20  .source) + 1) > 
6fb0: 73 69 7a 65 29 20 7b 0a 09 09 72 65 74 75 72 6e  size) {...return
6fc0: 28 2d 45 4e 41 4d 45 54 4f 4f 4c 4f 4e 47 29 3b  (-ENAMETOOLONG);
6fd0: 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79 28 62 75 66  ..}...memcpy(buf
6fe0: 2c 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69  , pathinfo.typei
6ff0: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72  nfo.symlink.sour
7000: 63 65 2c 20 73 74 72 6c 65 6e 28 70 61 74 68 69  ce, strlen(pathi
7010: 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  nfo.typeinfo.sym
7020: 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31  link.source) + 1
7030: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  );...return(0);.
7040: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
7050: 70 66 73 5f 66 75 73 65 5f 67 65 74 61 74 74 72  pfs_fuse_getattr
7060: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
7070: 68 2c 20 73 74 72 75 63 74 20 73 74 61 74 20 2a  h, struct stat *
7080: 73 74 62 75 66 29 20 7b 0a 09 73 74 72 75 63 74  stbuf) {..struct
7090: 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20   appfs_pathinfo 
70a0: 70 61 74 68 69 6e 66 6f 3b 0a 09 69 6e 74 20 63  pathinfo;..int c
70b0: 68 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65 72  hangeOwnerToUser
70c0: 49 66 50 61 63 6b 61 67 65 64 3b 0a 09 69 6e 74  IfPackaged;..int
70d0: 20 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61   retval;...retva
70e0: 6c 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44  l = 0;...APPFS_D
70f0: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
7100: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
7110: 61 74 68 29 3b 0a 0a 23 69 66 20 28 64 65 66 69  ath);..#if (defi
7120: 6e 65 64 28 44 45 42 55 47 29 20 26 26 20 64 65  ned(DEBUG) && de
7130: 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58 49 54  fined(APPFS_EXIT
7140: 5f 50 41 54 48 29 29 20 7c 7c 20 64 65 66 69 6e  _PATH)) || defin
7150: 65 64 28 41 50 50 46 53 5f 45 58 49 54 5f 50 41  ed(APPFS_EXIT_PA
7160: 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f  TH_ENABLE_MAJOR_
7170: 53 45 43 55 52 49 54 59 5f 48 4f 4c 45 29 0a 09  SECURITY_HOLE)..
7180: 2f 2a 0a 09 20 2a 20 54 68 69 73 20 69 73 20 61  /*.. * This is a
7190: 20 6d 61 6a 6f 72 20 73 65 63 75 72 69 74 79 20   major security 
71a0: 69 73 73 75 65 20 73 6f 20 77 65 20 63 61 6e 6e  issue so we cann
71b0: 6f 74 20 6c 65 74 20 69 74 20 62 65 20 63 6f 6d  ot let it be com
71c0: 70 69 6c 65 64 20 69 6e 74 6f 0a 09 20 2a 20 61  piled into.. * a
71d0: 6e 79 20 72 65 6c 65 61 73 65 0a 09 20 2a 2f 0a  ny release.. */.
71e0: 0a 09 69 66 20 28 73 74 72 63 6d 70 28 70 61 74  ..if (strcmp(pat
71f0: 68 2c 20 22 2f 65 78 69 74 22 29 20 3d 3d 20 30  h, "/exit") == 0
7200: 29 20 7b 0a 09 09 61 70 70 66 73 5f 65 78 69 74  ) {...appfs_exit
7210: 28 29 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a 09  ();..}.#endif...
7220: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20  pathinfo.type = 
7230: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49  APPFS_PATHTYPE_I
7240: 4e 56 41 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c  NVALID;...retval
7250: 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74   = appfs_get_pat
7260: 68 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26 70 61  h_info(path, &pa
7270: 74 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65  thinfo);..if (re
7280: 74 76 61 6c 20 21 3d 20 30 29 20 7b 0a 09 09 69  tval != 0) {...i
7290: 66 20 28 72 65 74 76 61 6c 20 3d 3d 20 2d 45 4e  f (retval == -EN
72a0: 4f 45 4e 54 29 20 7b 0a 09 09 09 41 50 50 46 53  OENT) {....APPFS
72b0: 5f 44 45 42 55 47 28 22 67 65 74 5f 70 61 74 68  _DEBUG("get_path
72c0: 5f 69 6e 66 6f 20 72 65 74 75 72 6e 65 64 20 45  _info returned E
72d0: 4e 4f 45 4e 54 2c 20 72 65 74 75 72 6e 69 6e 67  NOENT, returning
72e0: 20 69 74 20 61 73 20 77 65 6c 6c 2e 22 29 3b 0a   it as well.");.
72f0: 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 41 50  ..} else {....AP
7300: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
7310: 3a 20 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20  : get_path_info 
7320: 66 61 69 6c 65 64 22 29 3b 0a 09 09 7d 0a 0a 09  failed");...}...
7330: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
7340: 0a 09 7d 0a 0a 09 6d 65 6d 73 65 74 28 73 74 62  ..}...memset(stb
7350: 75 66 2c 20 30 2c 20 73 69 7a 65 6f 66 28 73 74  uf, 0, sizeof(st
7360: 72 75 63 74 20 73 74 61 74 29 29 3b 0a 0a 09 73  ruct stat));...s
7370: 74 62 75 66 2d 3e 73 74 5f 6d 74 69 6d 65 20 3d  tbuf->st_mtime =
7380: 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a   pathinfo.time;.
7390: 09 73 74 62 75 66 2d 3e 73 74 5f 63 74 69 6d 65  .stbuf->st_ctime
73a0: 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65   = pathinfo.time
73b0: 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 61 74 69  ;..stbuf->st_ati
73c0: 6d 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69  me = pathinfo.ti
73d0: 6d 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 69  me;..stbuf->st_i
73e0: 6e 6f 20 20 20 3d 20 70 61 74 68 69 6e 66 6f 2e  no   = pathinfo.
73f0: 69 6e 6f 64 65 3b 0a 09 73 74 62 75 66 2d 3e 73  inode;..stbuf->s
7400: 74 5f 6d 6f 64 65 20 20 3d 20 30 3b 0a 0a 09 63  t_mode  = 0;...c
7410: 68 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65 72  hangeOwnerToUser
7420: 49 66 50 61 63 6b 61 67 65 64 20 3d 20 31 3b 0a  IfPackaged = 1;.
7430: 0a 09 73 77 69 74 63 68 20 28 70 61 74 68 69 6e  ..switch (pathin
7440: 66 6f 2e 74 79 70 65 29 20 7b 0a 09 09 63 61 73  fo.type) {...cas
7450: 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  e APPFS_PATHTYPE
7460: 5f 44 49 52 45 43 54 4f 52 59 3a 0a 09 09 09 73  _DIRECTORY:....s
7470: 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20  tbuf->st_mode = 
7480: 53 5f 49 46 44 49 52 20 7c 20 30 35 35 35 3b 0a  S_IFDIR | 0555;.
7490: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69  ...stbuf->st_nli
74a0: 6e 6b 20 3d 20 32 20 2b 20 70 61 74 68 69 6e 66  nk = 2 + pathinf
74b0: 6f 2e 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63  o.typeinfo.dir.c
74c0: 68 69 6c 64 63 6f 75 6e 74 3b 0a 09 09 09 62 72  hildcount;....br
74d0: 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46  eak;...case APPF
74e0: 53 5f 50 41 54 48 54 59 50 45 5f 46 49 4c 45 3a  S_PATHTYPE_FILE:
74f0: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
7500: 64 65 20 3d 20 53 5f 49 46 52 45 47 20 7c 20 30  de = S_IFREG | 0
7510: 34 34 34 3b 0a 0a 09 09 09 69 66 20 28 70 61 74  444;.....if (pat
7520: 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66  hinfo.typeinfo.f
7530: 69 6c 65 2e 65 78 65 63 75 74 61 62 6c 65 29 20  ile.executable) 
7540: 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  {.....stbuf->st_
7550: 6d 6f 64 65 20 7c 3d 20 30 31 31 31 3b 0a 09 09  mode |= 0111;...
7560: 09 7d 0a 0a 09 09 09 69 66 20 28 70 61 74 68 69  .}.....if (pathi
7570: 6e 66 6f 2e 70 61 63 6b 61 67 65 64 29 20 7b 0a  nfo.packaged) {.
7580: 09 09 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f  ....if (pathinfo
7590: 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73  .typeinfo.file.s
75a0: 75 69 64 52 6f 6f 74 29 20 7b 0a 09 09 09 09 09  uidRoot) {......
75b0: 63 68 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65  changeOwnerToUse
75c0: 72 49 66 50 61 63 6b 61 67 65 64 20 3d 20 30 3b  rIfPackaged = 0;
75d0: 0a 0a 09 09 09 09 09 73 74 62 75 66 2d 3e 73 74  .......stbuf->st
75e0: 5f 6d 6f 64 65 20 7c 3d 20 30 34 30 30 30 3b 0a  _mode |= 04000;.
75f0: 09 09 09 09 7d 0a 09 09 09 7d 0a 0a 09 09 09 69  ....}....}.....i
7600: 66 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65  f (pathinfo.type
7610: 69 6e 66 6f 2e 66 69 6c 65 2e 77 6f 72 6c 64 61  info.file.worlda
7620: 63 63 65 73 73 69 62 6c 65 29 20 7b 0a 09 09 09  ccessible) {....
7630: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
7640: 26 3d 20 7e 30 37 37 3b 0a 09 09 09 7d 0a 0a 09  &= ~077;....}...
7650: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e  ..stbuf->st_nlin
7660: 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d  k = 1;....stbuf-
7670: 3e 73 74 5f 73 69 7a 65 20 3d 20 70 61 74 68 69  >st_size = pathi
7680: 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  nfo.typeinfo.fil
7690: 65 2e 73 69 7a 65 3b 0a 0a 09 09 09 62 72 65 61  e.size;.....brea
76a0: 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f  k;...case APPFS_
76b0: 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b  PATHTYPE_SYMLINK
76c0: 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d  :....stbuf->st_m
76d0: 6f 64 65 20 3d 20 53 5f 49 46 4c 4e 4b 20 7c 20  ode = S_IFLNK | 
76e0: 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e  0555;....stbuf->
76f0: 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09  st_nlink = 1;...
7700: 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20  .stbuf->st_size 
7710: 3d 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69  = pathinfo.typei
7720: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65  nfo.symlink.size
7730: 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61  ;....break;...ca
7740: 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50  se APPFS_PATHTYP
7750: 45 5f 53 4f 43 4b 45 54 3a 0a 09 09 09 73 74 62  E_SOCKET:....stb
7760: 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f  uf->st_mode = S_
7770: 49 46 53 4f 43 4b 20 7c 20 30 35 35 35 3b 0a 09  IFSOCK | 0555;..
7780: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e  ..stbuf->st_nlin
7790: 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d  k = 1;....stbuf-
77a0: 3e 73 74 5f 73 69 7a 65 20 3d 20 30 3b 0a 09 09  >st_size = 0;...
77b0: 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41  .break;...case A
77c0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49  PPFS_PATHTYPE_FI
77d0: 46 4f 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74  FO:....stbuf->st
77e0: 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 49 46 4f 20  _mode = S_IFIFO 
77f0: 7c 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66  | 0555;....stbuf
7800: 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a  ->st_nlink = 1;.
7810: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a  ...stbuf->st_siz
7820: 65 20 3d 20 30 3b 0a 09 09 09 62 72 65 61 6b 3b  e = 0;....break;
7830: 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41  ...case APPFS_PA
7840: 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f  THTYPE_DOES_NOT_
7850: 45 58 49 53 54 3a 0a 09 09 09 72 65 74 76 61 6c  EXIST:....retval
7860: 20 3d 20 2d 45 4e 4f 45 4e 54 3b 0a 0a 09 09 09   = -ENOENT;.....
7870: 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50  break;...case AP
7880: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56  PFS_PATHTYPE_INV
7890: 41 4c 49 44 3a 0a 09 09 09 72 65 74 76 61 6c 20  ALID:....retval 
78a0: 3d 20 2d 45 49 4f 3b 0a 0a 09 09 09 62 72 65 61  = -EIO;.....brea
78b0: 6b 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 70 61 74  k;..}...if ((pat
78c0: 68 69 6e 66 6f 2e 70 61 63 6b 61 67 65 64 20 26  hinfo.packaged &
78d0: 26 20 63 68 61 6e 67 65 4f 77 6e 65 72 54 6f 55  & changeOwnerToU
78e0: 73 65 72 49 66 50 61 63 6b 61 67 65 64 29 20 7c  serIfPackaged) |
78f0: 7c 20 28 21 70 61 74 68 69 6e 66 6f 2e 70 61 63  | (!pathinfo.pac
7900: 6b 61 67 65 64 29 29 20 7b 0a 09 09 73 74 62 75  kaged)) {...stbu
7910: 66 2d 3e 73 74 5f 75 69 64 20 20 20 3d 20 61 70  f->st_uid   = ap
7920: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b  pfs_get_fsuid();
7930: 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f 67 69 64  ...stbuf->st_gid
7940: 20 20 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66     = appfs_get_f
7950: 73 67 69 64 28 29 3b 0a 09 09 73 74 62 75 66 2d  sgid();...stbuf-
7960: 3e 73 74 5f 6d 6f 64 65 20 7c 3d 20 30 32 30 30  >st_mode |= 0200
7970: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65  ;..}...return(re
7980: 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  tval);.}..static
7990: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
79a0: 72 65 61 64 64 69 72 28 63 6f 6e 73 74 20 63 68  readdir(const ch
79b0: 61 72 20 2a 70 61 74 68 2c 20 76 6f 69 64 20 2a  ar *path, void *
79c0: 62 75 66 2c 20 66 75 73 65 5f 66 69 6c 6c 5f 64  buf, fuse_fill_d
79d0: 69 72 5f 74 20 66 69 6c 6c 65 72 2c 20 6f 66 66  ir_t filler, off
79e0: 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63  _t offset, struc
79f0: 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f  t fuse_file_info
7a00: 20 2a 66 69 29 20 7b 0a 09 54 63 6c 5f 49 6e 74   *fi) {..Tcl_Int
7a10: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63  erp *interp;..Tc
7a20: 6c 5f 4f 62 6a 20 2a 2a 63 68 69 6c 64 72 65 6e  l_Obj **children
7a30: 3b 0a 09 69 6e 74 20 63 68 69 6c 64 72 65 6e 5f  ;..int children_
7a40: 63 6f 75 6e 74 2c 20 69 64 78 3b 0a 09 69 6e 74  count, idx;..int
7a50: 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46   tcl_ret;...APPF
7a60: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
7a70: 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22  path = %s, ...)"
7a80: 2c 20 70 61 74 68 29 3b 0a 0a 09 69 6e 74 65 72  , path);...inter
7a90: 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74  p = appfs_TclInt
7aa0: 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65  erp();..if (inte
7ab0: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
7ac0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72  APPFS_DEBUG("err
7ad0: 6f 72 3a 20 55 6e 61 62 6c 65 20 74 6f 20 67 65  or: Unable to ge
7ae0: 74 20 61 6e 20 69 6e 74 65 72 70 72 65 74 65 72  t an interpreter
7af0: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30 29  ");....return(0)
7b00: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
7b10: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65  l_libtcl(Tcl_Pre
7b20: 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a  serve(interp);).
7b30: 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e  ..filler(buf, ".
7b40: 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 66 69  ", NULL, 0);..fi
7b50: 6c 6c 65 72 28 62 75 66 2c 20 22 2e 2e 22 2c 20  ller(buf, "..", 
7b60: 4e 55 4c 4c 2c 20 30 29 3b 0a 0a 09 74 63 6c 5f  NULL, 0);...tcl_
7b70: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
7b80: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20  Eval(interp, 2, 
7b90: 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 63 68 69  "::appfs::getchi
7ba0: 6c 64 72 65 6e 22 2c 20 70 61 74 68 29 3b 0a 09  ldren", path);..
7bb0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
7bc0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
7bd0: 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a  _DEBUG("::appfs:
7be0: 3a 67 65 74 63 68 69 6c 64 72 65 6e 28 25 73 29  :getchildren(%s)
7bf0: 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29   failed.", path)
7c00: 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ;...appfs_call_l
7c10: 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f  ibtcl(....APPFS_
7c20: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72  DEBUG("Tcl Error
7c30: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
7c40: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
7c50: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61  terp));...)....a
7c60: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
7c70: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
7c80: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e  erp);)....return
7c90: 28 30 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  (0);..}...appfs_
7ca0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74  call_libtcl(...t
7cb0: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 4c 69 73  cl_ret = Tcl_Lis
7cc0: 74 4f 62 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28  tObjGetElements(
7cd0: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 4f  interp, Tcl_GetO
7ce0: 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  bjResult(interp)
7cf0: 2c 20 26 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e  , &children_coun
7d00: 74 2c 20 26 63 68 69 6c 64 72 65 6e 29 3b 0a 09  t, &children);..
7d10: 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  )..if (tcl_ret !
7d20: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50  = TCL_OK) {...AP
7d30: 50 46 53 5f 44 45 42 55 47 28 22 50 61 72 73 69  PFS_DEBUG("Parsi
7d40: 6e 67 20 6c 69 73 74 20 6f 66 20 63 68 69 6c 64  ng list of child
7d50: 72 65 6e 20 6f 6e 20 70 61 74 68 20 25 73 20 66  ren on path %s f
7d60: 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a  ailed.", path);.
7d70: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
7d80: 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45  tcl(....APPFS_DE
7d90: 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69  BUG("Tcl Error i
7da0: 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53  s: %s", Tcl_GetS
7db0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
7dc0: 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70  rp));...)....app
7dd0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
7de0: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
7df0: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 30  p);)....return(0
7e00: 29 3b 0a 09 7d 0a 0a 09 66 6f 72 20 28 69 64 78  );..}...for (idx
7e10: 20 3d 20 30 3b 20 69 64 78 20 3c 20 63 68 69 6c   = 0; idx < chil
7e20: 64 72 65 6e 5f 63 6f 75 6e 74 3b 20 69 64 78 2b  dren_count; idx+
7e30: 2b 29 20 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c  +) {...appfs_cal
7e40: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 66 69 6c  l_libtcl(....fil
7e50: 6c 65 72 28 62 75 66 2c 20 54 63 6c 5f 47 65 74  ler(buf, Tcl_Get
7e60: 53 74 72 69 6e 67 28 63 68 69 6c 64 72 65 6e 5b  String(children[
7e70: 69 64 78 5d 29 2c 20 4e 55 4c 4c 2c 20 30 29 3b  idx]), NULL, 0);
7e80: 0a 09 09 29 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  ...)..}...appfs_
7e90: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
7ea0: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
7eb0: 29 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  )...return(0);.}
7ec0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
7ed0: 66 73 5f 66 75 73 65 5f 6f 70 65 6e 28 63 6f 6e  fs_fuse_open(con
7ee0: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73  st char *path, s
7ef0: 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f  truct fuse_file_
7f00: 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c  info *fi) {..Tcl
7f10: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
7f20: 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70  ..struct appfs_p
7f30: 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f  athinfo pathinfo
7f40: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72  ;..const char *r
7f50: 65 61 6c 5f 70 61 74 68 2c 20 2a 6d 6f 64 65 3b  eal_path, *mode;
7f60: 0a 09 69 6e 74 20 67 70 69 5f 72 65 74 2c 20 74  ..int gpi_ret, t
7f70: 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 66 68 3b  cl_ret;..int fh;
7f80: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
7f90: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
7fa0: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
7fb0: 0a 09 67 70 69 5f 72 65 74 20 3d 20 61 70 70 66  ..gpi_ret = appf
7fc0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28  s_get_path_info(
7fd0: 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29  path, &pathinfo)
7fe0: 3b 0a 0a 09 69 66 20 28 28 66 69 2d 3e 66 6c 61  ;...if ((fi->fla
7ff0: 67 73 20 26 20 28 4f 5f 57 52 4f 4e 4c 59 7c 4f  gs & (O_WRONLY|O
8000: 5f 43 52 45 41 54 29 29 20 3d 3d 20 28 4f 5f 43  _CREAT)) == (O_C
8010: 52 45 41 54 7c 4f 5f 57 52 4f 4e 4c 59 29 29 20  REAT|O_WRONLY)) 
8020: 7b 0a 09 09 2f 2a 20 54 68 65 20 66 69 6c 65 20  {.../* The file 
8030: 77 69 6c 6c 20 62 65 20 63 72 65 61 74 65 64 20  will be created 
8040: 69 66 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 65  if it does not e
8050: 78 69 73 74 20 2a 2f 0a 09 09 69 66 20 28 67 70  xist */...if (gp
8060: 69 5f 72 65 74 20 21 3d 20 30 20 26 26 20 67 70  i_ret != 0 && gp
8070: 69 5f 72 65 74 20 21 3d 20 2d 45 4e 4f 45 4e 54  i_ret != -ENOENT
8080: 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42  ) {....APPFS_DEB
8090: 55 47 28 22 65 72 72 6f 72 3a 20 67 65 74 5f 70  UG("error: get_p
80a0: 61 74 68 5f 69 6e 66 6f 20 66 61 69 6c 65 64 22  ath_info failed"
80b0: 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 67 70  );.....return(gp
80c0: 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d  i_ret);...}....m
80d0: 6f 64 65 20 3d 20 22 63 72 65 61 74 65 22 3b 0a  ode = "create";.
80e0: 0a 09 09 2f 2a 0a 09 09 20 2a 20 57 65 20 68 61  .../*... * We ha
80f0: 76 65 20 74 6f 20 63 6c 65 61 72 20 74 68 65 20  ve to clear the 
8100: 63 61 63 68 65 20 68 65 72 65 20 73 6f 20 74 68  cache here so th
8110: 61 74 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  at the number of
8120: 0a 09 09 20 2a 20 6c 69 6e 6b 73 20 67 65 74 73  ... * links gets
8130: 20 6d 61 69 6e 74 61 69 6e 65 64 20 6f 6e 20 74   maintained on t
8140: 68 65 20 70 61 72 65 6e 74 20 64 69 72 65 63 74  he parent direct
8150: 6f 72 79 0a 09 09 20 2a 2f 0a 09 09 61 70 70 66  ory... */...appf
8160: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
8170: 63 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66  cache_flush(appf
8180: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d  s_get_fsuid(), -
8190: 31 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09  1);..} else {...
81a0: 2f 2a 20 54 68 65 20 66 69 6c 65 20 6d 75 73 74  /* The file must
81b0: 20 61 6c 72 65 61 64 79 20 65 78 69 73 74 20 2a   already exist *
81c0: 2f 0a 09 09 69 66 20 28 67 70 69 5f 72 65 74 20  /...if (gpi_ret 
81d0: 21 3d 20 30 29 20 7b 0a 09 09 09 41 50 50 46 53  != 0) {....APPFS
81e0: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 67  _DEBUG("error: g
81f0: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20 66 61 69  et_path_info fai
8200: 6c 65 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72  led");.....retur
8210: 6e 28 67 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a  n(gpi_ret);...}.
8220: 0a 09 09 6d 6f 64 65 20 3d 20 22 22 3b 0a 0a 09  ...mode = "";...
8230: 09 69 66 20 28 28 66 69 2d 3e 66 6c 61 67 73 20  .if ((fi->flags 
8240: 26 20 4f 5f 57 52 4f 4e 4c 59 29 20 3d 3d 20 4f  & O_WRONLY) == O
8250: 5f 57 52 4f 4e 4c 59 29 20 7b 0a 09 09 09 6d 6f  _WRONLY) {....mo
8260: 64 65 20 3d 20 22 77 72 69 74 65 22 3b 0a 09 09  de = "write";...
8270: 7d 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69  }..}...if (pathi
8280: 6e 66 6f 2e 74 79 70 65 20 3d 3d 20 41 50 50 46  nfo.type == APPF
8290: 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45 43  S_PATHTYPE_DIREC
82a0: 54 4f 52 59 29 20 7b 0a 09 09 41 50 50 46 53 5f  TORY) {...APPFS_
82b0: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 41 73  DEBUG("error: As
82c0: 6b 65 64 20 74 6f 20 6f 70 65 6e 20 61 20 64 69  ked to open a di
82d0: 72 65 63 74 6f 72 79 2e 22 29 3b 0a 0a 09 09 72  rectory.");....r
82e0: 65 74 75 72 6e 28 2d 45 49 53 44 49 52 29 3b 0a  eturn(-EISDIR);.
82f0: 09 7d 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  .}...interp = ap
8300: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  pfs_TclInterp();
8310: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
8320: 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f  NULL) {...APPFS_
8330: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 55 6e  DEBUG("error: Un
8340: 61 62 6c 65 20 74 6f 20 67 65 74 20 61 6e 20 69  able to get an i
8350: 6e 74 65 72 70 72 65 74 65 72 22 29 3b 0a 0a 09  nterpreter");...
8360: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
8370: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
8380: 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72  ibtcl(Tcl_Preser
8390: 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74  ve(interp);)...t
83a0: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
83b0: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
83c0: 33 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65  3, "::appfs::ope
83d0: 6e 70 61 74 68 22 2c 20 70 61 74 68 2c 20 6d 6f  npath", path, mo
83e0: 64 65 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65  de);..if (tcl_re
83f0: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
8400: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a  .APPFS_DEBUG("::
8410: 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28  appfs::openpath(
8420: 25 73 2c 20 25 73 29 20 66 61 69 6c 65 64 2e 22  %s, %s) failed."
8430: 2c 20 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 09  , path, mode);..
8440: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
8450: 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42  cl(....APPFS_DEB
8460: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
8470: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
8480: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
8490: 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66  p));...)....appf
84a0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
84b0: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
84c0: 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45  );)....return(-E
84d0: 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  IO);..}...appfs_
84e0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72  call_libtcl(...r
84f0: 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47  eal_path = Tcl_G
8500: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
8510: 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70  nterp);..)...app
8520: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
8530: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
8540: 70 29 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f  p);)...if (real_
8550: 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  path == NULL) {.
8560: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65  ..APPFS_DEBUG("e
8570: 72 72 6f 72 3a 20 72 65 61 6c 5f 70 61 74 68 20  rror: real_path 
8580: 77 61 73 20 4e 55 4c 4c 2e 22 29 0a 0a 09 09 72  was NULL.")....r
8590: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
85a0: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
85b0: 72 61 6e 73 6c 61 74 65 64 20 72 65 71 75 65 73  ranslated reques
85c0: 74 20 74 6f 20 6f 70 65 6e 20 25 73 20 74 6f 20  t to open %s to 
85d0: 6f 70 65 6e 69 6e 67 20 25 73 20 28 6d 6f 64 65  opening %s (mode
85e0: 20 3d 20 5c 22 25 73 5c 22 29 22 2c 20 70 61 74   = \"%s\")", pat
85f0: 68 2c 20 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f  h, real_path, mo
8600: 64 65 29 3b 0a 0a 09 66 68 20 3d 20 6f 70 65 6e  de);...fh = open
8610: 28 72 65 61 6c 5f 70 61 74 68 2c 20 66 69 2d 3e  (real_path, fi->
8620: 66 6c 61 67 73 2c 20 30 36 30 30 29 3b 0a 0a 09  flags, 0600);...
8630: 69 66 20 28 66 68 20 3c 20 30 29 20 7b 0a 09 09  if (fh < 0) {...
8640: 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72  APPFS_DEBUG("err
8650: 6f 72 3a 20 6f 70 65 6e 20 66 61 69 6c 65 64 22  or: open failed"
8660: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 65 72 72  );....return(err
8670: 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66  no * -1);..}...f
8680: 69 2d 3e 66 68 20 3d 20 66 68 3b 0a 0a 09 41 50  i->fh = fh;...AP
8690: 50 46 53 5f 44 45 42 55 47 28 22 4f 70 65 6e 65  PFS_DEBUG("Opene
86a0: 64 20 5c 22 25 73 5c 22 20 28 66 6f 72 20 5c 22  d \"%s\" (for \"
86b0: 25 73 5c 22 29 20 77 69 74 68 20 66 69 6c 65 20  %s\") with file 
86c0: 64 65 73 63 72 69 70 74 6f 72 20 25 69 22 2c 20  descriptor %i", 
86d0: 72 65 61 6c 5f 70 61 74 68 2c 20 70 61 74 68 2c  real_path, path,
86e0: 20 66 68 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30   fh);...return(0
86f0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
8700: 20 61 70 70 66 73 5f 66 75 73 65 5f 63 6c 6f 73   appfs_fuse_clos
8710: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  e(const char *pa
8720: 74 68 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f  th, struct fuse_
8730: 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b  file_info *fi) {
8740: 0a 09 69 6e 74 20 63 6c 6f 73 65 5f 72 65 74 3b  ..int close_ret;
8750: 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74  ...appfs_get_pat
8760: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28  h_info_cache_rm(
8770: 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f  path, appfs_get_
8780: 66 73 75 69 64 28 29 29 3b 0a 0a 09 63 6c 6f 73  fsuid());...clos
8790: 65 5f 72 65 74 20 3d 20 63 6c 6f 73 65 28 66 69  e_ret = close(fi
87a0: 2d 3e 66 68 29 3b 0a 09 69 66 20 28 63 6c 6f 73  ->fh);..if (clos
87b0: 65 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  e_ret != 0) {...
87c0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72  APPFS_DEBUG("err
87d0: 6f 72 3a 20 63 6c 6f 73 65 20 66 61 69 6c 65 64  or: close failed
87e0: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 65 72  ");....return(er
87f0: 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09  rno * -1);..}...
8800: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74  return(0);.}..st
8810: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
8820: 75 73 65 5f 72 65 61 64 28 63 6f 6e 73 74 20 63  use_read(const c
8830: 68 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72 20  har *path, char 
8840: 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a  *buf, size_t siz
8850: 65 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c  e, off_t offset,
8860: 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c   struct fuse_fil
8870: 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 73  e_info *fi) {..s
8880: 73 69 7a 65 5f 74 20 72 65 61 64 5f 72 65 74 3b  size_t read_ret;
8890: 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09  ..int retval;...
88a0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
88b0: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 62  er (path = %s, b
88c0: 75 66 2c 20 73 69 7a 65 20 3d 20 25 6c 6c 69 2c  uf, size = %lli,
88d0: 20 6f 66 66 73 65 74 20 3d 20 25 6c 6c 69 2c 20   offset = %lli, 
88e0: 66 64 20 3d 20 25 6c 6c 69 29 22 2c 20 70 61 74  fd = %lli)", pat
88f0: 68 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73  h, (long long) s
8900: 69 7a 65 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29  ize, (long long)
8910: 20 6f 66 66 73 65 74 2c 20 28 6c 6f 6e 67 20 6c   offset, (long l
8920: 6f 6e 67 29 20 66 69 2d 3e 66 68 29 3b 0a 0a 09  ong) fi->fh);...
8930: 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 77 68  retval = 0;...wh
8940: 69 6c 65 20 28 73 69 7a 65 20 21 3d 20 30 29 20  ile (size != 0) 
8950: 7b 0a 09 09 72 65 61 64 5f 72 65 74 20 3d 20 70  {...read_ret = p
8960: 72 65 61 64 28 66 69 2d 3e 66 68 2c 20 62 75 66  read(fi->fh, buf
8970: 2c 20 73 69 7a 65 2c 20 6f 66 66 73 65 74 29 3b  , size, offset);
8980: 0a 0a 09 09 69 66 20 28 72 65 61 64 5f 72 65 74  ....if (read_ret
8990: 20 3c 20 30 29 20 7b 0a 09 09 09 41 50 50 46 53   < 0) {....APPFS
89a0: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 72  _DEBUG("error: r
89b0: 65 61 64 20 66 61 69 6c 65 64 22 29 3b 0a 0a 09  ead failed");...
89c0: 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a  ..return(errno *
89d0: 20 2d 31 29 3b 0a 09 09 7d 0a 0a 09 09 69 66 20   -1);...}....if 
89e0: 28 72 65 61 64 5f 72 65 74 20 3d 3d 20 30 29 20  (read_ret == 0) 
89f0: 7b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 7d 0a  {....break;...}.
8a00: 0a 09 09 73 69 7a 65 20 2d 3d 20 72 65 61 64 5f  ...size -= read_
8a10: 72 65 74 3b 0a 09 09 62 75 66 20 20 2b 3d 20 72  ret;...buf  += r
8a20: 65 61 64 5f 72 65 74 3b 0a 09 09 6f 66 66 73 65  ead_ret;...offse
8a30: 74 20 2b 3d 20 72 65 61 64 5f 72 65 74 3b 0a 09  t += read_ret;..
8a40: 09 72 65 74 76 61 6c 20 2b 3d 20 72 65 61 64 5f  .retval += read_
8a50: 72 65 74 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 69  ret;..}...if (si
8a60: 7a 65 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50  ze != 0) {...APP
8a70: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
8a80: 20 69 6e 63 6f 6d 70 6c 65 74 65 20 72 65 61 64   incomplete read
8a90: 20 28 74 68 69 73 20 6d 69 67 68 74 20 62 65 20   (this might be 
8aa0: 61 6e 20 65 72 72 6f 72 20 62 65 63 61 75 73 65  an error because
8ab0: 20 46 55 53 45 20 77 69 6c 6c 20 72 65 71 75 65   FUSE will reque
8ac0: 73 74 20 74 68 65 20 65 78 61 63 74 20 6c 65 6e  st the exact len
8ad0: 67 74 68 20 6f 66 20 74 68 65 20 66 69 6c 65 29  gth of the file)
8ae0: 22 29 3b 0a 09 7d 0a 0a 09 41 50 50 46 53 5f 44  ");..}...APPFS_D
8af0: 45 42 55 47 28 22 52 65 74 75 72 6e 69 6e 67 3a  EBUG("Returning:
8b00: 20 25 69 22 2c 20 72 65 74 76 61 6c 29 3b 0a 0a   %i", retval);..
8b10: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
8b20: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
8b30: 70 70 66 73 5f 66 75 73 65 5f 77 72 69 74 65 28  ppfs_fuse_write(
8b40: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
8b50: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 62 75  , const char *bu
8b60: 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20  f, size_t size, 
8b70: 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20 73 74  off_t offset, st
8b80: 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69  ruct fuse_file_i
8b90: 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 73 73 69 7a  nfo *fi) {..ssiz
8ba0: 65 5f 74 20 77 72 69 74 65 5f 72 65 74 3b 0a 09  e_t write_ret;..
8bb0: 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09 41 50  int retval;...AP
8bc0: 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72  PFS_DEBUG("Enter
8bd0: 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e   (path = %s, ...
8be0: 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70 70  )", path);...app
8bf0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
8c00: 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20  _cache_rm(path, 
8c10: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28  appfs_get_fsuid(
8c20: 29 29 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 30  ));...retval = 0
8c30: 3b 0a 0a 09 77 68 69 6c 65 20 28 73 69 7a 65 20  ;...while (size 
8c40: 21 3d 20 30 29 20 7b 0a 09 09 77 72 69 74 65 5f  != 0) {...write_
8c50: 72 65 74 20 3d 20 70 77 72 69 74 65 28 66 69 2d  ret = pwrite(fi-
8c60: 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a 65 2c 20  >fh, buf, size, 
8c70: 6f 66 66 73 65 74 29 3b 0a 0a 09 09 69 66 20 28  offset);....if (
8c80: 77 72 69 74 65 5f 72 65 74 20 3c 20 30 29 20 7b  write_ret < 0) {
8c90: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
8ca0: 22 65 72 72 6f 72 3a 20 77 72 69 74 65 20 66 61  "error: write fa
8cb0: 69 6c 65 64 22 29 3b 0a 0a 09 09 09 72 65 74 75  iled");.....retu
8cc0: 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a  rn(errno * -1);.
8cd0: 09 09 7d 0a 0a 09 09 69 66 20 28 77 72 69 74 65  ..}....if (write
8ce0: 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09 09 09  _ret == 0) {....
8cf0: 62 72 65 61 6b 3b 0a 09 09 7d 0a 0a 09 09 73 69  break;...}....si
8d00: 7a 65 20 2d 3d 20 77 72 69 74 65 5f 72 65 74 3b  ze -= write_ret;
8d10: 0a 09 09 62 75 66 20 20 2b 3d 20 77 72 69 74 65  ...buf  += write
8d20: 5f 72 65 74 3b 0a 09 09 6f 66 66 73 65 74 20 2b  _ret;...offset +
8d30: 3d 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 09 72  = write_ret;...r
8d40: 65 74 76 61 6c 20 2b 3d 20 77 72 69 74 65 5f 72  etval += write_r
8d50: 65 74 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 69 7a  et;..}...if (siz
8d60: 65 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  e != 0) {...APPF
8d70: 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20  S_DEBUG("error: 
8d80: 69 6e 63 6f 6d 70 6c 65 74 65 20 77 72 69 74 65  incomplete write
8d90: 22 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  ");..}...return(
8da0: 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74  retval);.}..stat
8db0: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
8dc0: 65 5f 6d 6b 6e 6f 64 28 63 6f 6e 73 74 20 63 68  e_mknod(const ch
8dd0: 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74  ar *path, mode_t
8de0: 20 6d 6f 64 65 2c 20 64 65 76 5f 74 20 64 65 76   mode, dev_t dev
8df0: 69 63 65 29 20 7b 0a 09 63 68 61 72 20 2a 72 65  ice) {..char *re
8e00: 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 6d 6b  al_path;..int mk
8e10: 6e 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53  nod_ret;...APPFS
8e20: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
8e30: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c  ath = %s, ...)",
8e40: 20 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 28 6d   path);...if ((m
8e50: 6f 64 65 20 26 20 53 5f 49 46 43 48 52 29 20 3d  ode & S_IFCHR) =
8e60: 3d 20 53 5f 49 46 43 48 52 29 20 7b 0a 09 09 72  = S_IFCHR) {...r
8e70: 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09  eturn(-EPERM);..
8e80: 7d 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20  }...if ((mode & 
8e90: 53 5f 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49 46  S_IFBLK) == S_IF
8ea0: 42 4c 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  BLK) {...return(
8eb0: 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65  -EPERM);..}...re
8ec0: 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f  al_path = appfs_
8ed0: 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74  prepare_to_creat
8ee0: 65 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65  e(path);..if (re
8ef0: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
8f00: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f   {...return(-EIO
8f10: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69  );..}...appfs_si
8f20: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65  mulate_user_fs_e
8f30: 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b 6e 6f 64 5f  nter();...mknod_
8f40: 72 65 74 20 3d 20 6d 6b 6e 6f 64 28 72 65 61 6c  ret = mknod(real
8f50: 5f 70 61 74 68 2c 20 6d 6f 64 65 2c 20 64 65 76  _path, mode, dev
8f60: 69 63 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  ice);...appfs_si
8f70: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
8f80: 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72  eave();...free(r
8f90: 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20  eal_path);...if 
8fa0: 28 6d 6b 6e 6f 64 5f 72 65 74 20 21 3d 20 30 29  (mknod_ret != 0)
8fb0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e   {...return(errn
8fc0: 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65  o * -1);..}...re
8fd0: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
8fe0: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
8ff0: 65 5f 63 72 65 61 74 65 28 63 6f 6e 73 74 20 63  e_create(const c
9000: 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f  har *path, mode_
9010: 74 20 6d 6f 64 65 2c 20 73 74 72 75 63 74 20 66  t mode, struct f
9020: 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66  use_file_info *f
9030: 69 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c  i) {..char *real
9040: 5f 70 61 74 68 3b 0a 09 69 6e 74 20 66 64 3b 0a  _path;..int fd;.
9050: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45  ..APPFS_DEBUG("E
9060: 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c  nter (path = %s,
9070: 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a   ...)", path);..
9080: 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49  .if ((mode & S_I
9090: 46 43 48 52 29 20 3d 3d 20 53 5f 49 46 43 48 52  FCHR) == S_IFCHR
90a0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50  ) {...return(-EP
90b0: 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28  ERM);..}...if ((
90c0: 6d 6f 64 65 20 26 20 53 5f 49 46 42 4c 4b 29 20  mode & S_IFBLK) 
90d0: 3d 3d 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09  == S_IFBLK) {...
90e0: 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a  return(-EPERM);.
90f0: 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d  .}...real_path =
9100: 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74   appfs_prepare_t
9110: 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a  o_create(path);.
9120: 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d  .if (real_path =
9130: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
9140: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
9150: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
9160: 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a  er_fs_enter();..
9170: 09 66 64 20 3d 20 63 72 65 61 74 28 72 65 61 6c  .fd = creat(real
9180: 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09  _path, mode);...
9190: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
91a0: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a  ser_fs_leave();.
91b0: 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68  ..free(real_path
91c0: 29 3b 0a 0a 09 69 66 20 28 66 64 20 3c 20 30 29  );...if (fd < 0)
91d0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e   {...return(errn
91e0: 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66 69  o * -1);..}...fi
91f0: 2d 3e 66 68 20 3d 20 66 64 3b 0a 0a 09 72 65 74  ->fh = fd;...ret
9200: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69  urn(0);.}..stati
9210: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
9220: 5f 74 72 75 6e 63 61 74 65 28 63 6f 6e 73 74 20  _truncate(const 
9230: 63 68 61 72 20 2a 70 61 74 68 2c 20 6f 66 66 5f  char *path, off_
9240: 74 20 73 69 7a 65 29 20 7b 0a 09 63 68 61 72 20  t size) {..char 
9250: 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74  *real_path;..int
9260: 20 74 72 75 6e 63 61 74 65 5f 72 65 74 3b 0a 0a   truncate_ret;..
9270: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
9280: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
9290: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09  ...)", path);...
92a0: 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66  real_path = appf
92b0: 73 5f 6c 6f 63 61 6c 70 61 74 68 28 70 61 74 68  s_localpath(path
92c0: 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74  );..if (real_pat
92d0: 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  h == NULL) {...r
92e0: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
92f0: 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  ..appfs_get_path
9300: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70  _info_cache_rm(p
9310: 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66  ath, appfs_get_f
9320: 73 75 69 64 28 29 29 3b 0a 0a 09 61 70 70 66 73  suid());...appfs
9330: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
9340: 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 74 72 75  s_enter();...tru
9350: 6e 63 61 74 65 5f 72 65 74 20 3d 20 74 72 75 6e  ncate_ret = trun
9360: 63 61 74 65 28 72 65 61 6c 5f 70 61 74 68 2c 20  cate(real_path, 
9370: 73 69 7a 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73  size);...appfs_s
9380: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
9390: 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28  leave();...free(
93a0: 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66  real_path);...if
93b0: 20 28 74 72 75 6e 63 61 74 65 5f 72 65 74 20 21   (truncate_ret !
93c0: 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  = 0) {...return(
93d0: 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a  errno * -1);..}.
93e0: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
93f0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
9400: 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64  _fuse_unlink_rmd
9410: 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  ir(const char *p
9420: 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  ath) {..Tcl_Inte
9430: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 69 6e 74  rp *interp;..int
9440: 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46   tcl_ret;...APPF
9450: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
9460: 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22  path = %s, ...)"
9470: 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 73  , path);...appfs
9480: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
9490: 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73  ache_flush(appfs
94a0: 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31  _get_fsuid(), -1
94b0: 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  );...interp = ap
94c0: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  pfs_TclInterp();
94d0: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
94e0: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
94f0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70  (-EIO);..}...app
9500: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
9510: 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65  cl_Preserve(inte
9520: 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72 65 74 20  rp);)...tcl_ret 
9530: 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c  = appfs_Tcl_Eval
9540: 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61  (interp, 2, "::a
9550: 70 70 66 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68  ppfs::unlinkpath
9560: 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28 74  ", path);..if (t
9570: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
9580: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
9590: 47 28 22 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c 69  G("::appfs::unli
95a0: 6e 6b 70 61 74 68 28 25 73 29 20 66 61 69 6c 65  nkpath(%s) faile
95b0: 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61 70  d.", path);...ap
95c0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
95d0: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
95e0: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
95f0: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
9600: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
9610: 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63  ;...)....appfs_c
9620: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
9630: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
9640: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  ....return(-EIO)
9650: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
9660: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
9670: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
9680: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
9690: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
96a0: 66 75 73 65 5f 6d 6b 64 69 72 28 63 6f 6e 73 74  fuse_mkdir(const
96b0: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64   char *path, mod
96c0: 65 5f 74 20 6d 6f 64 65 29 20 7b 0a 09 63 68 61  e_t mode) {..cha
96d0: 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69  r *real_path;..i
96e0: 6e 74 20 6d 6b 64 69 72 5f 72 65 74 3b 0a 0a 09  nt mkdir_ret;...
96f0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
9700: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
9710: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 72  ..)", path);...r
9720: 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73  eal_path = appfs
9730: 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61  _prepare_to_crea
9740: 74 65 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72  te(path);..if (r
9750: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
9760: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
9770: 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73  O);..}...appfs_s
9780: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
9790: 65 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b 64 69 72  enter();...mkdir
97a0: 5f 72 65 74 20 3d 20 6d 6b 64 69 72 28 72 65 61  _ret = mkdir(rea
97b0: 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a  l_path, mode);..
97c0: 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  .appfs_simulate_
97d0: 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b  user_fs_leave();
97e0: 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74  ...free(real_pat
97f0: 68 29 3b 0a 0a 09 69 66 20 28 6d 6b 64 69 72 5f  h);...if (mkdir_
9800: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 69 66  ret != 0) {...if
9810: 20 28 65 72 72 6e 6f 20 21 3d 20 45 45 58 49 53   (errno != EEXIS
9820: 54 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 65  T) {....return(e
9830: 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 09 7d 0a  rrno * -1);...}.
9840: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  .}...return(0);.
9850: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
9860: 70 66 73 5f 66 75 73 65 5f 63 68 6d 6f 64 28 63  pfs_fuse_chmod(c
9870: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
9880: 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 29 20 7b 0a   mode_t mode) {.
9890: 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  .Tcl_Interp *int
98a0: 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72  erp;..const char
98b0: 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e   *real_path;..in
98c0: 74 20 74 63 6c 5f 72 65 74 2c 20 63 68 6d 6f 64  t tcl_ret, chmod
98d0: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
98e0: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
98f0: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
9900: 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74  th);...appfs_get
9910: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
9920: 5f 72 6d 28 70 61 74 68 2c 20 61 70 70 66 73 5f  _rm(path, appfs_
9930: 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09  get_fsuid());...
9940: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54  interp = appfs_T
9950: 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20  clInterp();..if 
9960: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
9970: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f   {...return(-EIO
9980: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61  );..}...appfs_ca
9990: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72  ll_libtcl(Tcl_Pr
99a0: 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29  eserve(interp);)
99b0: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70  ...tcl_ret = app
99c0: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65  fs_Tcl_Eval(inte
99d0: 72 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a  rp, 3, "::appfs:
99e0: 3a 6f 70 65 6e 70 61 74 68 22 2c 20 70 61 74 68  :openpath", path
99f0: 2c 20 22 77 72 69 74 65 22 29 3b 0a 09 69 66 20  , "write");..if 
9a00: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
9a10: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
9a20: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6f 70  BUG("::appfs::op
9a30: 65 6e 70 61 74 68 28 25 73 2c 20 25 73 29 20 66  enpath(%s, %s) f
9a40: 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 2c 20 22  ailed.", path, "
9a50: 77 72 69 74 65 22 29 3b 0a 09 09 61 70 70 66 73  write");...appfs
9a60: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
9a70: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63  .APPFS_DEBUG("Tc
9a80: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c  l Error is: %s",
9a90: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
9aa0: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09  sult(interp));..
9ab0: 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  .)....appfs_call
9ac0: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
9ad0: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
9ae0: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
9af0: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
9b00: 69 62 74 63 6c 28 0a 09 09 72 65 61 6c 5f 70 61  ibtcl(...real_pa
9b10: 74 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  th = Tcl_GetStri
9b20: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
9b30: 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..)...appfs_cal
9b40: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
9b50: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
9b60: 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d  .if (real_path =
9b70: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
9b80: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
9b90: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
9ba0: 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a  er_fs_enter();..
9bb0: 09 63 68 6d 6f 64 5f 72 65 74 20 3d 20 63 68 6d  .chmod_ret = chm
9bc0: 6f 64 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f  od(real_path, mo
9bd0: 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d  de);...appfs_sim
9be0: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65  ulate_user_fs_le
9bf0: 61 76 65 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28  ave();...return(
9c00: 63 68 6d 6f 64 5f 72 65 74 29 3b 0a 7d 0a 0a 73  chmod_ret);.}..s
9c10: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
9c20: 66 75 73 65 5f 73 79 6d 6c 69 6e 6b 28 63 6f 6e  fuse_symlink(con
9c30: 73 74 20 63 68 61 72 20 2a 6f 6c 64 70 61 74 68  st char *oldpath
9c40: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 6e 65  , const char *ne
9c50: 77 70 61 74 68 29 20 7b 0a 09 63 68 61 72 20 2a  wpath) {..char *
9c60: 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20  real_path;..int 
9c70: 73 79 6d 6c 69 6e 6b 5f 72 65 74 3b 0a 0a 09 41  symlink_ret;...A
9c80: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
9c90: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 25 73  r (path = %s, %s
9ca0: 29 22 2c 20 6f 6c 64 70 61 74 68 2c 20 6e 65 77  )", oldpath, new
9cb0: 70 61 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61  path);...real_pa
9cc0: 74 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70 61  th = appfs_prepa
9cd0: 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 6e 65 77  re_to_create(new
9ce0: 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c  path);..if (real
9cf0: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
9d00: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
9d10: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  ..}...appfs_simu
9d20: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
9d30: 65 72 28 29 3b 0a 0a 09 73 79 6d 6c 69 6e 6b 5f  er();...symlink_
9d40: 72 65 74 20 3d 20 73 79 6d 6c 69 6e 6b 28 6f 6c  ret = symlink(ol
9d50: 64 70 61 74 68 2c 20 72 65 61 6c 5f 70 61 74 68  dpath, real_path
9d60: 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c  );...appfs_simul
9d70: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76  ate_user_fs_leav
9d80: 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c  e();...free(real
9d90: 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 73 79  _path);...if (sy
9da0: 6d 6c 69 6e 6b 5f 72 65 74 20 21 3d 20 30 29 20  mlink_ret != 0) 
9db0: 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f  {...return(errno
9dc0: 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74   * -1);..}...ret
9dd0: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  urn(0);.}../*. *
9de0: 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 3a 20 45   SQLite3 mode: E
9df0: 78 65 63 75 74 65 20 72 61 77 20 53 51 4c 20 61  xecute raw SQL a
9e00: 6e 64 20 72 65 74 75 72 6e 20 73 75 63 63 65 73  nd return succes
9e10: 73 20 6f 72 20 66 61 69 6c 75 72 65 0a 20 2a 2f  s or failure. */
9e20: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
9e30: 73 5f 73 71 6c 69 74 65 33 28 63 6f 6e 73 74 20  s_sqlite3(const 
9e40: 63 68 61 72 20 2a 73 71 6c 29 20 7b 0a 09 54 63  char *sql) {..Tc
9e50: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
9e60: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 73  ;..const char *s
9e70: 71 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 74 63 6c  ql_ret;..int tcl
9e80: 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d  _ret;...interp =
9e90: 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63   appfs_create_Tc
9ea0: 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 09  lInterp(NULL);..
9eb0: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
9ec0: 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28  LL) {...fprintf(
9ed0: 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20  stderr, "Unable 
9ee0: 74 6f 20 63 72 65 61 74 65 20 61 20 54 63 6c 20  to create a Tcl 
9ef0: 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41 62  interpreter.  Ab
9f00: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09  orting.\n");....
9f10: 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09  return(1);..}...
9f20: 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f  tcl_ret = appfs_
9f30: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
9f40: 20 35 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 64 62   5, "::appfs::db
9f50: 22 2c 20 22 65 76 61 6c 22 2c 20 73 71 6c 2c 20  ", "eval", sql, 
9f60: 22 72 6f 77 22 2c 20 22 75 6e 73 65 74 20 2d 6e  "row", "unset -n
9f70: 6f 63 6f 6d 70 6c 61 69 6e 20 72 6f 77 28 2a 29  ocomplain row(*)
9f80: 3b 20 70 61 72 72 61 79 20 72 6f 77 3b 20 70 75  ; parray row; pu
9f90: 74 73 20 5c 22 2d 2d 2d 2d 5c 22 22 29 3b 0a 09  ts \"----\"");..
9fa0: 73 71 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65  sql_ret = Tcl_Ge
9fb0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
9fc0: 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 74 63 6c  terp);...if (tcl
9fd0: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  _ret != TCL_OK) 
9fe0: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  {...fprintf(stde
9ff0: 72 72 2c 20 22 5b 65 72 72 6f 72 5d 20 25 73 5c  rr, "[error] %s\
a000: 6e 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a 0a 09  n", sql_ret);...
a010: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a  .return(1);..}..
a020: 09 69 66 20 28 73 71 6c 5f 72 65 74 20 26 26 20  .if (sql_ret && 
a030: 73 71 6c 5f 72 65 74 5b 30 5d 20 21 3d 20 27 5c  sql_ret[0] != '\
a040: 30 27 29 20 7b 0a 09 09 70 72 69 6e 74 66 28 22  0') {...printf("
a050: 25 73 5c 6e 22 2c 20 73 71 6c 5f 72 65 74 29 3b  %s\n", sql_ret);
a060: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  ..}...return(0);
a070: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 63 6c 20 6d 6f  .}../*. * Tcl mo
a080: 64 65 3a 20 45 78 65 63 75 74 65 20 72 61 77 20  de: Execute raw 
a090: 54 63 6c 20 61 6e 64 20 72 65 74 75 72 6e 20 73  Tcl and return s
a0a0: 75 63 63 65 73 73 20 6f 72 20 66 61 69 6c 75 72  uccess or failur
a0b0: 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e. */.static int
a0c0: 20 61 70 70 66 73 5f 74 63 6c 28 63 6f 6e 73 74   appfs_tcl(const
a0d0: 20 63 68 61 72 20 2a 74 63 6c 29 20 7b 0a 09 54   char *tcl) {..T
a0e0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
a0f0: 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a  p;..const char *
a100: 74 63 6c 5f 72 65 73 75 6c 74 3b 0a 09 69 6e 74  tcl_result;..int
a110: 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65   tcl_ret;...inte
a120: 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61 74  rp = appfs_creat
a130: 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c  e_TclInterp(NULL
a140: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  );..if (interp =
a150: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69  = NULL) {...fpri
a160: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61  ntf(stderr, "Una
a170: 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20 61 20  ble to create a 
a180: 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e  Tcl interpreter.
a190: 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b    Aborting.\n");
a1a0: 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  ....return(1);..
a1b0: 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54 63  }...tcl_ret = Tc
a1c0: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 74  l_Eval(interp, t
a1d0: 63 6c 29 3b 0a 09 74 63 6c 5f 72 65 73 75 6c 74  cl);..tcl_result
a1e0: 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67   = Tcl_GetString
a1f0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a  Result(interp);.
a200: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
a210: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72   TCL_OK) {...fpr
a220: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 5b 65  intf(stderr, "[e
a230: 72 72 6f 72 5d 20 25 73 5c 6e 22 2c 20 54 63 6c  rror] %s\n", Tcl
a240: 5f 47 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20  _GetVar(interp, 
a250: 22 65 72 72 6f 72 49 6e 66 6f 22 2c 20 54 43 4c  "errorInfo", TCL
a260: 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29 29 3b 0a  _GLOBAL_ONLY));.
a270: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
a280: 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 73 75 6c  ...if (tcl_resul
a290: 74 20 26 26 20 74 63 6c 5f 72 65 73 75 6c 74 5b  t && tcl_result[
a2a0: 30 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09  0] != '\0') {...
a2b0: 70 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 74  printf("%s\n", t
a2c0: 63 6c 5f 72 65 73 75 6c 74 29 3b 0a 09 7d 0a 0a  cl_result);..}..
a2d0: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f  .return(0);.}../
a2e0: 2a 0a 20 2a 20 41 70 70 46 53 64 20 50 61 63 6b  *. * AppFSd Pack
a2f0: 61 67 65 20 66 6f 72 20 54 63 6c 3a 0a 20 2a 20  age for Tcl:. * 
a300: 20 20 20 20 20 20 20 20 42 72 69 64 67 65 20 66          Bridge f
a310: 6f 72 20 49 2f 4f 20 6f 70 65 72 61 74 69 6f 6e  or I/O operation
a320: 73 20 74 6f 20 72 65 71 75 65 73 74 20 69 6e 66  s to request inf
a330: 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 74  ormation about t
a340: 68 65 20 63 75 72 72 65 6e 74 0a 20 2a 20 20 20  he current. *   
a350: 20 20 20 20 20 20 74 72 61 6e 73 61 63 74 69 6f        transactio
a360: 6e 0a 20 2a 2f 0a 2f 2a 0a 20 2a 20 54 63 6c 20  n. */./*. * Tcl 
a370: 69 6e 74 65 72 66 61 63 65 20 74 6f 20 67 65 74  interface to get
a380: 20 74 68 65 20 68 6f 6d 65 20 64 69 72 65 63 74   the home direct
a390: 6f 72 79 20 66 6f 72 20 74 68 65 20 75 73 65 72  ory for the user
a3a0: 20 6d 61 6b 69 6e 67 20 74 68 65 20 22 63 75 72   making the "cur
a3b0: 72 65 6e 74 22 0a 20 2a 20 46 55 53 45 20 49 2f  rent". * FUSE I/
a3c0: 4f 20 72 65 71 75 65 73 74 0a 20 2a 2f 0a 73 74  O request. */.st
a3d0: 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70  atic int tcl_app
a3e0: 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 43  fs_get_homedir(C
a3f0: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63  lientData cd, Tc
a400: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
a410: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f  , int objc, Tcl_
a420: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
a430: 5d 29 20 7b 0a 09 63 68 61 72 20 2a 68 6f 6d 65  ]) {..char *home
a440: 64 69 72 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 68  dir;..Tcl_Obj *h
a450: 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 75 69 64  omedir_obj;..uid
a460: 5f 74 20 66 73 75 69 64 3b 0a 09 73 74 61 74 69  _t fsuid;..stati
a470: 63 20 5f 5f 74 68 72 65 61 64 20 54 63 6c 5f 4f  c __thread Tcl_O
a480: 62 6a 20 2a 6c 61 73 74 5f 68 6f 6d 65 64 69 72  bj *last_homedir
a490: 5f 6f 62 6a 20 3d 20 4e 55 4c 4c 3b 0a 09 73 74  _obj = NULL;..st
a4a0: 61 74 69 63 20 5f 5f 74 68 72 65 61 64 20 75 69  atic __thread ui
a4b0: 64 5f 74 20 6c 61 73 74 5f 66 73 75 69 64 20 3d  d_t last_fsuid =
a4c0: 20 2d 31 3b 0a 0a 20 20 20 20 20 20 20 20 69 66   -1;..        if
a4d0: 20 28 6f 62 6a 63 20 21 3d 20 31 29 20 7b 0a 20   (objc != 1) {. 
a4e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54                 T
a4f0: 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28  cl_WrongNumArgs(
a500: 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c  interp, 1, objv,
a510: 20 4e 55 4c 4c 29 3b 0a 20 20 20 20 20 20 20 20   NULL);.        
a520: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 28 54          return(T
a530: 43 4c 5f 45 52 52 4f 52 29 3b 0a 20 20 20 20 20  CL_ERROR);.     
a540: 20 20 20 7d 0a 0a 09 66 73 75 69 64 20 3d 20 61     }...fsuid = a
a550: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
a560: 3b 0a 0a 09 69 66 20 28 66 73 75 69 64 20 3d 3d  ;...if (fsuid ==
a570: 20 6c 61 73 74 5f 66 73 75 69 64 20 26 26 20 6c   last_fsuid && l
a580: 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20  ast_homedir_obj 
a590: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 6f 6d  != NULL) {...hom
a5a0: 65 64 69 72 5f 6f 62 6a 20 3d 20 6c 61 73 74 5f  edir_obj = last_
a5b0: 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 0a 09 09  homedir_obj;....
a5c0: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74  Tcl_IncrRefCount
a5d0: 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09  (homedir_obj);..
a5e0: 7d 20 65 6c 73 65 20 7b 0a 09 09 68 6f 6d 65 64  } else {...homed
a5f0: 69 72 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 68  ir = appfs_get_h
a600: 6f 6d 65 64 69 72 28 61 70 70 66 73 5f 67 65 74  omedir(appfs_get
a610: 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 09 69 66  _fsuid());....if
a620: 20 28 68 6f 6d 65 64 69 72 20 3d 3d 20 4e 55 4c   (homedir == NUL
a630: 4c 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 54  L) {....return(T
a640: 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 09 7d 0a 0a  CL_ERROR);...}..
a650: 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20  ..homedir_obj = 
a660: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
a670: 28 68 6f 6d 65 64 69 72 2c 20 2d 31 29 3b 0a 0a  (homedir, -1);..
a680: 09 09 66 72 65 65 28 68 6f 6d 65 64 69 72 29 3b  ..free(homedir);
a690: 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43  ....Tcl_IncrRefC
a6a0: 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a  ount(homedir_obj
a6b0: 29 3b 0a 0a 09 09 69 66 20 28 6c 61 73 74 5f 68  );....if (last_h
a6c0: 6f 6d 65 64 69 72 5f 6f 62 6a 20 21 3d 20 4e 55  omedir_obj != NU
a6d0: 4c 4c 29 20 7b 0a 09 09 09 54 63 6c 5f 44 65 63  LL) {....Tcl_Dec
a6e0: 72 52 65 66 43 6f 75 6e 74 28 6c 61 73 74 5f 68  rRefCount(last_h
a6f0: 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 09 7d  omedir_obj);...}
a700: 0a 0a 09 09 6c 61 73 74 5f 68 6f 6d 65 64 69 72  ....last_homedir
a710: 5f 6f 62 6a 20 3d 20 68 6f 6d 65 64 69 72 5f 6f  _obj = homedir_o
a720: 62 6a 3b 0a 09 09 6c 61 73 74 5f 66 73 75 69 64  bj;...last_fsuid
a730: 20 3d 20 66 73 75 69 64 3b 0a 0a 09 09 54 63 6c   = fsuid;....Tcl
a740: 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 68 6f  _IncrRefCount(ho
a750: 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 7d 0a 0a  medir_obj);..}..
a760: 20 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74 4f         .Tcl_SetO
a770: 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  bjResult(interp,
a780: 20 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 0a   homedir_obj);..
a790: 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e  .Tcl_DecrRefCoun
a7a0: 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a  t(homedir_obj);.
a7b0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 28  .        return(
a7c0: 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74  TCL_OK);.}..stat
a7d0: 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73  ic int tcl_appfs
a7e0: 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  _simulate_user_f
a7f0: 73 5f 65 6e 74 65 72 28 43 6c 69 65 6e 74 44 61  s_enter(ClientDa
a800: 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72  ta cd, Tcl_Inter
a810: 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f  p *interp, int o
a820: 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f  bjc, Tcl_Obj *CO
a830: 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61  NST objv[]) {..a
a840: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
a850: 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a  er_fs_enter();..
a860: 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b  .return(TCL_OK);
a870: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
a880: 63 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  cl_appfs_simulat
a890: 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28  e_user_fs_leave(
a8a0: 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54  ClientData cd, T
a8b0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
a8c0: 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c  p, int objc, Tcl
a8d0: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
a8e0: 5b 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d  []) {..appfs_sim
a8f0: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65  ulate_user_fs_le
a900: 61 76 65 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28  ave();...return(
a910: 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74  TCL_OK);.}..stat
a920: 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73  ic int tcl_appfs
a930: 5f 67 65 74 5f 66 73 75 69 64 28 43 6c 69 65 6e  _get_fsuid(Clien
a940: 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e  tData cd, Tcl_In
a950: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e  terp *interp, in
a960: 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20  t objc, Tcl_Obj 
a970: 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b  *CONST objv[]) {
a980: 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a 0a  ..uid_t fsuid;..
a990: 09 66 73 75 69 64 20 3d 20 61 70 70 66 73 5f 67  .fsuid = appfs_g
a9a0: 65 74 5f 66 73 75 69 64 28 29 3b 0a 0a 20 20 20  et_fsuid();..   
a9b0: 20 20 20 20 09 54 63 6c 5f 53 65 74 4f 62 6a 52      .Tcl_SetObjR
a9c0: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63  esult(interp, Tc
a9d0: 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28  l_NewWideIntObj(
a9e0: 66 73 75 69 64 29 29 3b 0a 0a 09 72 65 74 75 72  fsuid));...retur
a9f0: 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74  n(TCL_OK);.}..st
aa00: 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70  atic int tcl_app
aa10: 66 73 5f 67 65 74 5f 66 73 67 69 64 28 43 6c 69  fs_get_fsgid(Cli
aa20: 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f  entData cd, Tcl_
aa30: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20  Interp *interp, 
aa40: 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62  int objc, Tcl_Ob
aa50: 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29  j *CONST objv[])
aa60: 20 7b 0a 09 67 69 64 5f 74 20 66 73 67 69 64 3b   {..gid_t fsgid;
aa70: 0a 0a 09 66 73 67 69 64 20 3d 20 61 70 70 66 73  ...fsgid = appfs
aa80: 5f 67 65 74 5f 66 73 67 69 64 28 29 3b 0a 0a 20  _get_fsgid();.. 
aa90: 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74 4f 62        .Tcl_SetOb
aaa0: 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  jResult(interp, 
aab0: 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62  Tcl_NewWideIntOb
aac0: 6a 28 66 73 67 69 64 29 29 3b 0a 0a 09 72 65 74  j(fsgid));...ret
aad0: 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a  urn(TCL_OK);.}..
aae0: 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61  static int tcl_a
aaf0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
ab00: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 43  fo_cache_flush(C
ab10: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63  lientData cd, Tc
ab20: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
ab30: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f  , int objc, Tcl_
ab40: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
ab50: 5d 29 20 7b 0a 09 69 6e 74 20 74 63 6c 5f 72 65  ]) {..int tcl_re
ab60: 74 3b 0a 09 69 6e 74 20 6e 65 77 5f 73 69 7a 65  t;..int new_size
ab70: 3b 0a 0a 09 6e 65 77 5f 73 69 7a 65 20 3d 20 2d  ;...new_size = -
ab80: 31 3b 0a 0a 09 69 66 20 28 6f 62 6a 63 20 3d 3d  1;...if (objc ==
ab90: 20 32 29 20 7b 0a 09 09 74 63 6c 5f 72 65 74 20   2) {...tcl_ret 
aba0: 3d 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d  = Tcl_GetIntFrom
abb0: 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76  Obj(interp, objv
abc0: 5b 31 5d 2c 20 26 6e 65 77 5f 73 69 7a 65 29 3b  [1], &new_size);
abd0: 0a 09 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  ...if (tcl_ret !
abe0: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 72  = TCL_OK) {....r
abf0: 65 74 75 72 6e 28 74 63 6c 5f 72 65 74 29 3b 0a  eturn(tcl_ret);.
ac00: 09 09 7d 0a 09 7d 20 65 6c 73 65 20 69 66 20 28  ..}..} else if (
ac10: 6f 62 6a 63 20 3e 20 32 20 7c 7c 20 6f 62 6a 63  objc > 2 || objc
ac20: 20 3c 20 31 29 20 7b 0a 20 20 20 20 20 20 20 20   < 1) {.        
ac30: 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e          Tcl_Wron
ac40: 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c  gNumArgs(interp,
ac50: 20 31 2c 20 6f 62 6a 76 2c 20 22 3f 6e 65 77 5f   1, objv, "?new_
ac60: 63 61 63 68 65 5f 73 69 7a 65 3f 22 29 3b 0a 09  cache_size?");..
ac70: 09 72 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f  .return(TCL_ERRO
ac80: 52 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67  R);..}...appfs_g
ac90: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
aca0: 68 65 5f 66 6c 75 73 68 28 2d 31 2c 20 6e 65 77  he_flush(-1, new
acb0: 5f 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72 6e  _size);...return
acc0: 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61  (TCL_OK);.}..sta
acd0: 74 69 63 20 69 6e 74 20 41 70 70 66 73 64 5f 49  tic int Appfsd_I
ace0: 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a  nit(Tcl_Interp *
acf0: 69 6e 74 65 72 70 29 20 7b 0a 23 69 66 64 65 66  interp) {.#ifdef
ad00: 20 55 53 45 5f 54 43 4c 5f 53 54 55 42 53 0a 09   USE_TCL_STUBS..
ad10: 69 66 20 28 54 63 6c 5f 49 6e 69 74 53 74 75 62  if (Tcl_InitStub
ad20: 73 28 69 6e 74 65 72 70 2c 20 54 43 4c 5f 56 45  s(interp, TCL_VE
ad30: 52 53 49 4f 4e 2c 20 30 29 20 3d 3d 20 30 4c 29  RSION, 0) == 0L)
ad40: 20 7b 0a 09 09 72 65 74 75 72 6e 28 54 43 4c 5f   {...return(TCL_
ad50: 45 52 52 4f 52 29 3b 0a 09 7d 0a 23 65 6e 64 69  ERROR);..}.#endi
ad60: 66 0a 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62  f...Tcl_CreateOb
ad70: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  jCommand(interp,
ad80: 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 68 6f   "appfsd::get_ho
ad90: 6d 65 64 69 72 22 2c 20 74 63 6c 5f 61 70 70 66  medir", tcl_appf
ada0: 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 2c 20 4e  s_get_homedir, N
adb0: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c  ULL, NULL);..Tcl
adc0: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e  _CreateObjComman
add0: 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73  d(interp, "appfs
ade0: 64 3a 3a 67 65 74 5f 66 73 75 69 64 22 2c 20 74  d::get_fsuid", t
adf0: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75  cl_appfs_get_fsu
ae00: 69 64 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b  id, NULL, NULL);
ae10: 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43  ..Tcl_CreateObjC
ae20: 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22  ommand(interp, "
ae30: 61 70 70 66 73 64 3a 3a 67 65 74 5f 66 73 67 69  appfsd::get_fsgi
ae40: 64 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67 65  d", tcl_appfs_ge
ae50: 74 5f 66 73 67 69 64 2c 20 4e 55 4c 4c 2c 20 4e  t_fsgid, NULL, N
ae60: 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74  ULL);..Tcl_Creat
ae70: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
ae80: 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 73 69 6d  rp, "appfsd::sim
ae90: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
aea0: 74 65 72 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f  ter", tcl_appfs_
aeb0: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
aec0: 5f 65 6e 74 65 72 2c 20 4e 55 4c 4c 2c 20 4e 55  _enter, NULL, NU
aed0: 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65  LL);..Tcl_Create
aee0: 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72  ObjCommand(inter
aef0: 70 2c 20 22 61 70 70 66 73 64 3a 3a 73 69 6d 75  p, "appfsd::simu
af00: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
af10: 76 65 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 73  ve", tcl_appfs_s
af20: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
af30: 6c 65 61 76 65 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  leave, NULL, NUL
af40: 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f  L);..Tcl_CreateO
af50: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
af60: 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 70  , "appfsd::get_p
af70: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66  ath_info_cache_f
af80: 6c 75 73 68 22 2c 20 74 63 6c 5f 61 70 70 66 73  lush", tcl_appfs
af90: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
afa0: 61 63 68 65 5f 66 6c 75 73 68 2c 20 4e 55 4c 4c  ache_flush, NULL
afb0: 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 54 63 6c 5f 50  , NULL);...Tcl_P
afc0: 6b 67 50 72 6f 76 69 64 65 28 69 6e 74 65 72 70  kgProvide(interp
afd0: 2c 20 22 61 70 70 66 73 64 22 2c 20 22 31 2e 30  , "appfsd", "1.0
afe0: 22 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c  ");...return(TCL
aff0: 5f 4f 4b 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 48  _OK);.}../*. * H
b000: 6f 74 2d 72 65 73 74 61 72 74 20 73 75 70 70 6f  ot-restart suppo
b010: 72 74 0a 20 2a 2f 0a 2f 2a 20 49 6e 69 74 69 61  rt. */./* Initia
b020: 74 65 20 61 20 68 6f 74 2d 72 65 73 74 61 72 74  te a hot-restart
b030: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
b040: 61 70 70 66 73 5f 68 6f 74 5f 72 65 73 74 61 72  appfs_hot_restar
b050: 74 28 76 6f 69 64 29 20 7b 0a 09 41 50 50 46 53  t(void) {..APPFS
b060: 5f 44 45 42 55 47 28 22 41 73 6b 65 64 20 74 6f  _DEBUG("Asked to
b070: 20 69 6e 69 74 69 61 74 65 20 68 6f 74 20 72 65   initiate hot re
b080: 73 74 61 72 74 22 29 3b 0a 0a 09 61 70 70 66 73  start");...appfs
b090: 5f 74 63 6c 5f 52 65 73 65 74 49 6e 74 65 72 70  _tcl_ResetInterp
b0a0: 73 28 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74  s();...appfs_get
b0b0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
b0c0: 5f 66 6c 75 73 68 28 2d 31 2c 20 2d 31 29 3b 0a  _flush(-1, -1);.
b0d0: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a  ..return;.}../*.
b0e0: 20 2a 20 53 69 67 6e 61 6c 20 68 61 6e 64 6c 65   * Signal handle
b0f0: 72 0a 20 2a 20 20 20 20 20 20 20 20 20 53 49 47  r. *         SIG
b100: 48 55 50 20 69 6e 69 74 69 61 74 65 73 20 61 20  HUP initiates a 
b110: 68 6f 74 20 72 65 73 74 61 72 74 0a 20 2a 2f 0a  hot restart. */.
b120: 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66  static void appf
b130: 73 5f 73 69 67 6e 61 6c 5f 68 61 6e 64 6c 65 72  s_signal_handler
b140: 28 69 6e 74 20 73 69 67 29 20 7b 0a 09 2f 2a 20  (int sig) {../* 
b150: 44 6f 20 6e 6f 74 20 68 61 6e 64 6c 65 20 73 69  Do not handle si
b160: 67 6e 61 6c 73 20 75 6e 74 69 6c 20 46 55 53 45  gnals until FUSE
b170: 20 68 61 73 20 62 65 65 6e 20 73 74 61 72 74 65   has been starte
b180: 64 20 2a 2f 0a 09 69 66 20 28 21 61 70 70 66 73  d */..if (!appfs
b190: 5f 66 75 73 65 5f 73 74 61 72 74 65 64 29 20 7b  _fuse_started) {
b1a0: 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09  ...return;..}...
b1b0: 2f 2a 20 52 65 71 75 65 73 74 20 74 6f 20 70 65  /* Request to pe
b1c0: 72 66 6f 72 6d 20 61 20 22 68 6f 74 22 20 72 65  rform a "hot" re
b1d0: 73 74 61 72 74 20 2a 2f 0a 09 69 66 20 28 73 69  start */..if (si
b1e0: 67 20 3d 3d 20 53 49 47 48 55 50 29 20 7b 0a 09  g == SIGHUP) {..
b1f0: 09 61 70 70 66 73 5f 68 6f 74 5f 72 65 73 74 61  .appfs_hot_resta
b200: 72 74 28 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  rt();..}...retur
b210: 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 65 72 6d  n;.}../*. * Term
b220: 69 6e 61 74 65 20 61 20 74 68 72 65 61 64 0a 20  inate a thread. 
b230: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  */.static void a
b240: 70 70 66 73 5f 74 65 72 6d 69 6e 61 74 65 5f 69  ppfs_terminate_i
b250: 6e 74 65 72 70 5f 61 6e 64 5f 74 68 72 65 61 64  nterp_and_thread
b260: 28 76 6f 69 64 20 2a 5f 69 6e 74 65 72 70 29 20  (void *_interp) 
b270: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
b280: 6e 74 65 72 70 3b 0a 0a 09 41 50 50 46 53 5f 44  nterp;...APPFS_D
b290: 45 42 55 47 28 22 43 61 6c 6c 65 64 3a 20 5f 69  EBUG("Called: _i
b2a0: 6e 74 65 72 70 20 3d 20 25 70 22 2c 20 5f 69 6e  nterp = %p", _in
b2b0: 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 5f 69 6e  terp);...if (_in
b2c0: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
b2d0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
b2e0: 65 72 6d 69 6e 61 74 69 6e 67 20 74 68 72 65 61  erminating threa
b2f0: 64 20 77 69 74 68 20 6e 6f 20 69 6e 74 65 72 70  d with no interp
b300: 72 65 74 65 72 22 29 3b 0a 0a 09 09 72 65 74 75  reter");....retu
b310: 72 6e 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72 70 20  rn;..}...interp 
b320: 3d 20 5f 69 6e 74 65 72 70 3b 0a 0a 09 41 50 50  = _interp;...APP
b330: 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e  FS_DEBUG("Termin
b340: 61 74 69 6e 67 20 69 6e 74 65 72 70 72 65 74 65  ating interprete
b350: 72 20 64 75 65 20 74 6f 20 74 68 72 65 61 64 20  r due to thread 
b360: 74 65 72 6d 69 6e 61 74 69 6f 6e 22 29 3b 0a 0a  termination");..
b370: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
b380: 63 6c 28 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65  cl(...Tcl_Delete
b390: 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a  Interp(interp);.
b3a0: 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .)...appfs_call_
b3b0: 6c 69 62 74 63 6c 28 0a 09 09 54 63 6c 5f 46 69  libtcl(...Tcl_Fi
b3c0: 6e 61 6c 69 7a 65 54 68 72 65 61 64 28 29 3b 0a  nalizeThread();.
b3d0: 09 29 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a  .)...return;.}..
b3e0: 2f 2a 0a 20 2a 20 43 6f 6d 6d 61 6e 64 2d 6c 69  /*. * Command-li
b3f0: 6e 65 20 70 61 72 73 69 6e 67 20 74 6f 6f 6c 73  ne parsing tools
b400: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  . */.static void
b410: 20 61 70 70 66 73 5f 70 72 69 6e 74 5f 68 65 6c   appfs_print_hel
b420: 70 28 46 49 4c 45 20 2a 63 68 61 6e 6e 65 6c 29  p(FILE *channel)
b430: 20 7b 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e   {..fprintf(chan
b440: 6e 65 6c 2c 20 22 55 73 61 67 65 3a 20 7b 61 70  nel, "Usage: {ap
b450: 70 66 73 64 7c 6d 6f 75 6e 74 2e 61 70 70 66 73  pfsd|mount.appfs
b460: 7d 20 5b 2d 6f 20 3c 6f 70 74 69 6f 6e 3e 5d 20  } [-o <option>] 
b470: 5b 2d 64 66 73 68 5d 20 3c 63 61 63 68 65 64 69  [-dfsh] <cachedi
b480: 72 3e 20 3c 6d 6f 75 6e 74 70 6f 69 6e 74 3e 5c  r> <mountpoint>\
b490: 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68  n");..fprintf(ch
b4a0: 61 6e 6e 65 6c 2c 20 22 5c 6e 22 29 3b 0a 09 66  annel, "\n");..f
b4b0: 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20  printf(channel, 
b4c0: 22 4f 70 74 69 6f 6e 73 3a 5c 6e 22 29 3b 0a 09  "Options:\n");..
b4d0: 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c  fprintf(channel,
b4e0: 20 22 20 20 2d 64 20 20 20 20 20 20 20 20 20 20   "  -d          
b4f0: 20 20 20 20 45 6e 61 62 6c 65 20 46 55 53 45 20      Enable FUSE 
b500: 64 65 62 75 67 20 6d 6f 64 65 2e 5c 6e 22 29 3b  debug mode.\n");
b510: 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65  ..fprintf(channe
b520: 6c 2c 20 22 20 20 2d 66 20 20 20 20 20 20 20 20  l, "  -f        
b530: 20 20 20 20 20 20 52 75 6e 20 69 6e 20 66 6f 72        Run in for
b540: 65 67 72 6f 75 6e 64 2e 5c 6e 22 29 3b 0a 09 66  eground.\n");..f
b550: 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20  printf(channel, 
b560: 22 20 20 2d 73 20 20 20 20 20 20 20 20 20 20 20  "  -s           
b570: 20 20 20 45 6e 61 62 6c 65 20 73 69 6e 67 6c 65     Enable single
b580: 20 74 68 72 65 61 64 65 64 20 6d 6f 64 65 2e 5c   threaded mode.\
b590: 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68  n");..fprintf(ch
b5a0: 61 6e 6e 65 6c 2c 20 22 20 20 2d 68 20 20 20 20  annel, "  -h    
b5b0: 20 20 20 20 20 20 20 20 20 20 47 69 76 65 20 74            Give t
b5c0: 68 69 73 20 68 65 6c 70 2e 5c 6e 22 29 3b 0a 09  his help.\n");..
b5d0: 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c  fprintf(channel,
b5e0: 20 22 20 20 2d 6f 20 6e 6f 74 68 72 65 61 64 73   "  -o nothreads
b5f0: 20 20 20 20 45 6e 61 62 6c 65 20 73 69 6e 67 6c      Enable singl
b600: 65 20 74 68 72 65 61 64 65 64 20 6d 6f 64 65 2e  e threaded mode.
b610: 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63  \n");..fprintf(c
b620: 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 6f 20 61 6c  hannel, "  -o al
b630: 6c 6f 77 5f 6f 74 68 65 72 20 20 41 6c 6c 6f 77  low_other  Allow
b640: 20 6f 74 68 65 72 20 75 73 65 72 73 20 74 6f 20   other users to 
b650: 61 63 63 65 73 73 20 74 68 69 73 20 6d 6f 75 6e  access this moun
b660: 74 70 6f 69 6e 74 20 28 64 65 66 61 75 6c 74 5c  tpoint (default\
b670: 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68  n");..fprintf(ch
b680: 61 6e 6e 65 6c 2c 20 22 20 20 20 20 20 20 20 20  annel, "        
b690: 20 20 20 20 20 20 20 20 20 20 69 66 20 72 6f 6f            if roo
b6a0: 74 29 2e 5c 6e 22 29 3b 0a 0a 09 72 65 74 75 72  t).\n");...retur
b6b0: 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  n;.}..static int
b6c0: 20 61 70 70 66 73 5f 6f 70 74 5f 70 61 72 73 65   appfs_opt_parse
b6d0: 28 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20  (int argc, char 
b6e0: 2a 2a 61 72 67 76 2c 20 20 73 74 72 75 63 74 20  **argv,  struct 
b6f0: 66 75 73 65 5f 61 72 67 73 20 2a 61 72 67 73 29  fuse_args *args)
b700: 20 7b 0a 09 69 6e 74 20 63 68 3b 0a 09 63 68 61   {..int ch;..cha
b710: 72 20 2a 6f 70 74 73 74 72 2c 20 2a 6f 70 74 73  r *optstr, *opts
b720: 74 72 5f 6e 65 78 74 2c 20 2a 6f 70 74 73 74 72  tr_next, *optstr
b730: 5f 73 3b 0a 09 63 68 61 72 20 66 61 6b 65 5f 61  _s;..char fake_a
b740: 72 67 5b 33 5d 20 3d 20 7b 27 2d 27 2c 20 30 2c  rg[3] = {'-', 0,
b750: 20 30 7d 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 44 65   0};.../*.. * De
b760: 66 61 75 6c 74 20 76 61 6c 75 65 73 0a 09 20 2a  fault values.. *
b770: 2f 0a 23 69 66 64 65 66 20 54 43 4c 5f 54 48 52  /.#ifdef TCL_THR
b780: 45 41 44 53 0a 09 61 70 70 66 73 5f 74 68 72 65  EADS..appfs_thre
b790: 61 64 65 64 5f 74 63 6c 20 3d 20 31 3b 0a 23 65  aded_tcl = 1;.#e
b7a0: 6c 73 65 0a 09 61 70 70 66 73 5f 74 68 72 65 61  lse..appfs_threa
b7b0: 64 65 64 5f 74 63 6c 20 3d 20 30 3b 0a 23 65 6e  ded_tcl = 0;.#en
b7c0: 64 69 66 0a 0a 09 2f 2a 2a 0a 09 20 2a 2a 20 41  dif.../**.. ** A
b7d0: 64 64 20 46 55 53 45 20 61 72 67 75 6d 65 6e 74  dd FUSE argument
b7e0: 73 20 77 68 69 63 68 20 77 65 20 61 6c 77 61 79  s which we alway
b7f0: 73 20 73 75 70 70 6c 79 0a 09 20 2a 2a 2f 0a 09  s supply.. **/..
b800: 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67  fuse_opt_add_arg
b810: 28 61 72 67 73 2c 20 22 2d 6f 64 65 66 61 75 6c  (args, "-odefaul
b820: 74 5f 70 65 72 6d 69 73 73 69 6f 6e 73 2c 66 73  t_permissions,fs
b830: 6e 61 6d 65 3d 61 70 70 66 73 2c 73 75 62 74 79  name=appfs,subty
b840: 70 65 3d 61 70 70 66 73 64 2c 75 73 65 5f 69 6e  pe=appfsd,use_in
b850: 6f 2c 65 6e 74 72 79 5f 74 69 6d 65 6f 75 74 3d  o,entry_timeout=
b860: 30 2c 61 74 74 72 5f 74 69 6d 65 6f 75 74 3d 30  0,attr_timeout=0
b870: 2c 62 69 67 5f 77 72 69 74 65 73 2c 69 6e 74 72  ,big_writes,intr
b880: 2c 68 61 72 64 5f 72 65 6d 6f 76 65 22 29 3b 0a  ,hard_remove");.
b890: 0a 09 69 66 20 28 67 65 74 75 69 64 28 29 20 3d  ..if (getuid() =
b8a0: 3d 20 30 29 20 7b 0a 09 09 66 75 73 65 5f 6f 70  = 0) {...fuse_op
b8b0: 74 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55  t_parse(args, NU
b8c0: 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b  LL, NULL, NULL);
b8d0: 0a 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f  ...fuse_opt_add_
b8e0: 61 72 67 28 61 72 67 73 2c 20 22 2d 6f 61 6c 6c  arg(args, "-oall
b8f0: 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 0a 09 09 2f  ow_other");..../
b900: 2a 0a 09 09 20 2a 20 54 68 69 73 20 73 68 6f 75  *... * This shou
b910: 6c 64 20 67 65 6e 65 72 61 6c 6c 79 20 62 65 20  ld generally be 
b920: 61 76 6f 69 64 65 64 2c 20 62 75 74 20 69 66 20  avoided, but if 
b930: 74 68 65 72 65 20 61 72 65 20 73 65 63 75 72 69  there are securi
b940: 74 79 0a 09 09 20 2a 20 63 6f 6e 63 65 72 6e 73  ty... * concerns
b950: 20 73 75 69 64 20 63 61 6e 20 62 65 20 64 69 73   suid can be dis
b960: 61 62 6c 65 64 20 63 6f 6d 70 6c 65 74 65 6c 79  abled completely
b970: 20 6f 6e 20 74 68 65 20 63 6f 6d 6d 61 6e 64 6c   on the commandl
b980: 69 6e 65 0a 09 09 20 2a 2f 0a 09 09 66 75 73 65  ine... */...fuse
b990: 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67 73 2c  _opt_parse(args,
b9a0: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c   NULL, NULL, NUL
b9b0: 4c 29 3b 0a 09 09 66 75 73 65 5f 6f 70 74 5f 61  L);...fuse_opt_a
b9c0: 64 64 5f 61 72 67 28 61 72 67 73 2c 20 22 2d 6f  dd_arg(args, "-o
b9d0: 73 75 69 64 22 29 3b 0a 09 7d 0a 0a 09 77 68 69  suid");..}...whi
b9e0: 6c 65 20 28 28 63 68 20 3d 20 67 65 74 6f 70 74  le ((ch = getopt
b9f0: 28 61 72 67 63 2c 20 61 72 67 76 2c 20 22 64 66  (argc, argv, "df
ba00: 73 68 76 6f 3a 22 29 29 20 21 3d 20 2d 31 29 20  shvo:")) != -1) 
ba10: 7b 0a 09 09 73 77 69 74 63 68 20 28 63 68 29 20  {...switch (ch) 
ba20: 7b 0a 09 09 09 63 61 73 65 20 27 76 27 3a 0a 09  {....case 'v':..
ba30: 09 09 09 2f 2a 20 49 67 6e 6f 72 65 64 20 2a 2f  .../* Ignored */
ba40: 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63  .....break;....c
ba50: 61 73 65 20 27 6f 27 3a 0a 09 09 09 09 6f 70 74  ase 'o':.....opt
ba60: 73 74 72 5f 6e 65 78 74 20 3d 20 6f 70 74 73 74  str_next = optst
ba70: 72 20 3d 20 6f 70 74 73 74 72 5f 73 20 3d 20 73  r = optstr_s = s
ba80: 74 72 64 75 70 28 6f 70 74 61 72 67 29 3b 0a 0a  trdup(optarg);..
ba90: 09 09 09 09 77 68 69 6c 65 20 28 31 29 20 7b 0a  ....while (1) {.
baa0: 09 09 09 09 09 6f 70 74 73 74 72 20 3d 20 6f 70  .....optstr = op
bab0: 74 73 74 72 5f 6e 65 78 74 3b 0a 0a 09 09 09 09  tstr_next;......
bac0: 09 69 66 20 28 21 6f 70 74 73 74 72 29 20 7b 0a  .if (!optstr) {.
bad0: 09 09 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09  ......break;....
bae0: 09 09 7d 0a 0a 09 09 09 09 09 6f 70 74 73 74 72  ..}.......optstr
baf0: 5f 6e 65 78 74 20 3d 20 73 74 72 63 68 72 28 6f  _next = strchr(o
bb00: 70 74 73 74 72 2c 20 27 2c 27 29 3b 0a 09 09 09  ptstr, ',');....
bb10: 09 09 69 66 20 28 6f 70 74 73 74 72 5f 6e 65 78  ..if (optstr_nex
bb20: 74 29 20 7b 0a 09 09 09 09 09 09 2a 6f 70 74 73  t) {.......*opts
bb30: 74 72 5f 6e 65 78 74 20 3d 20 27 5c 30 27 3b 0a  tr_next = '\0';.
bb40: 09 09 09 09 09 09 6f 70 74 73 74 72 5f 6e 65 78  ......optstr_nex
bb50: 74 2b 2b 3b 0a 09 09 09 09 09 7d 0a 0a 09 09 09  t++;......}.....
bb60: 09 09 69 66 20 28 73 74 72 63 6d 70 28 6f 70 74  ..if (strcmp(opt
bb70: 73 74 72 2c 20 22 6e 6f 74 68 72 65 61 64 73 22  str, "nothreads"
bb80: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09 09  ) == 0) {.......
bb90: 41 50 50 46 53 5f 44 45 42 55 47 28 22 50 61 73  APPFS_DEBUG("Pas
bba0: 73 69 6e 67 20 6f 70 74 69 6f 6e 20 74 6f 20 46  sing option to F
bbb0: 55 53 45 3a 20 2d 73 22 29 3b 0a 0a 09 09 09 09  USE: -s");......
bbc0: 09 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65  ..fuse_opt_parse
bbd0: 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  (args, NULL, NUL
bbe0: 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09 09 09 09 09  L, NULL);.......
bbf0: 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67  fuse_opt_add_arg
bc00: 28 61 72 67 73 2c 20 22 2d 73 22 29 3b 0a 0a 09  (args, "-s");...
bc10: 09 09 09 09 09 61 70 70 66 73 5f 74 68 72 65 61  .....appfs_threa
bc20: 64 65 64 5f 74 63 6c 20 3d 20 30 3b 0a 09 09 09  ded_tcl = 0;....
bc30: 09 09 7d 20 65 6c 73 65 20 69 66 20 28 73 74 72  ..} else if (str
bc40: 63 6d 70 28 6f 70 74 73 74 72 2c 20 22 61 6c 6c  cmp(optstr, "all
bc50: 6f 77 5f 6f 74 68 65 72 22 29 20 3d 3d 20 30 29  ow_other") == 0)
bc60: 20 7b 0a 09 09 09 09 09 09 41 50 50 46 53 5f 44   {.......APPFS_D
bc70: 45 42 55 47 28 22 50 61 73 73 69 6e 67 20 6f 70  EBUG("Passing op
bc80: 74 69 6f 6e 20 74 6f 20 46 55 53 45 3a 20 2d 6f  tion to FUSE: -o
bc90: 20 61 6c 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a   allow_other");.
bca0: 0a 09 09 09 09 09 09 66 75 73 65 5f 6f 70 74 5f  .......fuse_opt_
bcb0: 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c  parse(args, NULL
bcc0: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09  , NULL, NULL);..
bcd0: 09 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 61 64  .....fuse_opt_ad
bce0: 64 5f 61 72 67 28 61 72 67 73 2c 20 22 2d 6f 61  d_arg(args, "-oa
bcf0: 6c 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 09 09  llow_other");...
bd00: 09 09 09 7d 20 65 6c 73 65 20 69 66 20 28 73 74  ...} else if (st
bd10: 72 63 6d 70 28 6f 70 74 73 74 72 2c 20 22 72 77  rcmp(optstr, "rw
bd20: 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09  ") == 0) {......
bd30: 09 2f 2a 20 49 67 6e 6f 72 65 64 20 2a 2f 0a 09  ./* Ignored */..
bd40: 09 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09  ....} else {....
bd50: 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
bd60: 72 2c 20 22 61 70 70 66 73 64 3a 20 69 6e 76 61  r, "appfsd: inva
bd70: 6c 69 64 20 6f 70 74 69 6f 6e 3a 20 5c 22 2d 6f  lid option: \"-o
bd80: 20 25 73 5c 22 5c 6e 22 2c 20 6f 70 74 73 74 72   %s\"\n", optstr
bd90: 29 3b 0a 0a 09 09 09 09 09 09 66 72 65 65 28 6f  );........free(o
bda0: 70 74 73 74 72 5f 73 29 3b 0a 0a 09 09 09 09 09  ptstr_s);.......
bdb0: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 09 09 09  .return(1);.....
bdc0: 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66 72  .}.....}......fr
bdd0: 65 65 28 6f 70 74 73 74 72 5f 73 29 3b 0a 0a 09  ee(optstr_s);...
bde0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73  ...break;....cas
bdf0: 65 20 27 64 27 3a 0a 09 09 09 63 61 73 65 20 27  e 'd':....case '
be00: 66 27 3a 0a 09 09 09 63 61 73 65 20 27 73 27 3a  f':....case 's':
be10: 0a 09 09 09 09 69 66 20 28 63 68 20 3d 3d 20 27  .....if (ch == '
be20: 73 27 29 20 7b 0a 09 09 09 09 09 61 70 70 66 73  s') {......appfs
be30: 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 20 3d 20  _threaded_tcl = 
be40: 30 3b 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66 61  0;.....}......fa
be50: 6b 65 5f 61 72 67 5b 31 5d 20 3d 20 63 68 3b 0a  ke_arg[1] = ch;.
be60: 0a 09 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  .....APPFS_DEBUG
be70: 28 22 50 61 73 73 69 6e 67 20 6f 70 74 69 6f 6e  ("Passing option
be80: 20 74 6f 20 46 55 53 45 3a 20 25 73 22 2c 20 66   to FUSE: %s", f
be90: 61 6b 65 5f 61 72 67 29 3b 0a 0a 09 09 09 09 66  ake_arg);......f
bea0: 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72  use_opt_parse(ar
beb0: 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20  gs, NULL, NULL, 
bec0: 4e 55 4c 4c 29 3b 0a 09 09 09 09 66 75 73 65 5f  NULL);.....fuse_
bed0: 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72 67 73  opt_add_arg(args
bee0: 2c 20 66 61 6b 65 5f 61 72 67 29 3b 0a 09 09 09  , fake_arg);....
bef0: 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20  .break;....case 
bf00: 27 68 27 3a 0a 09 09 09 09 61 70 70 66 73 5f 70  'h':.....appfs_p
bf10: 72 69 6e 74 5f 68 65 6c 70 28 73 74 64 6f 75 74  rint_help(stdout
bf20: 29 3b 0a 0a 09 09 09 09 72 65 74 75 72 6e 28 2d  );......return(-
bf30: 31 29 3b 0a 09 09 09 63 61 73 65 20 27 3a 27 3a  1);....case ':':
bf40: 0a 09 09 09 63 61 73 65 20 27 3f 27 3a 0a 09 09  ....case '?':...
bf50: 09 64 65 66 61 75 6c 74 3a 0a 09 09 09 09 61 70  .default:.....ap
bf60: 70 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28 73  pfs_print_help(s
bf70: 74 64 65 72 72 29 3b 0a 0a 09 09 09 09 72 65 74  tderr);......ret
bf80: 75 72 6e 28 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a  urn(1);...}..}..
bf90: 09 69 66 20 28 28 6f 70 74 69 6e 64 20 2b 20 32  .if ((optind + 2
bfa0: 29 20 21 3d 20 61 72 67 63 29 20 7b 0a 09 09 69  ) != argc) {...i
bfb0: 66 20 28 28 6f 70 74 69 6e 64 20 2b 20 32 29 20  f ((optind + 2) 
bfc0: 3c 20 61 72 67 63 29 20 7b 0a 09 09 09 66 70 72  < argc) {....fpr
bfd0: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54 6f  intf(stderr, "To
bfe0: 6f 20 6d 61 6e 79 20 61 72 67 75 6d 65 6e 74 73  o many arguments
bff0: 5c 6e 22 29 3b 0a 09 09 7d 20 65 6c 73 65 20 7b  \n");...} else {
c000: 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ....fprintf(stde
c010: 72 72 2c 20 22 4d 69 73 73 69 6e 67 20 63 61 63  rr, "Missing cac
c020: 68 65 64 69 72 20 6f 72 20 6d 6f 75 6e 74 70 6f  hedir or mountpo
c030: 69 6e 74 5c 6e 22 29 3b 0a 09 09 7d 0a 0a 09 09  int\n");...}....
c040: 61 70 70 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70  appfs_print_help
c050: 28 73 74 64 65 72 72 29 3b 0a 0a 09 09 72 65 74  (stderr);....ret
c060: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a  urn(1);..}.../*.
c070: 09 20 2a 20 53 65 74 20 63 61 63 68 65 20 64 69  . * Set cache di
c080: 72 20 61 73 20 66 69 72 73 74 20 61 72 67 75 6d  r as first argum
c090: 65 6e 74 20 28 74 68 65 20 22 64 65 76 69 63 65  ent (the "device
c0a0: 22 2c 20 65 73 73 65 6e 74 69 61 6c 6c 79 29 0a  ", essentially).
c0b0: 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68  . */..appfs_cach
c0c0: 65 64 69 72 20 3d 20 61 72 67 76 5b 6f 70 74 69  edir = argv[opti
c0d0: 6e 64 5d 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 50 61  nd];.../*.. * Pa
c0e0: 73 73 20 74 68 65 20 72 65 6d 61 69 6e 69 6e 67  ss the remaining
c0f0: 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 46 55 53   argument to FUS
c100: 45 20 61 73 20 74 68 65 20 64 69 72 65 63 74 6f  E as the directo
c110: 72 79 0a 09 20 2a 2f 0a 09 66 75 73 65 5f 6f 70  ry.. */..fuse_op
c120: 74 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55  t_parse(args, NU
c130: 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b  LL, NULL, NULL);
c140: 0a 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61  ..fuse_opt_add_a
c150: 72 67 28 61 72 67 73 2c 20 61 72 67 76 5b 6f 70  rg(args, argv[op
c160: 74 69 6e 64 20 2b 20 31 5d 29 3b 0a 0a 09 72 65  tind + 1]);...re
c170: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 0a 2f 2a 0a  turn(0);.}.../*.
c180: 20 2a 20 46 55 53 45 20 6f 70 65 72 61 74 69 6f   * FUSE operatio
c190: 6e 73 20 73 74 72 75 63 74 75 72 65 0a 20 2a 2f  ns structure. */
c1a0: 0a 73 74 61 74 69 63 20 73 74 72 75 63 74 20 66  .static struct f
c1b0: 75 73 65 5f 6f 70 65 72 61 74 69 6f 6e 73 20 61  use_operations a
c1c0: 70 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 20  ppfs_operations 
c1d0: 3d 20 7b 0a 09 2e 67 65 74 61 74 74 72 20 20 20  = {...getattr   
c1e0: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74  = appfs_fuse_get
c1f0: 61 74 74 72 2c 0a 09 2e 72 65 61 64 64 69 72 20  attr,...readdir 
c200: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72    = appfs_fuse_r
c210: 65 61 64 64 69 72 2c 0a 09 2e 72 65 61 64 6c 69  eaddir,...readli
c220: 6e 6b 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  nk  = appfs_fuse
c230: 5f 72 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f 70 65  _readlink,...ope
c240: 6e 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66  n      = appfs_f
c250: 75 73 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65 6c 65  use_open,...rele
c260: 61 73 65 20 20 20 3d 20 61 70 70 66 73 5f 66 75  ase   = appfs_fu
c270: 73 65 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65 61 64  se_close,...read
c280: 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75        = appfs_fu
c290: 73 65 5f 72 65 61 64 2c 0a 09 2e 77 72 69 74 65  se_read,...write
c2a0: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
c2b0: 65 5f 77 72 69 74 65 2c 0a 09 2e 6d 6b 6e 6f 64  e_write,...mknod
c2c0: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
c2d0: 65 5f 6d 6b 6e 6f 64 2c 0a 09 2e 63 72 65 61 74  e_mknod,...creat
c2e0: 65 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73  e    = appfs_fus
c2f0: 65 5f 63 72 65 61 74 65 2c 0a 09 2e 74 72 75 6e  e_create,...trun
c300: 63 61 74 65 20 20 3d 20 61 70 70 66 73 5f 66 75  cate  = appfs_fu
c310: 73 65 5f 74 72 75 6e 63 61 74 65 2c 0a 09 2e 75  se_truncate,...u
c320: 6e 6c 69 6e 6b 20 20 20 20 3d 20 61 70 70 66 73  nlink    = appfs
c330: 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64  _fuse_unlink_rmd
c340: 69 72 2c 0a 09 2e 72 6d 64 69 72 20 20 20 20 20  ir,...rmdir     
c350: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c  = appfs_fuse_unl
c360: 69 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 6d 6b 64  ink_rmdir,...mkd
c370: 69 72 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66  ir     = appfs_f
c380: 75 73 65 5f 6d 6b 64 69 72 2c 0a 09 2e 63 68 6d  use_mkdir,...chm
c390: 6f 64 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66  od     = appfs_f
c3a0: 75 73 65 5f 63 68 6d 6f 64 2c 0a 09 2e 73 79 6d  use_chmod,...sym
c3b0: 6c 69 6e 6b 20 20 20 3d 20 61 70 70 66 73 5f 66  link   = appfs_f
c3c0: 75 73 65 5f 73 79 6d 6c 69 6e 6b 2c 0a 7d 3b 0a  use_symlink,.};.
c3d0: 0a 2f 2a 0a 20 2a 20 45 6e 74 72 79 20 70 6f 69  ./*. * Entry poi
c3e0: 6e 74 20 69 6e 74 6f 20 74 68 69 73 20 70 72 6f  nt into this pro
c3f0: 67 72 61 6d 2e 0a 20 2a 2f 0a 69 6e 74 20 6d 61  gram.. */.int ma
c400: 69 6e 28 69 6e 74 20 61 72 67 63 2c 20 63 68 61  in(int argc, cha
c410: 72 20 2a 2a 61 72 67 76 29 20 7b 0a 09 54 63 6c  r **argv) {..Tcl
c420: 5f 49 6e 74 65 72 70 20 2a 74 65 73 74 5f 69 6e  _Interp *test_in
c430: 74 65 72 70 3b 0a 09 63 68 61 72 20 2a 74 65 73  terp;..char *tes
c440: 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 3b 0a  t_interp_error;.
c450: 09 73 74 72 75 63 74 20 66 75 73 65 5f 61 72 67  .struct fuse_arg
c460: 73 20 61 72 67 73 20 3d 20 46 55 53 45 5f 41 52  s args = FUSE_AR
c470: 47 53 5f 49 4e 49 54 28 30 2c 20 4e 55 4c 4c 29  GS_INIT(0, NULL)
c480: 3b 0a 09 73 74 72 75 63 74 20 72 6c 69 6d 69 74  ;..struct rlimit
c490: 20 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c   number_open_fil
c4a0: 65 73 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64  es;..int pthread
c4b0: 5f 72 65 74 2c 20 61 6f 70 5f 72 65 74 2c 20 72  _ret, aop_ret, r
c4c0: 6c 69 6d 69 74 5f 72 65 74 3b 0a 09 76 6f 69 64  limit_ret;..void
c4d0: 20 2a 73 69 67 6e 61 6c 5f 72 65 74 3b 0a 09 63   *signal_ret;..c
c4e0: 68 61 72 20 2a 61 72 67 76 30 3b 0a 09 72 6c 69  har *argv0;..rli
c4f0: 6d 5f 74 20 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f  m_t number_open_
c500: 66 69 6c 65 73 5f 6d 61 78 3b 0a 0a 09 2f 2a 0a  files_max;.../*.
c510: 09 20 2a 20 53 6b 69 70 20 70 61 73 73 65 64 20  . * Skip passed 
c520: 70 72 6f 67 72 61 6d 20 6e 61 6d 65 0a 09 20 2a  program name.. *
c530: 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20 30  /..if (argc == 0
c540: 20 7c 7c 20 61 72 67 76 20 3d 3d 20 4e 55 4c 4c   || argv == NULL
c550: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 31 29 3b  ) {...return(1);
c560: 0a 09 7d 0a 0a 09 61 72 67 76 30 20 3d 20 61 72  ..}...argv0 = ar
c570: 67 76 5b 30 5d 3b 0a 0a 09 61 72 67 63 2d 2d 3b  gv[0];...argc--;
c580: 0a 09 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09  ..argv++;.../*..
c590: 20 2a 20 53 65 74 20 61 70 70 72 6f 70 72 69 61   * Set appropria
c5a0: 74 65 20 75 6d 61 73 6b 0a 09 20 2a 2f 0a 09 75  te umask.. */..u
c5b0: 6d 61 73 6b 28 30 32 32 29 3b 0a 0a 09 2f 2a 0a  mask(022);.../*.
c5c0: 09 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76  . * Set global v
c5d0: 61 72 69 61 62 6c 65 73 2c 20 74 68 65 73 65 20  ariables, these 
c5e0: 73 68 6f 75 6c 64 20 62 65 20 63 6f 6e 66 69 67  should be config
c5f0: 75 72 61 74 69 6f 6e 20 6f 70 74 69 6f 6e 73 2e  uration options.
c600: 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63  .. */..appfs_cac
c610: 68 65 64 69 72 20 3d 20 41 50 50 46 53 5f 43 41  hedir = APPFS_CA
c620: 43 48 45 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20 2a  CHEDIR;.../*.. *
c630: 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69   Set global vari
c640: 61 62 6c 65 20 66 6f 72 20 22 62 6f 6f 74 20 74  able for "boot t
c650: 69 6d 65 22 20 74 6f 20 73 65 74 20 61 20 74 69  ime" to set a ti
c660: 6d 65 20 6f 6e 20 64 69 72 65 63 74 6f 72 69 65  me on directorie
c670: 73 0a 09 20 2a 20 74 68 61 74 20 77 65 20 66 61  s.. * that we fa
c680: 6b 65 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f  ke... */..appfs_
c690: 62 6f 6f 74 74 69 6d 65 20 3d 20 74 69 6d 65 28  boottime = time(
c6a0: 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20  NULL);.../*.. * 
c6b0: 52 65 67 69 73 74 65 72 20 22 73 68 61 31 22 20  Register "sha1" 
c6c0: 61 6e 64 20 22 61 70 70 66 73 64 22 20 70 61 63  and "appfsd" pac
c6d0: 6b 61 67 65 20 77 69 74 68 20 6c 69 62 74 63 6c  kage with libtcl
c6e0: 20 73 6f 20 74 68 61 74 20 61 6e 79 20 6e 65 77   so that any new
c6f0: 0a 09 20 2a 20 69 6e 74 65 72 70 72 65 74 65 72  .. * interpreter
c700: 73 20 63 72 65 61 74 65 64 20 28 77 68 69 63 68  s created (which
c710: 20 61 72 65 20 64 6f 6e 65 20 64 79 6e 61 6d 69   are done dynami
c720: 63 61 6c 6c 79 20 62 79 20 46 55 53 45 29 20 63  cally by FUSE) c
c730: 61 6e 20 68 61 76 65 0a 09 20 2a 20 74 68 65 20  an have.. * the 
c740: 61 70 70 72 6f 70 72 69 61 74 65 20 63 6f 6e 66  appropriate conf
c750: 69 67 75 72 61 74 69 6f 6e 20 64 6f 6e 65 20 61  iguration done a
c760: 75 74 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 09 20  utomatically... 
c770: 2a 2f 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61  */..Tcl_StaticPa
c780: 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 73 68 61  ckage(NULL, "sha
c790: 31 22 2c 20 53 68 61 31 5f 49 6e 69 74 2c 20 4e  1", Sha1_Init, N
c7a0: 55 4c 4c 29 3b 0a 09 54 63 6c 5f 53 74 61 74 69  ULL);..Tcl_Stati
c7b0: 63 50 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22  cPackage(NULL, "
c7c0: 61 70 70 66 73 64 22 2c 20 41 70 70 66 73 64 5f  appfsd", Appfsd_
c7d0: 49 6e 69 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 2f  Init, NULL);.../
c7e0: 2a 0a 09 20 2a 20 43 72 65 61 74 65 20 61 20 74  *.. * Create a t
c7f0: 68 72 65 61 64 2d 73 70 65 63 69 66 69 63 2d 64  hread-specific-d
c800: 61 74 61 20 28 54 53 44 29 20 6b 65 79 20 66 6f  ata (TSD) key fo
c810: 72 20 65 61 63 68 20 74 68 72 65 61 64 20 74 6f  r each thread to
c820: 20 72 65 66 65 72 0a 09 20 2a 20 74 6f 20 69 74   refer.. * to it
c830: 73 20 6f 77 6e 20 54 63 6c 20 69 6e 74 65 72 70  s own Tcl interp
c840: 72 65 74 65 72 2e 20 20 54 63 6c 20 69 6e 74 65  reter.  Tcl inte
c850: 72 70 72 65 74 65 72 73 20 6d 75 73 74 20 62 65  rpreters must be
c860: 20 75 6e 69 71 75 65 20 70 65 72 0a 09 20 2a 20   unique per.. * 
c870: 74 68 72 65 61 64 20 61 6e 64 20 6e 65 77 20 74  thread and new t
c880: 68 72 65 61 64 73 20 61 72 65 20 64 79 6e 61 6d  hreads are dynam
c890: 69 63 61 6c 6c 79 20 63 72 65 61 74 65 64 20 62  ically created b
c8a0: 79 20 46 55 53 45 2e 0a 09 20 2a 2f 0a 09 70 74  y FUSE... */..pt
c8b0: 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72  hread_ret = pthr
c8c0: 65 61 64 5f 6b 65 79 5f 63 72 65 61 74 65 28 26  ead_key_create(&
c8d0: 69 6e 74 65 72 70 4b 65 79 2c 20 61 70 70 66 73  interpKey, appfs
c8e0: 5f 74 65 72 6d 69 6e 61 74 65 5f 69 6e 74 65 72  _terminate_inter
c8f0: 70 5f 61 6e 64 5f 74 68 72 65 61 64 29 3b 0a 09  p_and_thread);..
c900: 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20  if (pthread_ret 
c910: 21 3d 20 30 29 20 7b 0a 09 09 66 70 72 69 6e 74  != 0) {...fprint
c920: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
c930: 65 20 74 6f 20 63 72 65 61 74 65 20 54 53 44 20  e to create TSD 
c940: 6b 65 79 20 66 6f 72 20 54 63 6c 2e 20 20 41 62  key for Tcl.  Ab
c950: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09  orting.\n");....
c960: 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09  return(1);..}...
c970: 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61 6c 6c 79 20  /*.. * Manually 
c980: 73 70 65 63 69 66 79 20 63 61 63 68 65 20 64 69  specify cache di
c990: 72 65 63 74 6f 72 79 2c 20 77 69 74 68 6f 75 74  rectory, without
c9a0: 20 46 55 53 45 20 63 61 6c 6c 62 61 63 6b 0a 09   FUSE callback..
c9b0: 20 2a 20 54 68 69 73 20 6f 70 74 69 6f 6e 20 6f   * This option o
c9c0: 6e 6c 79 20 77 6f 72 6b 73 20 77 68 65 6e 20 6e  nly works when n
c9d0: 6f 74 20 75 73 69 6e 67 20 46 55 53 45 2c 20 73  ot using FUSE, s
c9e0: 69 6e 63 65 20 77 65 0a 09 20 2a 20 64 6f 20 6e  ince we.. * do n
c9f0: 6f 74 20 70 72 6f 63 65 73 73 20 69 74 20 77 69  ot process it wi
ca00: 74 68 20 46 55 53 45 73 20 6f 70 74 69 6f 6e 20  th FUSEs option 
ca10: 70 72 6f 63 65 73 73 69 6e 67 2e 0a 09 20 2a 2f  processing... */
ca20: 0a 09 69 66 20 28 61 72 67 63 20 3e 3d 20 32 29  ..if (argc >= 2)
ca30: 20 7b 0a 09 09 69 66 20 28 73 74 72 63 6d 70 28   {...if (strcmp(
ca40: 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 63 61 63 68  argv[0], "--cach
ca50: 65 64 69 72 22 29 20 3d 3d 20 30 29 20 7b 0a 09  edir") == 0) {..
ca60: 09 09 61 70 70 66 73 5f 63 61 63 68 65 64 69 72  ..appfs_cachedir
ca70: 20 3d 20 73 74 72 64 75 70 28 61 72 67 76 5b 31   = strdup(argv[1
ca80: 5d 29 3b 0a 0a 09 09 09 61 72 67 63 20 2d 3d 20  ]);.....argc -= 
ca90: 32 3b 0a 09 09 09 61 72 67 76 20 2b 3d 20 32 3b  2;....argv += 2;
caa0: 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  ...}..}.../*.. *
cab0: 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 2c 20 66   SQLite3 mode, f
cac0: 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77 20 53  or running raw S
cad0: 51 4c 20 61 67 61 69 6e 73 74 20 74 68 65 20 63  QL against the c
cae0: 61 63 68 65 20 64 61 74 61 62 61 73 65 0a 09 20  ache database.. 
caf0: 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20  */..if (argc == 
cb00: 32 20 26 26 20 73 74 72 63 6d 70 28 61 72 67 76  2 && strcmp(argv
cb10: 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69 74 65 33 22  [0], "--sqlite3"
cb20: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  ) == 0) {...retu
cb30: 72 6e 28 61 70 70 66 73 5f 73 71 6c 69 74 65 33  rn(appfs_sqlite3
cb40: 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 0a  (argv[1]));..}..
cb50: 09 2f 2a 0a 09 20 2a 20 54 63 6c 20 6d 6f 64 65  ./*.. * Tcl mode
cb60: 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61  , for running ra
cb70: 77 20 54 63 6c 20 69 6e 20 74 68 65 20 73 61 6d  w Tcl in the sam
cb80: 65 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 41 70  e environment Ap
cb90: 70 46 53 64 20 77 6f 75 6c 64 0a 09 20 2a 20 72  pFSd would.. * r
cba0: 75 6e 20 63 6f 64 65 2e 0a 09 20 2a 2f 0a 09 69  un code... */..i
cbb0: 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26 26 20  f (argc == 2 && 
cbc0: 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20  strcmp(argv[0], 
cbd0: 22 2d 2d 74 63 6c 22 29 20 3d 3d 20 30 29 20 7b  "--tcl") == 0) {
cbe0: 0a 09 09 72 65 74 75 72 6e 28 61 70 70 66 73 5f  ...return(appfs_
cbf0: 74 63 6c 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09  tcl(argv[1]));..
cc00: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 67 69 73  }.../*.. * Regis
cc10: 74 65 72 20 61 20 73 69 67 6e 61 6c 20 68 61 6e  ter a signal han
cc20: 64 6c 65 72 20 66 6f 72 20 68 6f 74 2d 72 65 73  dler for hot-res
cc30: 74 61 72 74 20 72 65 71 75 65 73 74 73 0a 09 20  tart requests.. 
cc40: 2a 2f 0a 09 73 69 67 6e 61 6c 5f 72 65 74 20 3d  */..signal_ret =
cc50: 20 73 69 67 6e 61 6c 28 53 49 47 48 55 50 2c 20   signal(SIGHUP, 
cc60: 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f 68 61 6e  appfs_signal_han
cc70: 64 6c 65 72 29 3b 0a 09 69 66 20 28 73 69 67 6e  dler);..if (sign
cc80: 61 6c 5f 72 65 74 20 3d 3d 20 53 49 47 5f 45 52  al_ret == SIG_ER
cc90: 52 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  R) {...fprintf(s
cca0: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
ccb0: 6f 20 69 6e 73 74 61 6c 6c 20 73 69 67 6e 61 6c  o install signal
ccc0: 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 68 6f 74   handler for hot
ccd0: 2d 72 65 73 74 61 72 74 5c 6e 22 29 3b 0a 09 09  -restart\n");...
cce0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
ccf0: 22 48 6f 74 2d 72 65 73 74 61 72 74 20 77 69 6c  "Hot-restart wil
cd00: 6c 20 6e 6f 74 20 62 65 20 61 76 61 69 6c 61 62  l not be availab
cd10: 6c 65 2e 5c 6e 22 29 3b 0a 09 7d 0a 0a 09 2f 2a  le.\n");..}.../*
cd20: 0a 09 20 2a 20 50 61 72 73 65 20 63 6f 6d 6d 61  .. * Parse comma
cd30: 6e 64 20 6c 69 6e 65 20 61 72 67 75 6d 65 6e 74  nd line argument
cd40: 73 0a 09 20 2a 2f 0a 09 2f 2a 2a 0a 09 20 2a 2a  s.. */../**.. **
cd50: 20 52 65 73 74 6f 72 65 20 61 72 67 63 2f 61 72   Restore argc/ar
cd60: 67 76 20 74 6f 20 6f 72 69 67 69 6e 61 6c 20 76  gv to original v
cd70: 61 6c 75 65 73 2c 20 72 65 70 6c 61 63 69 6e 67  alues, replacing
cd80: 20 61 72 67 76 5b 30 5d 20 69 6e 20 63 61 73 65   argv[0] in case
cd90: 0a 09 20 2a 2a 20 69 74 20 77 61 73 20 6d 6f 69  .. ** it was moi
cda0: 66 69 65 64 20 62 79 20 2d 2d 63 61 63 68 65 64  fied by --cached
cdb0: 69 72 20 6f 70 74 69 6f 6e 2e 0a 09 20 2a 2a 2f  ir option... **/
cdc0: 0a 09 61 72 67 63 2b 2b 3b 0a 09 61 72 67 76 2d  ..argc++;..argv-
cdd0: 2d 3b 0a 09 61 72 67 76 5b 30 5d 20 3d 20 61 72  -;..argv[0] = ar
cde0: 67 76 30 3b 0a 0a 09 2f 2a 2a 0a 09 20 2a 2a 20  gv0;.../**.. ** 
cdf0: 50 65 72 66 6f 72 6d 20 74 68 65 20 61 72 67 75  Perform the argu
ce00: 6d 65 6e 74 20 70 61 72 73 69 6e 67 0a 09 20 2a  ment parsing.. *
ce10: 2a 2f 0a 09 61 6f 70 5f 72 65 74 20 3d 20 61 70  */..aop_ret = ap
ce20: 70 66 73 5f 6f 70 74 5f 70 61 72 73 65 28 61 72  pfs_opt_parse(ar
ce30: 67 63 2c 20 61 72 67 76 2c 20 26 61 72 67 73 29  gc, argv, &args)
ce40: 3b 0a 09 69 66 20 28 61 6f 70 5f 72 65 74 20 21  ;..if (aop_ret !
ce50: 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 61 6f 70  = 0) {...if (aop
ce60: 5f 72 65 74 20 3c 20 30 29 20 7b 0a 09 09 09 72  _ret < 0) {....r
ce70: 65 74 75 72 6e 28 30 29 3b 0a 09 09 7d 0a 0a 09  eturn(0);...}...
ce80: 09 72 65 74 75 72 6e 28 61 6f 70 5f 72 65 74 29  .return(aop_ret)
ce90: 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72  ;..}.../*.. * Cr
cea0: 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72  eate a Tcl inter
ceb0: 70 72 65 74 65 72 20 6a 75 73 74 20 74 6f 20 76  preter just to v
cec0: 65 72 69 66 79 20 74 68 61 74 20 74 68 69 6e 67  erify that thing
ced0: 73 20 61 72 65 20 69 6e 20 77 6f 72 6b 69 6e 67  s are in working
cee0: 20 0a 09 20 2a 20 6f 72 64 65 72 20 62 65 66 6f   .. * order befo
cef0: 72 65 20 77 65 20 62 65 63 6f 6d 65 20 61 20 64  re we become a d
cf00: 61 65 6d 6f 6e 2e 0a 09 20 2a 2f 0a 09 74 65 73  aemon... */..tes
cf10: 74 5f 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  t_interp = appfs
cf20: 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72  _create_TclInter
cf30: 70 28 26 74 65 73 74 5f 69 6e 74 65 72 70 5f 65  p(&test_interp_e
cf40: 72 72 6f 72 29 3b 0a 09 69 66 20 28 74 65 73 74  rror);..if (test
cf50: 5f 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  _interp == NULL)
cf60: 20 7b 0a 09 09 69 66 20 28 74 65 73 74 5f 69 6e   {...if (test_in
cf70: 74 65 72 70 5f 65 72 72 6f 72 20 3d 3d 20 4e 55  terp_error == NU
cf80: 4c 4c 29 20 7b 0a 09 09 09 74 65 73 74 5f 69 6e  LL) {....test_in
cf90: 74 65 72 70 5f 65 72 72 6f 72 20 3d 20 22 55 6e  terp_error = "Un
cfa0: 6b 6e 6f 77 6e 20 65 72 72 6f 72 22 3b 0a 09 09  known error";...
cfb0: 7d 0a 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64  }....fprintf(std
cfc0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
cfd0: 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 69  initialize Tcl i
cfe0: 6e 74 65 72 70 72 65 74 65 72 20 66 6f 72 20 41  nterpreter for A
cff0: 70 70 46 53 64 3a 5c 6e 22 29 3b 0a 09 09 66 70  ppFSd:\n");...fp
d000: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25  rintf(stderr, "%
d010: 73 5c 6e 22 2c 20 74 65 73 74 5f 69 6e 74 65 72  s\n", test_inter
d020: 70 5f 65 72 72 6f 72 29 3b 0a 0a 09 09 72 65 74  p_error);....ret
d030: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 54 63 6c  urn(1);..}...Tcl
d040: 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 74 65  _DeleteInterp(te
d050: 73 74 5f 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66  st_interp);...if
d060: 20 28 61 70 70 66 73 5f 74 68 72 65 61 64 65 64   (appfs_threaded
d070: 5f 74 63 6c 29 20 7b 0a 09 09 54 63 6c 5f 46 69  _tcl) {...Tcl_Fi
d080: 6e 61 6c 69 7a 65 4e 6f 74 69 66 69 65 72 28 4e  nalizeNotifier(N
d090: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  ULL);..}.../*.. 
d0a0: 2a 20 49 6e 63 72 65 61 73 65 20 72 65 73 6f 75  * Increase resou
d0b0: 72 63 65 20 6c 69 6d 69 74 73 20 66 6f 72 20 6e  rce limits for n
d0c0: 75 6d 62 65 72 20 6f 66 20 6f 70 65 6e 20 66 69  umber of open fi
d0d0: 6c 65 73 0a 09 20 2a 20 74 6f 20 74 68 65 20 6d  les.. * to the m
d0e0: 61 78 69 6d 75 6d 20 76 61 6c 75 65 73 2c 20 73  aximum values, s
d0f0: 69 6e 63 65 20 77 65 20 6d 61 79 20 62 65 20 61  ince we may be a
d100: 73 6b 65 64 20 74 6f 0a 09 20 2a 20 68 6f 6c 64  sked to.. * hold
d110: 20 6f 70 65 6e 20 6d 61 6e 79 20 66 69 6c 65 73   open many files
d120: 20 6f 6e 20 62 65 68 61 6c 66 20 6f 66 20 6d 61   on behalf of ma
d130: 6e 79 20 6f 74 68 65 72 20 70 72 6f 63 65 73 73  ny other process
d140: 65 73 0a 09 20 2a 2f 0a 09 6e 75 6d 62 65 72 5f  es.. */..number_
d150: 6f 70 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f  open_files.rlim_
d160: 63 75 72 20 3d 20 6e 75 6d 62 65 72 5f 6f 70 65  cur = number_ope
d170: 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f 6d 61 78  n_files.rlim_max
d180: 20 3d 20 52 4c 49 4d 5f 49 4e 46 49 4e 49 54 59   = RLIM_INFINITY
d190: 3b 0a 0a 09 72 6c 69 6d 69 74 5f 72 65 74 20 3d  ;...rlimit_ret =
d1a0: 20 73 65 74 72 6c 69 6d 69 74 28 52 4c 49 4d 49   setrlimit(RLIMI
d1b0: 54 5f 4e 4f 46 49 4c 45 2c 20 26 6e 75 6d 62 65  T_NOFILE, &numbe
d1c0: 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 29 3b 0a 0a  r_open_files);..
d1d0: 09 69 66 20 28 72 6c 69 6d 69 74 5f 72 65 74 20  .if (rlimit_ret 
d1e0: 21 3d 20 30 29 20 7b 0a 09 09 72 6c 69 6d 69 74  != 0) {...rlimit
d1f0: 5f 72 65 74 20 3d 20 67 65 74 72 6c 69 6d 69 74  _ret = getrlimit
d200: 28 52 4c 49 4d 49 54 5f 4e 4f 46 49 4c 45 2c 20  (RLIMIT_NOFILE, 
d210: 26 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c  &number_open_fil
d220: 65 73 29 3b 0a 09 09 69 66 20 28 72 6c 69 6d 69  es);...if (rlimi
d230: 74 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09 09  t_ret == 0) {...
d240: 09 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c  .number_open_fil
d250: 65 73 5f 6d 61 78 20 3d 20 6e 75 6d 62 65 72 5f  es_max = number_
d260: 6f 70 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f  open_files.rlim_
d270: 6d 61 78 3b 0a 0a 09 09 09 69 66 20 28 6e 75 6d  max;.....if (num
d280: 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 5f 6d  ber_open_files_m
d290: 61 78 20 3c 20 28 31 30 32 34 20 2a 20 31 30 32  ax < (1024 * 102
d2a0: 34 29 29 20 7b 0a 09 09 09 09 6e 75 6d 62 65 72  4)) {.....number
d2b0: 5f 6f 70 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d  _open_files.rlim
d2c0: 5f 63 75 72 20 3d 20 6e 75 6d 62 65 72 5f 6f 70  _cur = number_op
d2d0: 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f 6d 61  en_files.rlim_ma
d2e0: 78 20 3d 20 31 30 32 34 20 2a 20 31 30 32 34 3b  x = 1024 * 1024;
d2f0: 0a 0a 09 09 09 09 72 6c 69 6d 69 74 5f 72 65 74  ......rlimit_ret
d300: 20 3d 20 73 65 74 72 6c 69 6d 69 74 28 52 4c 49   = setrlimit(RLI
d310: 4d 49 54 5f 4e 4f 46 49 4c 45 2c 20 26 6e 75 6d  MIT_NOFILE, &num
d320: 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 29 3b  ber_open_files);
d330: 0a 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09  ....} else {....
d340: 09 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c  .number_open_fil
d350: 65 73 2e 72 6c 69 6d 5f 63 75 72 20 3d 20 6e 75  es.rlim_cur = nu
d360: 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 2e  mber_open_files.
d370: 72 6c 69 6d 5f 6d 61 78 3b 0a 09 09 09 7d 0a 0a  rlim_max;....}..
d380: 09 09 09 72 6c 69 6d 69 74 5f 72 65 74 20 3d 20  ...rlimit_ret = 
d390: 73 65 74 72 6c 69 6d 69 74 28 52 4c 49 4d 49 54  setrlimit(RLIMIT
d3a0: 5f 4e 4f 46 49 4c 45 2c 20 26 6e 75 6d 62 65 72  _NOFILE, &number
d3b0: 5f 6f 70 65 6e 5f 66 69 6c 65 73 29 3b 0a 0a 09  _open_files);...
d3c0: 09 09 69 66 20 28 72 6c 69 6d 69 74 5f 72 65 74  ..if (rlimit_ret
d3d0: 20 21 3d 20 30 20 26 26 20 6e 75 6d 62 65 72 5f   != 0 && number_
d3e0: 6f 70 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f  open_files.rlim_
d3f0: 63 75 72 20 21 3d 20 6e 75 6d 62 65 72 5f 6f 70  cur != number_op
d400: 65 6e 5f 66 69 6c 65 73 5f 6d 61 78 29 20 7b 0a  en_files_max) {.
d410: 09 09 09 09 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f  ....number_open_
d420: 66 69 6c 65 73 2e 72 6c 69 6d 5f 63 75 72 20 3d  files.rlim_cur =
d430: 20 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c   number_open_fil
d440: 65 73 2e 72 6c 69 6d 5f 6d 61 78 20 3d 20 6e 75  es.rlim_max = nu
d450: 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 5f  mber_open_files_
d460: 6d 61 78 3b 0a 0a 09 09 09 09 73 65 74 72 6c 69  max;......setrli
d470: 6d 69 74 28 52 4c 49 4d 49 54 5f 4e 4f 46 49 4c  mit(RLIMIT_NOFIL
d480: 45 2c 20 26 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f  E, &number_open_
d490: 66 69 6c 65 73 29 3b 0a 09 09 09 7d 0a 09 09 7d  files);....}...}
d4a0: 0a 09 7d 0a 0a 0a 09 2f 2a 0a 09 20 2a 20 45 6e  ..}..../*.. * En
d4b0: 74 65 72 20 74 68 65 20 46 55 53 45 20 6d 61 69  ter the FUSE mai
d4c0: 6e 20 6c 6f 6f 70 20 2d 2d 20 74 68 69 73 20 77  n loop -- this w
d4d0: 69 6c 6c 20 70 72 6f 63 65 73 73 20 61 6e 79 20  ill process any 
d4e0: 61 72 67 75 6d 65 6e 74 73 0a 09 20 2a 20 61 6e  arguments.. * an
d4f0: 64 20 73 74 61 72 74 20 73 65 72 76 69 63 69 6e  d start servicin
d500: 67 20 72 65 71 75 65 73 74 73 2e 0a 09 20 2a 2f  g requests... */
d510: 0a 09 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61  ..appfs_fuse_sta
d520: 72 74 65 64 20 3d 20 31 3b 0a 09 72 65 74 75 72  rted = 1;..retur
d530: 6e 28 66 75 73 65 5f 6d 61 69 6e 28 61 72 67 73  n(fuse_main(args
d540: 2e 61 72 67 63 2c 20 61 72 67 73 2e 61 72 67 76  .argc, args.argv
d550: 2c 20 26 61 70 70 66 73 5f 6f 70 65 72 61 74 69  , &appfs_operati
d560: 6f 6e 73 2c 20 4e 55 4c 4c 29 29 3b 0a 7d 0a     ons, NULL));.}.