Hex Artifact Content

Artifact b7dddfc0b8144875948fa7339cda6d3181ea1137:


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 20 69 6e  ed, returning in
29d0: 20 66 61 69 6c 75 72 65 2e 22 29 3b 0a 0a 09 09   failure.");....
29e0: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
29f0: 09 7d 0a 0a 09 09 70 74 68 72 65 61 64 5f 72 65  .}....pthread_re
2a00: 74 20 3d 20 70 74 68 72 65 61 64 5f 73 65 74 73  t = pthread_sets
2a10: 70 65 63 69 66 69 63 28 69 6e 74 65 72 70 4b 65  pecific(interpKe
2a20: 79 2c 20 69 6e 74 65 72 70 29 3b 0a 09 09 69 66  y, interp);...if
2a30: 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d   (pthread_ret !=
2a40: 20 30 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44   0) {....APPFS_D
2a50: 45 42 55 47 28 22 70 74 68 72 65 61 64 5f 73 65  EBUG("pthread_se
2a60: 74 73 70 65 63 69 66 69 63 28 29 20 66 61 69 6c  tspecific() fail
2a70: 65 64 2e 20 20 54 65 72 6d 69 6e 61 74 69 6e 67  ed.  Terminating
2a80: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
2a90: 2e 22 29 3b 0a 0a 09 09 09 61 70 70 66 73 5f 63  .");.....appfs_c
2aa0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44  all_libtcl(Tcl_D
2ab0: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65  eleteInterp(inte
2ac0: 72 70 29 3b 29 0a 0a 09 09 09 72 65 74 75 72 6e  rp);).....return
2ad0: 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a 09 7d 0a 0a  (NULL);...}..}..
2ae0: 09 72 65 74 75 72 6e 28 69 6e 74 65 72 70 29 3b  .return(interp);
2af0: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 76 61 6c 75 61  .}../*. * Evalua
2b00: 74 65 20 61 20 54 63 6c 20 73 63 72 69 70 74 20  te a Tcl script 
2b10: 63 6f 6e 73 74 72 75 63 74 65 64 20 62 79 20 63  constructed by c
2b20: 6f 6e 63 61 74 65 6e 61 74 69 6e 67 20 61 20 62  oncatenating a b
2b30: 75 6e 63 68 20 6f 66 20 43 20 73 74 72 69 6e 67  unch of C string
2b40: 73 0a 20 2a 20 74 6f 67 65 74 68 65 72 2e 0a 20  s. * together.. 
2b50: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  */.static int ap
2b60: 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 54 63 6c  pfs_Tcl_Eval(Tcl
2b70: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
2b80: 20 69 6e 74 20 6f 62 6a 63 2c 20 63 6f 6e 73 74   int objc, const
2b90: 20 63 68 61 72 20 2a 63 6d 64 2c 20 2e 2e 2e 29   char *cmd, ...)
2ba0: 20 7b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a 6f 62   {..Tcl_Obj **ob
2bb0: 6a 76 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20  jv;..const char 
2bc0: 2a 61 72 67 3b 0a 09 76 61 5f 6c 69 73 74 20 61  *arg;..va_list a
2bd0: 72 67 70 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c  rgp;..int retval
2be0: 3b 0a 09 69 6e 74 20 69 3b 0a 0a 09 69 66 20 28  ;..int i;...if (
2bf0: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
2c00: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
2c10: 22 49 6e 76 61 6c 69 64 20 69 6e 74 65 72 70 72  "Invalid interpr
2c20: 65 74 65 72 20 70 61 73 73 65 64 20 69 6e 2c 20  eter passed in, 
2c30: 72 65 74 75 72 6e 69 6e 67 20 69 6e 20 66 61 69  returning in fai
2c40: 6c 75 72 65 2e 22 29 3b 0a 0a 09 09 72 65 74 75  lure.");....retu
2c50: 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09  rn(TCL_ERROR);..
2c60: 7d 0a 0a 09 6f 62 6a 76 20 3d 20 28 76 6f 69 64  }...objv = (void
2c70: 20 2a 29 20 63 6b 61 6c 6c 6f 63 28 73 69 7a 65   *) ckalloc(size
2c80: 6f 66 28 2a 6f 62 6a 76 29 20 2a 20 6f 62 6a 63  of(*objv) * objc
2c90: 29 3b 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  );...appfs_call_
2ca0: 6c 69 62 74 63 6c 28 0a 09 09 6f 62 6a 76 5b 30  libtcl(...objv[0
2cb0: 5d 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  ] = Tcl_NewStrin
2cc0: 67 4f 62 6a 28 63 6d 64 2c 20 2d 31 29 3b 0a 0a  gObj(cmd, -1);..
2cd0: 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75  ..Tcl_IncrRefCou
2ce0: 6e 74 28 6f 62 6a 76 5b 30 5d 29 3b 0a 0a 09 09  nt(objv[0]);....
2cf0: 76 61 5f 73 74 61 72 74 28 61 72 67 70 2c 20 63  va_start(argp, c
2d00: 6d 64 29 3b 0a 09 09 66 6f 72 20 28 69 20 3d 20  md);...for (i = 
2d10: 31 3b 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b  1; i < objc; i++
2d20: 29 20 7b 0a 09 09 09 61 72 67 20 3d 20 76 61 5f  ) {....arg = va_
2d30: 61 72 67 28 61 72 67 70 2c 20 63 6f 6e 73 74 20  arg(argp, const 
2d40: 63 68 61 72 20 2a 29 3b 0a 0a 09 09 09 6f 62 6a  char *);.....obj
2d50: 76 5b 69 5d 20 3d 20 54 63 6c 5f 4e 65 77 53 74  v[i] = Tcl_NewSt
2d60: 72 69 6e 67 4f 62 6a 28 61 72 67 2c 20 2d 31 29  ringObj(arg, -1)
2d70: 3b 0a 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65  ;.....Tcl_IncrRe
2d80: 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b  fCount(objv[i]);
2d90: 0a 09 09 7d 0a 09 09 76 61 5f 65 6e 64 28 61 72  ...}...va_end(ar
2da0: 67 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f  gp);..)...appfs_
2db0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72  call_libtcl(...r
2dc0: 65 74 76 61 6c 20 3d 20 54 63 6c 5f 45 76 61 6c  etval = Tcl_Eval
2dd0: 4f 62 6a 76 28 69 6e 74 65 72 70 2c 20 6f 62 6a  Objv(interp, obj
2de0: 63 2c 20 6f 62 6a 76 2c 20 30 29 3b 0a 09 29 0a  c, objv, 0);..).
2df0: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
2e00: 74 63 6c 28 0a 09 09 66 6f 72 20 28 69 20 3d 20  tcl(...for (i = 
2e10: 30 3b 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b  0; i < objc; i++
2e20: 29 20 7b 0a 09 09 09 54 63 6c 5f 44 65 63 72 52  ) {....Tcl_DecrR
2e30: 65 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29  efCount(objv[i])
2e40: 3b 0a 09 09 7d 0a 09 29 0a 0a 09 63 6b 66 72 65  ;...}..)...ckfre
2e50: 65 28 28 76 6f 69 64 20 2a 29 20 6f 62 6a 76 29  e((void *) objv)
2e60: 3b 0a 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21  ;...if (retval !
2e70: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 61 70  = TCL_OK) {...ap
2e80: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
2e90: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
2ea0: 22 54 63 6c 20 63 6f 6d 6d 61 6e 64 20 66 61 69  "Tcl command fai
2eb0: 6c 65 64 2c 20 3a 3a 65 72 72 6f 72 49 6e 66 6f  led, ::errorInfo
2ec0: 20 63 6f 6e 74 61 69 6e 73 3a 20 25 73 5c 6e 22   contains: %s\n"
2ed0: 2c 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74  , Tcl_GetVar(int
2ee0: 65 72 70 2c 20 22 3a 3a 65 72 72 6f 72 49 6e 66  erp, "::errorInf
2ef0: 6f 22 2c 20 30 29 29 3b 0a 09 09 29 0a 09 7d 0a  o", 0));...)..}.
2f00: 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
2f10: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 52 65 71 75 65  ;.}../*. * Reque
2f20: 73 74 20 61 6c 6c 20 54 63 6c 20 69 6e 74 65 72  st all Tcl inter
2f30: 70 72 65 74 65 72 73 20 72 65 73 74 61 72 74 0a  preters restart.
2f40: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
2f50: 61 70 70 66 73 5f 74 63 6c 5f 52 65 73 65 74 49  appfs_tcl_ResetI
2f60: 6e 74 65 72 70 73 28 76 6f 69 64 29 20 7b 0a 09  nterps(void) {..
2f70: 41 50 50 46 53 5f 44 45 42 55 47 28 22 52 65 71  APPFS_DEBUG("Req
2f80: 75 65 73 74 69 6e 67 20 72 65 73 65 74 20 6f 66  uesting reset of
2f90: 20 61 6c 6c 20 69 6e 74 65 72 70 72 65 74 65 72   all interpreter
2fa0: 73 2e 22 29 3b 0a 0a 09 5f 5f 73 79 6e 63 5f 61  s.");...__sync_a
2fb0: 64 64 5f 61 6e 64 5f 66 65 74 63 68 28 26 69 6e  dd_and_fetch(&in
2fc0: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20  terp_reset_key, 
2fd0: 31 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a  1);...return;.}.
2fe0: 0a 2f 2a 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65  ./*. * Determine
2ff0: 20 74 68 65 20 55 49 44 20 66 6f 72 20 74 68 65   the UID for the
3000: 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65   user making the
3010: 20 63 75 72 72 65 6e 74 20 46 55 53 45 20 66 69   current FUSE fi
3020: 6c 65 73 79 73 74 65 6d 20 72 65 71 75 65 73 74  lesystem request
3030: 2e 0a 20 2a 20 54 68 69 73 20 77 69 6c 6c 20 62  .. * This will b
3040: 65 20 75 73 65 64 20 74 6f 20 6c 6f 6f 6b 75 70  e used to lookup
3050: 20 74 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65   the user's home
3060: 20 64 69 72 65 63 74 6f 72 79 20 73 6f 20 77 65   directory so we
3070: 20 63 61 6e 20 73 65 61 72 63 68 20 66 6f 72 0a   can search for.
3080: 20 2a 20 6c 6f 63 61 6c 6c 79 20 6d 6f 64 69 66   * locally modif
3090: 69 65 64 20 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73  ied files.. */.s
30a0: 74 61 74 69 63 20 75 69 64 5f 74 20 61 70 70 66  tatic uid_t appf
30b0: 73 5f 67 65 74 5f 66 73 75 69 64 28 76 6f 69 64  s_get_fsuid(void
30c0: 29 20 7b 0a 09 73 74 72 75 63 74 20 66 75 73 65  ) {..struct fuse
30d0: 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78 3b 0a 0a  _context *ctx;..
30e0: 09 69 66 20 28 21 61 70 70 66 73 5f 66 75 73 65  .if (!appfs_fuse
30f0: 5f 73 74 61 72 74 65 64 29 20 7b 0a 09 09 72 65  _started) {...re
3100: 74 75 72 6e 28 67 65 74 75 69 64 28 29 29 3b 0a  turn(getuid());.
3110: 09 7d 0a 0a 09 63 74 78 20 3d 20 66 75 73 65 5f  .}...ctx = fuse_
3120: 67 65 74 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09  get_context();..
3130: 69 66 20 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29  if (ctx == NULL)
3140: 20 7b 0a 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74   {.../* Unable t
3150: 6f 20 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f  o lookup user fo
3160: 72 20 73 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f  r some reason */
3170: 0a 09 09 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20  .../* Return an 
3180: 75 6e 70 72 69 76 69 6c 65 67 65 64 20 75 73 65  unprivileged use
3190: 72 20 49 44 20 2a 2f 0a 09 09 41 50 50 46 53 5f  r ID */...APPFS_
31a0: 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f  DEBUG("Unable to
31b0: 20 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72   lookup user for
31c0: 20 73 6f 6d 65 20 72 65 61 73 6f 6e 2c 20 72 65   some reason, re
31d0: 74 75 72 6e 69 6e 6e 67 20 75 73 65 72 20 49 44  turninng user ID
31e0: 20 6f 66 20 31 22 29 3b 0a 0a 09 09 72 65 74 75   of 1");....retu
31f0: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  rn(1);..}...retu
3200: 72 6e 28 63 74 78 2d 3e 75 69 64 29 3b 0a 7d 0a  rn(ctx->uid);.}.
3210: 0a 2f 2a 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65  ./*. * Determine
3220: 20 74 68 65 20 47 49 44 20 66 6f 72 20 74 68 65   the GID for the
3230: 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65   user making the
3240: 20 63 75 72 72 65 6e 74 20 46 55 53 45 20 66 69   current FUSE fi
3250: 6c 65 73 79 73 74 65 6d 20 72 65 71 75 65 73 74  lesystem request
3260: 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 67 69 64  .. */.static gid
3270: 5f 74 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67  _t appfs_get_fsg
3280: 69 64 28 76 6f 69 64 29 20 7b 0a 09 73 74 72 75  id(void) {..stru
3290: 63 74 20 66 75 73 65 5f 63 6f 6e 74 65 78 74 20  ct fuse_context 
32a0: 2a 63 74 78 3b 0a 0a 09 69 66 20 28 21 61 70 70  *ctx;...if (!app
32b0: 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 29  fs_fuse_started)
32c0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 67 65 74 67   {...return(getg
32d0: 69 64 28 29 29 3b 0a 09 7d 0a 0a 09 63 74 78 20  id());..}...ctx 
32e0: 3d 20 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65  = fuse_get_conte
32f0: 78 74 28 29 3b 0a 09 69 66 20 28 63 74 78 20 3d  xt();..if (ctx =
3300: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20 55  = NULL) {.../* U
3310: 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20  nable to lookup 
3320: 75 73 65 72 20 66 6f 72 20 73 6f 6d 65 20 72 65  user for some re
3330: 61 73 6f 6e 20 2a 2f 0a 09 09 2f 2a 20 52 65 74  ason */.../* Ret
3340: 75 72 6e 20 61 6e 20 75 6e 70 72 69 76 69 6c 65  urn an unprivile
3350: 67 65 64 20 75 73 65 72 20 49 44 20 2a 2f 0a 09  ged user ID */..
3360: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
3370: 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 67  able to lookup g
3380: 72 6f 75 70 20 66 6f 72 20 73 6f 6d 65 20 72 65  roup for some re
3390: 61 73 6f 6e 2c 20 72 65 74 75 72 6e 69 6e 6e 67  ason, returninng
33a0: 20 67 72 6f 75 70 20 49 44 20 6f 66 20 31 22 29   group ID of 1")
33b0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a  ;....return(1);.
33c0: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 63 74 78 2d  .}...return(ctx-
33d0: 3e 67 69 64 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  >gid);.}..static
33e0: 20 76 6f 69 64 20 61 70 70 66 73 5f 73 69 6d 75   void appfs_simu
33f0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
3400: 65 72 28 76 6f 69 64 29 20 7b 0a 09 73 65 74 66  er(void) {..setf
3410: 73 75 69 64 28 61 70 70 66 73 5f 67 65 74 5f 66  suid(appfs_get_f
3420: 73 75 69 64 28 29 29 3b 0a 09 73 65 74 66 73 67  suid());..setfsg
3430: 69 64 28 61 70 70 66 73 5f 67 65 74 5f 66 73 67  id(appfs_get_fsg
3440: 69 64 28 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  id());.}..static
3450: 20 76 6f 69 64 20 61 70 70 66 73 5f 73 69 6d 75   void appfs_simu
3460: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
3470: 76 65 28 76 6f 69 64 29 20 7b 0a 09 73 65 74 66  ve(void) {..setf
3480: 73 75 69 64 28 30 29 3b 0a 09 73 65 74 66 73 67  suid(0);..setfsg
3490: 69 64 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  id(0);.}../*. * 
34a0: 4c 6f 6f 6b 20 75 70 20 74 68 65 20 68 6f 6d 65  Look up the home
34b0: 20 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20 61   directory for a
34c0: 20 67 69 76 65 6e 20 55 49 44 0a 20 2a 20 20 20   given UID. *   
34d0: 20 20 20 20 20 52 65 74 75 72 6e 73 20 61 20 43       Returns a C
34e0: 20 73 74 72 69 6e 67 20 63 6f 6e 74 61 69 6e 69   string containi
34f0: 6e 67 20 74 68 65 20 75 73 65 72 27 73 20 68 6f  ng the user's ho
3500: 6d 65 20 64 69 72 65 63 74 6f 72 79 20 6f 72 20  me directory or 
3510: 4e 55 4c 4c 20 69 66 0a 20 2a 20 20 20 20 20 20  NULL if. *      
3520: 20 20 74 68 65 20 75 73 65 72 27 73 20 68 6f 6d    the user's hom
3530: 65 20 64 69 72 65 63 74 6f 72 79 20 64 6f 65 73  e directory does
3540: 20 6e 6f 74 20 65 78 69 73 74 20 6f 72 20 69 73   not exist or is
3550: 20 6e 6f 74 20 63 6f 72 72 65 63 74 6c 79 0a 20   not correctly. 
3560: 2a 20 20 20 20 20 20 20 20 63 6f 6e 66 69 67 75  *        configu
3570: 72 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 63  red. */.static c
3580: 68 61 72 20 2a 61 70 70 66 73 5f 67 65 74 5f 68  har *appfs_get_h
3590: 6f 6d 65 64 69 72 28 75 69 64 5f 74 20 66 73 75  omedir(uid_t fsu
35a0: 69 64 29 20 7b 0a 09 73 74 72 75 63 74 20 70 61  id) {..struct pa
35b0: 73 73 77 64 20 65 6e 74 72 79 2c 20 2a 72 65 73  sswd entry, *res
35c0: 75 6c 74 3b 0a 09 73 74 72 75 63 74 20 73 74 61  ult;..struct sta
35d0: 74 20 73 74 62 75 66 3b 0a 09 63 68 61 72 20 62  t stbuf;..char b
35e0: 75 66 5b 31 30 32 34 5d 2c 20 2a 72 65 74 76 61  uf[1024], *retva
35f0: 6c 3b 0a 09 69 6e 74 20 67 70 75 5f 72 65 74 2c  l;..int gpu_ret,
3600: 20 73 74 61 74 5f 72 65 74 3b 0a 0a 09 67 70 75   stat_ret;...gpu
3610: 5f 72 65 74 20 3d 20 67 65 74 70 77 75 69 64 5f  _ret = getpwuid_
3620: 72 28 66 73 75 69 64 2c 20 26 65 6e 74 72 79 2c  r(fsuid, &entry,
3630: 20 62 75 66 2c 20 73 69 7a 65 6f 66 28 62 75 66   buf, sizeof(buf
3640: 29 2c 20 26 72 65 73 75 6c 74 29 3b 0a 09 69 66  ), &result);..if
3650: 20 28 67 70 75 5f 72 65 74 20 21 3d 20 30 29 20   (gpu_ret != 0) 
3660: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
3670: 22 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c 75  "getpwuid_r(%llu
3680: 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64 20  , ...) returned 
3690: 69 6e 20 66 61 69 6c 75 72 65 22 2c 20 28 75 6e  in failure", (un
36a0: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
36b0: 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72 65 74  ) fsuid);....ret
36c0: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
36d0: 69 66 20 28 72 65 73 75 6c 74 20 3d 3d 20 4e 55  if (result == NU
36e0: 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  LL) {...APPFS_DE
36f0: 42 55 47 28 22 67 65 74 70 77 75 69 64 5f 72 28  BUG("getpwuid_r(
3700: 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 74 75 72  %llu, ...) retur
3710: 6e 65 64 20 4e 55 4c 4c 20 72 65 73 75 6c 74 22  ned NULL result"
3720: 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67  , (unsigned long
3730: 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b 0a 0a   long) fsuid);..
3740: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
3750: 09 7d 0a 0a 09 69 66 20 28 72 65 73 75 6c 74 2d  .}...if (result-
3760: 3e 70 77 5f 64 69 72 20 3d 3d 20 4e 55 4c 4c 29  >pw_dir == NULL)
3770: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
3780: 28 22 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c  ("getpwuid_r(%ll
3790: 75 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64  u, ...) returned
37a0: 20 4e 55 4c 4c 20 68 6f 6d 65 20 64 69 72 65 63   NULL home direc
37b0: 74 6f 72 79 22 2c 20 28 75 6e 73 69 67 6e 65 64  tory", (unsigned
37c0: 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69   long long) fsui
37d0: 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  d);....return(NU
37e0: 4c 4c 29 3b 0a 09 7d 0a 0a 09 73 74 61 74 5f 72  LL);..}...stat_r
37f0: 65 74 20 3d 20 73 74 61 74 28 72 65 73 75 6c 74  et = stat(result
3800: 2d 3e 70 77 5f 64 69 72 2c 20 26 73 74 62 75 66  ->pw_dir, &stbuf
3810: 29 3b 0a 09 69 66 20 28 73 74 61 74 5f 72 65 74  );..if (stat_ret
3820: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53   != 0) {...APPFS
3830: 5f 44 45 42 55 47 28 22 73 74 61 74 28 25 73 29  _DEBUG("stat(%s)
3840: 20 72 65 74 75 72 6e 65 64 20 69 6e 20 66 61 69   returned in fai
3850: 6c 75 72 65 22 2c 20 72 65 73 75 6c 74 2d 3e 70  lure", result->p
3860: 77 5f 64 69 72 29 3b 0a 0a 09 09 72 65 74 75 72  w_dir);....retur
3870: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66  n(NULL);..}...if
3880: 20 28 73 74 62 75 66 2e 73 74 5f 75 69 64 20 21   (stbuf.st_uid !
3890: 3d 20 66 73 75 69 64 29 20 7b 0a 09 09 41 50 50  = fsuid) {...APP
38a0: 46 53 5f 44 45 42 55 47 28 22 55 49 44 20 6d 69  FS_DEBUG("UID mi
38b0: 73 2d 6d 61 74 63 68 20 6f 6e 20 75 73 65 72 20  s-match on user 
38c0: 25 6c 6c 75 27 73 20 68 6f 6d 65 20 64 69 72 65  %llu's home dire
38d0: 63 74 6f 72 79 20 28 25 73 29 2e 20 20 49 74 27  ctory (%s).  It'
38e0: 73 20 6f 77 6e 65 64 20 62 79 20 25 6c 6c 75 2e  s owned by %llu.
38f0: 22 2c 0a 09 09 20 20 20 20 28 75 6e 73 69 67 6e  ",...    (unsign
3900: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73  ed long long) fs
3910: 75 69 64 2c 0a 09 09 20 20 20 20 72 65 73 75 6c  uid,...    resul
3920: 74 2d 3e 70 77 5f 64 69 72 2c 0a 09 09 20 20 20  t->pw_dir,...   
3930: 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20   (unsigned long 
3940: 6c 6f 6e 67 29 20 73 74 62 75 66 2e 73 74 5f 75  long) stbuf.st_u
3950: 69 64 0a 09 09 29 3b 0a 0a 09 09 72 65 74 75 72  id...);....retur
3960: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65  n(NULL);..}...re
3970: 74 76 61 6c 20 3d 20 73 74 72 64 75 70 28 72 65  tval = strdup(re
3980: 73 75 6c 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a  sult->pw_dir);..
3990: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
39a0: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 47 65 6e 65 72 61  .}../*. * Genera
39b0: 74 65 20 61 6e 20 69 6e 6f 64 65 20 66 6f 72 20  te an inode for 
39c0: 61 20 67 69 76 65 6e 20 70 61 74 68 2e 20 20 54  a given path.  T
39d0: 68 65 20 69 6e 6f 64 65 20 73 68 6f 75 6c 64 20  he inode should 
39e0: 62 65 20 63 6f 6d 70 75 74 65 64 20 69 6e 20 73  be computed in s
39f0: 75 63 68 0a 20 2a 20 61 20 77 61 79 20 74 68 61  uch. * a way tha
3a00: 74 20 69 74 20 69 73 20 75 6e 6c 69 6b 65 6c 79  t it is unlikely
3a10: 20 74 6f 20 62 65 20 64 75 70 6c 69 63 61 74 65   to be duplicate
3a20: 64 20 61 6e 64 20 72 65 6d 61 69 6e 73 20 74 68  d and remains th
3a30: 65 20 73 61 6d 65 20 66 6f 72 20 61 20 67 69 76  e same for a giv
3a40: 65 6e 0a 20 2a 20 66 69 6c 65 0a 20 2a 0a 20 2a  en. * file. *. *
3a50: 20 43 75 72 72 65 6e 74 20 69 6d 70 6c 65 6d 65   Current impleme
3a60: 6e 74 61 74 69 6f 6e 20 69 73 20 61 6e 20 46 4e  ntation is an FN
3a70: 56 2d 31 61 20 33 32 2d 62 69 74 0a 20 2a 2f 0a  V-1a 32-bit. */.
3a80: 23 69 66 20 55 49 4e 54 5f 4d 41 58 20 3c 20 34  #if UINT_MAX < 4
3a90: 32 39 34 39 36 37 32 39 35 0a 23 65 72 72 6f 72  294967295.#error
3aa0: 20 49 6e 74 65 67 65 72 20 73 69 7a 65 20 69 73   Integer size is
3ab0: 20 74 6f 6f 20 73 6d 61 6c 6c 20 0a 23 65 6e 64   too small .#end
3ac0: 69 66 0a 73 74 61 74 69 63 20 75 6e 73 69 67 6e  if.static unsign
3ad0: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 20 61 70 70  ed long long app
3ae0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64  fs_get_path_inod
3af0: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  e(const char *pa
3b00: 74 68 2c 20 69 6e 74 20 75 69 64 29 20 7b 0a 09  th, int uid) {..
3b10: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 72 65 74  unsigned int ret
3b20: 76 61 6c 3b 0a 09 63 6f 6e 73 74 20 75 6e 73 69  val;..const unsi
3b30: 67 6e 65 64 20 63 68 61 72 20 2a 70 3b 0a 0a 09  gned char *p;...
3b40: 72 65 74 76 61 6c 20 3d 20 32 31 36 36 31 33 36  retval = 2166136
3b50: 32 36 31 55 3b 20 2f 2a 20 46 4e 56 2d 31 61 20  261U; /* FNV-1a 
3b60: 33 32 2d 62 69 74 20 6f 66 66 73 65 74 5f 62 61  32-bit offset_ba
3b70: 73 69 73 20 2a 2f 0a 0a 09 66 6f 72 20 28 70 20  sis */...for (p 
3b80: 3d 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72  = (unsigned char
3b90: 20 2a 29 20 70 61 74 68 3b 20 2a 70 3b 20 70 2b   *) path; *p; p+
3ba0: 2b 29 20 7b 0a 09 09 72 65 74 76 61 6c 20 5e 3d  +) {...retval ^=
3bb0: 20 28 69 6e 74 29 20 2a 70 3b 0a 23 69 66 20 30   (int) *p;.#if 0
3bc0: 0a 09 09 72 65 74 76 61 6c 20 2a 3d 20 31 36 37  ...retval *= 167
3bd0: 37 37 36 31 39 3b 20 2f 2a 20 46 4e 56 2d 31 61  77619; /* FNV-1a
3be0: 20 33 32 2d 62 69 74 20 70 72 69 6d 65 20 2a 2f   32-bit prime */
3bf0: 0a 23 65 6c 73 65 0a 09 09 2f 2a 20 47 43 43 20  .#else.../* GCC 
3c00: 4f 70 74 69 6d 69 7a 65 64 20 72 65 70 6c 61 63  Optimized replac
3c10: 65 6d 65 6e 74 20 2a 2f 0a 09 09 72 65 74 76 61  ement */...retva
3c20: 6c 20 2b 3d 20 28 72 65 74 76 61 6c 20 3c 3c 20  l += (retval << 
3c30: 31 29 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20  1) + (retval << 
3c40: 34 29 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20  4) + (retval << 
3c50: 37 29 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20  7) + (retval << 
3c60: 38 29 20 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20  8) + (retval << 
3c70: 32 34 29 3b 0a 23 65 6e 64 69 66 0a 09 7d 0a 0a  24);.#endif..}..
3c80: 09 69 66 20 28 75 69 64 20 3e 3d 20 30 29 20 7b  .if (uid >= 0) {
3c90: 0a 09 09 72 65 74 76 61 6c 20 2b 3d 20 75 69 64  ...retval += uid
3ca0: 3b 0a 09 09 72 65 74 76 61 6c 2b 2b 3b 0a 09 7d  ;...retval++;..}
3cb0: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
3cc0: 4c 6f 6f 6b 65 64 20 75 70 20 69 6e 6f 64 65 20  Looked up inode 
3cd0: 6e 75 6d 62 65 72 20 66 6f 72 20 70 61 74 68 3d  number for path=
3ce0: 25 73 2c 75 69 64 3d 25 69 3a 20 25 75 22 2c 20  %s,uid=%i: %u", 
3cf0: 70 61 74 68 2c 20 75 69 64 2c 20 72 65 74 76 61  path, uid, retva
3d00: 6c 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65 74  l);...return(ret
3d10: 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43  val);.}../*. * C
3d20: 61 63 68 65 20 47 65 74 20 50 61 74 68 20 49 6e  ache Get Path In
3d30: 66 6f 20 6c 6f 6f 6b 75 70 73 20 66 6f 72 20 73  fo lookups for s
3d40: 70 65 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20  peed. */.static 
3d50: 69 6e 74 20 61 70 70 66 73 5f 67 65 74 5f 70 61  int appfs_get_pa
3d60: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 67 65  th_info_cache_ge
3d70: 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  t(const char *pa
3d80: 74 68 2c 20 75 69 64 5f 74 20 75 69 64 2c 20 73  th, uid_t uid, s
3d90: 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68  truct appfs_path
3da0: 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20  info *pathinfo) 
3db0: 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  {..unsigned int 
3dc0: 68 61 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70  hash_idx;..int p
3dd0: 74 68 72 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74  thread_ret;..int
3de0: 20 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61   retval;...retva
3df0: 6c 20 3d 20 31 3b 0a 0a 09 70 74 68 72 65 61 64  l = 1;...pthread
3e00: 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d  _ret = pthread_m
3e10: 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73  utex_lock(&appfs
3e20: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
3e30: 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74  _mutex);..if (pt
3e40: 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20  hread_ret != 0) 
3e50: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
3e60: 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20  "Unable to lock 
3e70: 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20  path_info cache 
3e80: 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65  mutex !");....re
3e90: 74 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 41  turn(-1);..}...A
3ea0: 50 50 46 53 5f 44 45 42 55 47 28 22 4c 6f 6f 6b  PPFS_DEBUG("Look
3eb0: 69 6e 67 20 75 70 20 63 61 63 68 65 20 65 6e 74  ing up cache ent
3ec0: 72 79 20 66 6f 72 20 70 61 74 68 3d 25 73 2c 75  ry for path=%s,u
3ed0: 69 64 3d 25 6c 6c 69 2e 2e 2e 22 2c 20 70 61 74  id=%lli...", pat
3ee0: 68 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75  h, (long long) u
3ef0: 69 64 29 3b 0a 0a 09 69 66 20 28 61 70 70 66 73  id);...if (appfs
3f00: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
3f10: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 61   != NULL) {...ha
3f20: 73 68 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f  sh_idx = (appfs_
3f30: 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70  get_path_inode(p
3f40: 61 74 68 2c 20 75 69 64 29 29 20 25 20 61 70 70  ath, uid)) % app
3f50: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
3f60: 68 65 5f 73 69 7a 65 3b 0a 0a 09 09 69 66 20 28  he_size;....if (
3f70: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
3f80: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
3f90: 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e  _cache_path != N
3fa0: 55 4c 4c 29 20 7b 0a 09 09 09 69 66 20 28 73 74  ULL) {....if (st
3fb0: 72 63 6d 70 28 61 70 70 66 73 5f 70 61 74 68 5f  rcmp(appfs_path_
3fc0: 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f  info_cache[hash_
3fd0: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68  idx]._cache_path
3fe0: 2c 20 70 61 74 68 29 20 3d 3d 20 30 20 26 26 20  , path) == 0 && 
3ff0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4000: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
4010: 5f 63 61 63 68 65 5f 75 69 64 20 3d 3d 20 75 69  _cache_uid == ui
4020: 64 29 20 7b 0a 09 09 09 09 72 65 74 76 61 6c 20  d) {.....retval 
4030: 3d 20 30 3b 0a 0a 09 09 09 09 6d 65 6d 63 70 79  = 0;......memcpy
4040: 28 70 61 74 68 69 6e 66 6f 2c 20 26 61 70 70 66  (pathinfo, &appf
4050: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4060: 65 5b 68 61 73 68 5f 69 64 78 5d 2c 20 73 69 7a  e[hash_idx], siz
4070: 65 6f 66 28 2a 70 61 74 68 69 6e 66 6f 29 29 3b  eof(*pathinfo));
4080: 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 5f  .....pathinfo->_
4090: 63 61 63 68 65 5f 70 61 74 68 20 3d 20 4e 55 4c  cache_path = NUL
40a0: 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a 0a  L;....}...}..}..
40b0: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
40c0: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c  thread_mutex_unl
40d0: 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f  ock(&appfs_path_
40e0: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
40f0: 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f  );..if (pthread_
4100: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ret != 0) {...AP
4110: 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c  PFS_DEBUG("Unabl
4120: 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68  e to unlock path
4130: 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65  _info cache mute
4140: 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  x !");....return
4150: 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 72  (-1);..}...if (r
4160: 65 74 76 61 6c 20 3d 3d 20 30 29 20 7b 0a 09 09  etval == 0) {...
4170: 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 61 63  APPFS_DEBUG("Cac
4180: 68 65 20 68 69 74 20 6f 6e 20 70 61 74 68 3d 25  he hit on path=%
4190: 73 2c 75 69 64 3d 25 6c 6c 69 22 2c 20 70 61 74  s,uid=%lli", pat
41a0: 68 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75  h, (long long) u
41b0: 69 64 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09  id);..} else {..
41c0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 61  .APPFS_DEBUG("Ca
41d0: 63 68 65 20 6d 69 73 73 20 6f 6e 20 70 61 74 68  che miss on path
41e0: 3d 25 73 2c 75 69 64 3d 25 6c 6c 69 22 2c 20 70  =%s,uid=%lli", p
41f0: 61 74 68 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29  ath, (long long)
4200: 20 75 69 64 29 3b 0a 09 7d 0a 0a 09 72 65 74 75   uid);..}...retu
4210: 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73  rn(retval);.}..s
4220: 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73  tatic void appfs
4230: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
4240: 61 63 68 65 5f 61 64 64 28 63 6f 6e 73 74 20 63  ache_add(const c
4250: 68 61 72 20 2a 70 61 74 68 2c 20 75 69 64 5f 74  har *path, uid_t
4260: 20 75 69 64 2c 20 73 74 72 75 63 74 20 61 70 70   uid, struct app
4270: 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61 74  fs_pathinfo *pat
4280: 68 69 6e 66 6f 29 20 7b 0a 09 75 6e 73 69 67 6e  hinfo) {..unsign
4290: 65 64 20 69 6e 74 20 68 61 73 68 5f 69 64 78 3b  ed int hash_idx;
42a0: 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65  ..int pthread_re
42b0: 74 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74  t;...pthread_ret
42c0: 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78   = pthread_mutex
42d0: 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74  _lock(&appfs_pat
42e0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74  h_info_cache_mut
42f0: 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61  ex);..if (pthrea
4300: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
4310: 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61  APPFS_DEBUG("Una
4320: 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68  ble to lock path
4330: 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65  _info cache mute
4340: 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  x !");....return
4350: 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73  ;..}...if (appfs
4360: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4370: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 61 70   == NULL) {...ap
4380: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4390: 63 68 65 20 3d 20 63 61 6c 6c 6f 63 28 61 70 70  che = calloc(app
43a0: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
43b0: 68 65 5f 73 69 7a 65 2c 20 73 69 7a 65 6f 66 28  he_size, sizeof(
43c0: 2a 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  *appfs_path_info
43d0: 5f 63 61 63 68 65 29 29 3b 0a 09 7d 0a 0a 09 68  _cache));..}...h
43e0: 61 73 68 5f 69 64 78 20 3d 20 28 61 70 70 66 73  ash_idx = (appfs
43f0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28  _get_path_inode(
4400: 70 61 74 68 2c 20 75 69 64 29 29 20 25 20 61 70  path, uid)) % ap
4410: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4420: 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 69 66 20 28  che_size;...if (
4430: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4440: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
4450: 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e  _cache_path != N
4460: 55 4c 4c 29 20 7b 0a 09 09 66 72 65 65 28 61 70  ULL) {...free(ap
4470: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4480: 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63  che[hash_idx]._c
4490: 61 63 68 65 5f 70 61 74 68 29 3b 0a 09 7d 0a 0a  ache_path);..}..
44a0: 09 6d 65 6d 63 70 79 28 26 61 70 70 66 73 5f 70  .memcpy(&appfs_p
44b0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68  ath_info_cache[h
44c0: 61 73 68 5f 69 64 78 5d 2c 20 70 61 74 68 69 6e  ash_idx], pathin
44d0: 66 6f 2c 20 73 69 7a 65 6f 66 28 2a 70 61 74 68  fo, sizeof(*path
44e0: 69 6e 66 6f 29 29 3b 0a 0a 09 61 70 70 66 73 5f  info));...appfs_
44f0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
4500: 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65  hash_idx]._cache
4510: 5f 70 61 74 68 20 3d 20 73 74 72 64 75 70 28 70  _path = strdup(p
4520: 61 74 68 29 3b 0a 09 61 70 70 66 73 5f 70 61 74  ath);..appfs_pat
4530: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73  h_info_cache[has
4540: 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 75 69  h_idx]._cache_ui
4550: 64 20 20 3d 20 75 69 64 3b 0a 0a 09 70 74 68 72  d  = uid;...pthr
4560: 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61  ead_ret = pthrea
4570: 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26  d_mutex_unlock(&
4580: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4590: 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69  cache_mutex);..i
45a0: 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21  f (pthread_ret !
45b0: 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  = 0) {...APPFS_D
45c0: 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20  EBUG("Unable to 
45d0: 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f  unlock path_info
45e0: 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22 29   cache mutex !")
45f0: 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a  ;....return;..}.
4600: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61  ..return;.}..sta
4610: 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 67  tic void appfs_g
4620: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
4630: 68 65 5f 72 6d 28 63 6f 6e 73 74 20 63 68 61 72  he_rm(const char
4640: 20 2a 70 61 74 68 2c 20 75 69 64 5f 74 20 75 69   *path, uid_t ui
4650: 64 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69  d) {..unsigned i
4660: 6e 74 20 68 61 73 68 5f 69 64 78 3b 0a 09 69 6e  nt hash_idx;..in
4670: 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a  t pthread_ret;..
4680: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
4690: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63  thread_mutex_loc
46a0: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  k(&appfs_path_in
46b0: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b  fo_cache_mutex);
46c0: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
46d0: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  t != 0) {...APPF
46e0: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20  S_DEBUG("Unable 
46f0: 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66  to lock path_inf
4700: 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22  o cache mutex !"
4710: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d  );....return;..}
4720: 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70 61 74  ...if (appfs_pat
4730: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 21 3d 20  h_info_cache != 
4740: 4e 55 4c 4c 29 20 7b 0a 09 09 68 61 73 68 5f 69  NULL) {...hash_i
4750: 64 78 20 3d 20 28 61 70 70 66 73 5f 67 65 74 5f  dx = (appfs_get_
4760: 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74 68 2c  path_inode(path,
4770: 20 75 69 64 29 29 20 25 20 61 70 70 66 73 5f 70   uid)) % appfs_p
4780: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73  ath_info_cache_s
4790: 69 7a 65 3b 0a 0a 09 09 69 66 20 28 61 70 70 66  ize;....if (appf
47a0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
47b0: 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63  e[hash_idx]._cac
47c0: 68 65 5f 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29  he_path != NULL)
47d0: 20 7b 0a 09 09 09 66 72 65 65 28 61 70 70 66 73   {....free(appfs
47e0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
47f0: 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68  [hash_idx]._cach
4800: 65 5f 70 61 74 68 29 3b 0a 0a 09 09 09 61 70 70  e_path);.....app
4810: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4820: 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61  he[hash_idx]._ca
4830: 63 68 65 5f 70 61 74 68 20 3d 20 4e 55 4c 4c 3b  che_path = NULL;
4840: 0a 09 09 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61  ...}..}...pthrea
4850: 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f  d_ret = pthread_
4860: 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70  mutex_unlock(&ap
4870: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4880: 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20  che_mutex);..if 
4890: 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20  (pthread_ret != 
48a0: 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  0) {...APPFS_DEB
48b0: 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e  UG("Unable to un
48c0: 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63  lock path_info c
48d0: 61 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a  ache mutex !");.
48e0: 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09  ...return;..}...
48f0: 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69  return;.}..stati
4900: 63 20 76 6f 69 64 20 61 70 70 66 73 5f 67 65 74  c void appfs_get
4910: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4920: 5f 66 6c 75 73 68 28 75 69 64 5f 74 20 75 69 64  _flush(uid_t uid
4930: 2c 20 69 6e 74 20 6e 65 77 5f 73 69 7a 65 29 20  , int new_size) 
4940: 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  {..unsigned int 
4950: 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 61  idx;..int pthrea
4960: 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  d_ret;...APPFS_D
4970: 45 42 55 47 28 22 46 6c 75 73 68 69 6e 67 20 41  EBUG("Flushing A
4980: 70 70 46 53 20 63 61 63 68 65 20 28 75 69 64 20  ppFS cache (uid 
4990: 3d 20 25 6c 6c 69 2c 20 6e 65 77 5f 73 69 7a 65  = %lli, new_size
49a0: 20 3d 20 25 69 29 22 2c 20 28 6c 6f 6e 67 20 6c   = %i)", (long l
49b0: 6f 6e 67 29 20 75 69 64 2c 20 6e 65 77 5f 73 69  ong) uid, new_si
49c0: 7a 65 29 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72  ze);...pthread_r
49d0: 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74  et = pthread_mut
49e0: 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70  ex_lock(&appfs_p
49f0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d  ath_info_cache_m
4a00: 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72  utex);..if (pthr
4a10: 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  ead_ret != 0) {.
4a20: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55  ..APPFS_DEBUG("U
4a30: 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61  nable to lock pa
4a40: 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75  th_info cache mu
4a50: 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75  tex !");....retu
4a60: 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70  rn;..}...if (app
4a70: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4a80: 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  he != NULL) {...
4a90: 66 6f 72 20 28 69 64 78 20 3d 20 30 3b 20 69 64  for (idx = 0; id
4aa0: 78 20 3c 20 61 70 70 66 73 5f 70 61 74 68 5f 69  x < appfs_path_i
4ab0: 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 20  nfo_cache_size; 
4ac0: 69 64 78 2b 2b 29 20 7b 0a 09 09 09 69 66 20 28  idx++) {....if (
4ad0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4ae0: 63 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68  cache[idx]._cach
4af0: 65 5f 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20  e_path != NULL) 
4b00: 7b 0a 09 09 09 09 69 66 20 28 75 69 64 20 21 3d  {.....if (uid !=
4b10: 20 28 28 75 69 64 5f 74 29 20 2d 31 29 29 20 7b   ((uid_t) -1)) {
4b20: 0a 09 09 09 09 09 69 66 20 28 61 70 70 66 73 5f  ......if (appfs_
4b30: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
4b40: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64 20  idx]._cache_uid 
4b50: 21 3d 20 75 69 64 29 20 7b 0a 09 09 09 09 09 09  != uid) {.......
4b60: 63 6f 6e 74 69 6e 75 65 3b 0a 09 09 09 09 09 7d  continue;......}
4b70: 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66 72 65 65  .....}......free
4b80: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  (appfs_path_info
4b90: 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63  _cache[idx]._cac
4ba0: 68 65 5f 70 61 74 68 29 3b 0a 0a 09 09 09 09 61  he_path);......a
4bb0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4bc0: 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65  ache[idx]._cache
4bd0: 5f 70 61 74 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09  _path = NULL;...
4be0: 09 7d 0a 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 28  .}...}..}...if (
4bf0: 75 69 64 20 3d 3d 20 28 28 75 69 64 5f 74 29 20  uid == ((uid_t) 
4c00: 2d 31 29 29 20 7b 0a 09 09 66 72 65 65 28 61 70  -1)) {...free(ap
4c10: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4c20: 63 68 65 29 3b 0a 0a 09 09 61 70 70 66 73 5f 70  che);....appfs_p
4c30: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d  ath_info_cache =
4c40: 20 4e 55 4c 4c 3b 0a 0a 09 09 69 66 20 28 6e 65   NULL;....if (ne
4c50: 77 5f 73 69 7a 65 20 21 3d 20 2d 31 29 20 7b 0a  w_size != -1) {.
4c60: 09 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  ...appfs_path_in
4c70: 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 20 3d 20  fo_cache_size = 
4c80: 6e 65 77 5f 73 69 7a 65 3b 0a 09 09 7d 0a 09 7d  new_size;...}..}
4c90: 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d  ...pthread_ret =
4ca0: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75   pthread_mutex_u
4cb0: 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74  nlock(&appfs_pat
4cc0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74  h_info_cache_mut
4cd0: 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61  ex);..if (pthrea
4ce0: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
4cf0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61  APPFS_DEBUG("Una
4d00: 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61  ble to unlock pa
4d10: 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75  th_info cache mu
4d20: 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75  tex !");....retu
4d30: 72 6e 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b  rn;..}...return;
4d40: 0a 7d 0a 0a 2f 2a 20 47 65 74 20 69 6e 66 6f 72  .}../* Get infor
4d50: 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 61 20 70  mation about a p
4d60: 61 74 68 2c 20 61 6e 64 20 6f 70 74 69 6f 6e 61  ath, and optiona
4d70: 6c 6c 79 20 6c 69 73 74 20 63 68 69 6c 64 72 65  lly list childre
4d80: 6e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  n */.static int 
4d90: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
4da0: 6e 66 6f 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  nfo(const char *
4db0: 70 61 74 68 2c 20 73 74 72 75 63 74 20 61 70 70  path, struct app
4dc0: 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61 74  fs_pathinfo *pat
4dd0: 68 69 6e 66 6f 29 20 7b 0a 09 54 63 6c 5f 49 6e  hinfo) {..Tcl_In
4de0: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 54  terp *interp;..T
4df0: 63 6c 5f 4f 62 6a 20 2a 61 74 74 72 73 5f 64 69  cl_Obj *attrs_di
4e00: 63 74 2c 20 2a 61 74 74 72 5f 76 61 6c 75 65 3b  ct, *attr_value;
4e10: 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 74  ..const char *at
4e20: 74 72 5f 76 61 6c 75 65 5f 73 74 72 2c 20 2a 61  tr_value_str, *a
4e30: 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 3b  ttr_value_str_i;
4e40: 0a 09 54 63 6c 5f 57 69 64 65 49 6e 74 20 61 74  ..Tcl_WideInt at
4e50: 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09  tr_value_wide;..
4e60: 69 6e 74 20 61 74 74 72 5f 76 61 6c 75 65 5f 69  int attr_value_i
4e70: 6e 74 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68  nt;..static __th
4e80: 72 65 61 64 20 54 63 6c 5f 4f 62 6a 20 2a 61 74  read Tcl_Obj *at
4e90: 74 72 5f 6b 65 79 5f 74 79 70 65 20 3d 20 4e 55  tr_key_type = NU
4ea0: 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 70 65  LL, *attr_key_pe
4eb0: 72 6d 73 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74  rms = NULL, *att
4ec0: 72 5f 6b 65 79 5f 73 69 7a 65 20 3d 20 4e 55 4c  r_key_size = NUL
4ed0: 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 74 69 6d  L, *attr_key_tim
4ee0: 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f  e = NULL, *attr_
4ef0: 6b 65 79 5f 73 6f 75 72 63 65 20 3d 20 4e 55 4c  key_source = NUL
4f00: 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 63 68 69  L, *attr_key_chi
4f10: 6c 64 63 6f 75 6e 74 20 3d 20 4e 55 4c 4c 2c 20  ldcount = NULL, 
4f20: 2a 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67  *attr_key_packag
4f30: 65 64 20 3d 20 4e 55 4c 4c 3b 0a 09 69 6e 74 20  ed = NULL;..int 
4f40: 63 61 63 68 65 5f 72 65 74 3b 0a 09 69 6e 74 20  cache_ret;..int 
4f50: 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65  tcl_ret;..int re
4f60: 74 76 61 6c 3b 0a 09 75 69 64 5f 74 20 66 73 75  tval;..uid_t fsu
4f70: 69 64 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 30  id;...retval = 0
4f80: 3b 0a 0a 09 66 73 75 69 64 20 3d 20 61 70 70 66  ;...fsuid = appf
4f90: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 0a  s_get_fsuid();..
4fa0: 09 63 61 63 68 65 5f 72 65 74 20 3d 20 61 70 70  .cache_ret = app
4fb0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
4fc0: 5f 63 61 63 68 65 5f 67 65 74 28 70 61 74 68 2c  _cache_get(path,
4fd0: 20 66 73 75 69 64 2c 20 70 61 74 68 69 6e 66 6f   fsuid, pathinfo
4fe0: 29 3b 0a 09 69 66 20 28 63 61 63 68 65 5f 72 65  );..if (cache_re
4ff0: 74 20 3d 3d 20 30 29 20 7b 0a 09 09 69 66 20 28  t == 0) {...if (
5000: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d  pathinfo->type =
5010: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  = APPFS_PATHTYPE
5020: 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 29  _DOES_NOT_EXIST)
5030: 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55   {....APPFS_DEBU
5040: 47 28 22 52 65 74 75 72 6e 69 6e 67 20 66 72 6f  G("Returning fro
5050: 6d 20 63 61 63 68 65 3a 20 64 6f 65 73 20 6e 6f  m cache: does no
5060: 74 20 65 78 69 73 74 20 5c 22 25 73 5c 22 22 2c  t exist \"%s\"",
5070: 20 70 61 74 68 29 3b 0a 0a 09 09 09 72 65 74 75   path);.....retu
5080: 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09 09 7d  rn(-ENOENT);...}
5090: 0a 0a 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f  ....if (pathinfo
50a0: 2d 3e 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f  ->type == APPFS_
50b0: 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44  PATHTYPE_INVALID
50c0: 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42  ) {....APPFS_DEB
50d0: 55 47 28 22 52 65 74 75 72 6e 69 6e 67 20 66 72  UG("Returning fr
50e0: 6f 6d 20 63 61 63 68 65 3a 20 69 6e 76 61 6c 69  om cache: invali
50f0: 64 20 6f 62 6a 65 63 74 20 5c 22 25 73 5c 22 22  d object \"%s\""
5100: 2c 20 70 61 74 68 29 3b 0a 0a 09 09 09 72 65 74  , path);.....ret
5110: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 09 7d 0a 0a  urn(-EIO);...}..
5120: 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a  ..return(0);..}.
5130: 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
5140: 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69  _TclInterp();..i
5150: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
5160: 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  L) {...APPFS_DEB
5170: 55 47 28 22 65 72 72 6f 72 3a 20 55 6e 61 62 6c  UG("error: Unabl
5180: 65 20 74 6f 20 67 65 74 20 61 6e 20 69 6e 74 65  e to get an inte
5190: 72 70 72 65 74 65 72 22 29 3b 0a 0a 09 09 72 65  rpreter");....re
51a0: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
51b0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
51c0: 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28  cl(Tcl_Preserve(
51d0: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f  interp);)...tcl_
51e0: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
51f0: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20  Eval(interp, 2, 
5200: 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61 74 74  "::appfs::getatt
5210: 72 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28  r", path);..if (
5220: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
5230: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
5240: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74  UG("::appfs::get
5250: 61 74 74 72 28 25 73 29 20 66 61 69 6c 65 64 2e  attr(%s) failed.
5260: 22 2c 20 70 61 74 68 29 3b 0a 09 09 61 70 70 66  ", path);...appf
5270: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
5280: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
5290: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22  cl Error is: %s"
52a0: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
52b0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
52c0: 09 09 29 0a 0a 09 09 70 61 74 68 69 6e 66 6f 2d  ..)....pathinfo-
52d0: 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41  >type = APPFS_PA
52e0: 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f  THTYPE_DOES_NOT_
52f0: 45 58 49 53 54 3b 0a 0a 09 09 61 70 70 66 73 5f  EXIST;....appfs_
5300: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
5310: 63 68 65 5f 61 64 64 28 70 61 74 68 2c 20 66 73  che_add(path, fs
5320: 75 69 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a  uid, pathinfo);.
5330: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
5340: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
5350: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65  (interp);)....re
5360: 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09  turn(-ENOENT);..
5370: 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 6b 65 79  }...if (attr_key
5380: 5f 74 79 70 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _type == NULL) {
5390: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
53a0: 62 74 63 6c 28 0a 09 09 09 61 74 74 72 5f 6b 65  btcl(....attr_ke
53b0: 79 5f 74 79 70 65 20 20 20 20 20 20 20 3d 20 54  y_type       = T
53c0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
53d0: 22 74 79 70 65 22 2c 20 2d 31 29 3b 0a 09 09 09  "type", -1);....
53e0: 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20 20  attr_key_perms  
53f0: 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72      = Tcl_NewStr
5400: 69 6e 67 4f 62 6a 28 22 70 65 72 6d 73 22 2c 20  ingObj("perms", 
5410: 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79  -1);....attr_key
5420: 5f 73 69 7a 65 20 20 20 20 20 20 20 3d 20 54 63  _size       = Tc
5430: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
5440: 73 69 7a 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61  size", -1);....a
5450: 74 74 72 5f 6b 65 79 5f 74 69 6d 65 20 20 20 20  ttr_key_time    
5460: 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69     = Tcl_NewStri
5470: 6e 67 4f 62 6a 28 22 74 69 6d 65 22 2c 20 2d 31  ngObj("time", -1
5480: 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 73  );....attr_key_s
5490: 6f 75 72 63 65 20 20 20 20 20 3d 20 54 63 6c 5f  ource     = Tcl_
54a0: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 73 6f  NewStringObj("so
54b0: 75 72 63 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61  urce", -1);....a
54c0: 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75  ttr_key_childcou
54d0: 6e 74 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69  nt = Tcl_NewStri
54e0: 6e 67 4f 62 6a 28 22 63 68 69 6c 64 63 6f 75 6e  ngObj("childcoun
54f0: 74 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72  t", -1);....attr
5500: 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 20 20 20  _key_packaged   
5510: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
5520: 62 6a 28 22 70 61 63 6b 61 67 65 64 22 2c 20 2d  bj("packaged", -
5530: 31 29 3b 0a 0a 09 09 09 54 63 6c 5f 49 6e 63 72  1);.....Tcl_Incr
5540: 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65  RefCount(attr_ke
5550: 79 5f 74 79 70 65 29 3b 0a 09 09 09 54 63 6c 5f  y_type);....Tcl_
5560: 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74  IncrRefCount(att
5570: 72 5f 6b 65 79 5f 70 65 72 6d 73 29 3b 0a 09 09  r_key_perms);...
5580: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
5590: 74 28 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 29  t(attr_key_size)
55a0: 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66  ;....Tcl_IncrRef
55b0: 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 74  Count(attr_key_t
55c0: 69 6d 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63  ime);....Tcl_Inc
55d0: 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b  rRefCount(attr_k
55e0: 65 79 5f 73 6f 75 72 63 65 29 3b 0a 09 09 09 54  ey_source);....T
55f0: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
5600: 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f  attr_key_childco
5610: 75 6e 74 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63  unt);....Tcl_Inc
5620: 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b  rRefCount(attr_k
5630: 65 79 5f 70 61 63 6b 61 67 65 64 29 3b 0a 09 09  ey_packaged);...
5640: 29 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  )..}...appfs_cal
5650: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 61 74 74 72  l_libtcl(...attr
5660: 73 5f 64 69 63 74 20 3d 20 54 63 6c 5f 47 65 74  s_dict = Tcl_Get
5670: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
5680: 29 3b 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54  );...tcl_ret = T
5690: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
56a0: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
56b0: 2c 20 61 74 74 72 5f 6b 65 79 5f 74 79 70 65 2c  , attr_key_type,
56c0: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
56d0: 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  )..if (tcl_ret !
56e0: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50  = TCL_OK) {...AP
56f0: 50 46 53 5f 44 45 42 55 47 28 22 5b 64 69 63 74  PFS_DEBUG("[dict
5700: 20 67 65 74 20 5c 22 74 79 70 65 5c 22 5d 20 66   get \"type\"] f
5710: 61 69 6c 65 64 22 29 3b 0a 09 09 61 70 70 66 73  ailed");...appfs
5720: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
5730: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63  .APPFS_DEBUG("Tc
5740: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c  l Error is: %s",
5750: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
5760: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09  sult(interp));..
5770: 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  .)....appfs_call
5780: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
5790: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
57a0: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
57b0: 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 76 61 6c  }...if (attr_val
57c0: 75 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  ue == NULL) {...
57d0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72  APPFS_DEBUG("err
57e0: 6f 72 3a 20 55 6e 61 62 6c 65 20 74 6f 20 67 65  or: Unable to ge
57f0: 74 20 74 79 70 65 20 66 6f 72 20 5c 22 25 73 5c  t type for \"%s\
5800: 22 20 66 72 6f 6d 20 54 63 6c 22 2c 20 70 61 74  " from Tcl", pat
5810: 68 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c  h);....appfs_cal
5820: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
5830: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
5840: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
5850: 09 7d 0a 0a 09 70 61 74 68 69 6e 66 6f 2d 3e 70  .}...pathinfo->p
5860: 61 63 6b 61 67 65 64 20 3d 20 30 3b 0a 0a 09 61  ackaged = 0;...a
5870: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
5880: 28 0a 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73  (...attr_value_s
5890: 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  tr = Tcl_GetStri
58a0: 6e 67 28 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a  ng(attr_value);.
58b0: 0a 09 09 73 77 69 74 63 68 20 28 61 74 74 72 5f  ...switch (attr_
58c0: 76 61 6c 75 65 5f 73 74 72 5b 30 5d 29 20 7b 0a  value_str[0]) {.
58d0: 09 09 09 63 61 73 65 20 27 64 27 3a 20 2f 2a 20  ...case 'd': /* 
58e0: 64 69 72 65 63 74 6f 72 79 20 2a 2f 0a 09 09 09  directory */....
58f0: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20  .pathinfo->type 
5900: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  = APPFS_PATHTYPE
5910: 5f 44 49 52 45 43 54 4f 52 59 3b 0a 09 09 09 09  _DIRECTORY;.....
5920: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
5930: 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e  fo.dir.childcoun
5940: 74 20 3d 20 30 3b 0a 0a 09 09 09 09 54 63 6c 5f  t = 0;......Tcl_
5950: 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72  DictObjGet(inter
5960: 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61  p, attrs_dict, a
5970: 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75  ttr_key_childcou
5980: 6e 74 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29  nt, &attr_value)
5990: 3b 0a 09 09 09 09 69 66 20 28 61 74 74 72 5f 76  ;.....if (attr_v
59a0: 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  alue != NULL) {.
59b0: 09 09 09 09 09 74 63 6c 5f 72 65 74 20 3d 20 54  .....tcl_ret = T
59c0: 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f  cl_GetWideIntFro
59d0: 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f  mObj(NULL, attr_
59e0: 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c  value, &attr_val
59f0: 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 09 09 69  ue_wide);......i
5a00: 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43  f (tcl_ret == TC
5a10: 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 09 70 61  L_OK) {.......pa
5a20: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
5a30: 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20  .dir.childcount 
5a40: 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64  = attr_value_wid
5a50: 65 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a  e;......}.....}.
5a60: 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63  .....break;....c
5a70: 61 73 65 20 27 66 27 3a 20 2f 2a 20 66 69 6c 65  ase 'f': /* file
5a80: 20 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f   */.....pathinfo
5a90: 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50  ->type = APPFS_P
5aa0: 41 54 48 54 59 50 45 5f 46 49 4c 45 3b 0a 09 09  ATHTYPE_FILE;...
5ab0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
5ac0: 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 3d  info.file.size =
5ad0: 20 30 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f   0;.....pathinfo
5ae0: 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e  ->typeinfo.file.
5af0: 65 78 65 63 75 74 61 62 6c 65 20 3d 20 30 3b 0a  executable = 0;.
5b00: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
5b10: 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 75 69 64  peinfo.file.suid
5b20: 52 6f 6f 74 20 3d 20 30 3b 0a 09 09 09 09 70 61  Root = 0;.....pa
5b30: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
5b40: 2e 66 69 6c 65 2e 77 6f 72 6c 64 61 63 63 65 73  .file.worldacces
5b50: 73 69 62 6c 65 20 3d 20 30 3b 0a 0a 09 09 09 09  sible = 0;......
5b60: 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69  Tcl_DictObjGet(i
5b70: 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63  nterp, attrs_dic
5b80: 74 2c 20 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65  t, attr_key_size
5b90: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a  , &attr_value);.
5ba0: 09 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c  ....if (attr_val
5bb0: 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  ue != NULL) {...
5bc0: 09 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
5bd0: 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f  _GetWideIntFromO
5be0: 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61  bj(NULL, attr_va
5bf0: 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  lue, &attr_value
5c00: 5f 77 69 64 65 29 3b 0a 09 09 09 09 09 69 66 20  _wide);......if 
5c10: 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f  (tcl_ret == TCL_
5c20: 4f 4b 29 20 7b 0a 09 09 09 09 09 09 70 61 74 68  OK) {.......path
5c30: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66  info->typeinfo.f
5c40: 69 6c 65 2e 73 69 7a 65 20 3d 20 61 74 74 72 5f  ile.size = attr_
5c50: 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09 09  value_wide;.....
5c60: 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 09 54 63  .}.....}......Tc
5c70: 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74  l_DictObjGet(int
5c80: 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c  erp, attrs_dict,
5c90: 20 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 2c   attr_key_perms,
5ca0: 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09   &attr_value);..
5cb0: 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75  ...if (attr_valu
5cc0: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  e != NULL) {....
5cd0: 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72  ..attr_value_str
5ce0: 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67   = Tcl_GetString
5cf0: 28 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09  (attr_value);...
5d00: 09 09 09 66 6f 72 20 28 61 74 74 72 5f 76 61 6c  ...for (attr_val
5d10: 75 65 5f 73 74 72 5f 69 20 3d 20 26 61 74 74 72  ue_str_i = &attr
5d20: 5f 76 61 6c 75 65 5f 73 74 72 5b 30 5d 3b 20 2a  _value_str[0]; *
5d30: 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69  attr_value_str_i
5d40: 20 21 3d 20 27 5c 30 27 3b 20 61 74 74 72 5f 76   != '\0'; attr_v
5d50: 61 6c 75 65 5f 73 74 72 5f 69 2b 2b 29 20 7b 0a  alue_str_i++) {.
5d60: 09 09 09 09 09 09 73 77 69 74 63 68 20 28 2a 61  ......switch (*a
5d70: 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 29  ttr_value_str_i)
5d80: 20 7b 0a 09 09 09 09 09 09 09 63 61 73 65 20 27   {........case '
5d90: 78 27 3a 0a 09 09 09 09 09 09 09 09 70 61 74 68  x':.........path
5da0: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66  info->typeinfo.f
5db0: 69 6c 65 2e 65 78 65 63 75 74 61 62 6c 65 20 3d  ile.executable =
5dc0: 20 31 3b 0a 0a 09 09 09 09 09 09 09 09 62 72 65   1;..........bre
5dd0: 61 6b 3b 0a 09 09 09 09 09 09 09 63 61 73 65 20  ak;........case 
5de0: 27 55 27 3a 0a 09 09 09 09 09 09 09 09 70 61 74  'U':.........pat
5df0: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
5e00: 66 69 6c 65 2e 73 75 69 64 52 6f 6f 74 20 3d 20  file.suidRoot = 
5e10: 31 3b 0a 0a 09 09 09 09 09 09 09 09 62 72 65 61  1;..........brea
5e20: 6b 3b 0a 09 09 09 09 09 09 09 63 61 73 65 20 27  k;........case '
5e30: 2d 27 3a 0a 09 09 09 09 09 09 09 09 70 61 74 68  -':.........path
5e40: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66  info->typeinfo.f
5e50: 69 6c 65 2e 77 6f 72 6c 64 61 63 63 65 73 73 69  ile.worldaccessi
5e60: 62 6c 65 20 3d 20 31 3b 0a 0a 09 09 09 09 09 09  ble = 1;........
5e70: 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 09 09 7d  ..break;.......}
5e80: 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 09 09  ......}.....}...
5e90: 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65  ..break;....case
5ea0: 20 27 73 27 3a 20 2f 2a 20 73 79 6d 6c 69 6e 6b   's': /* symlink
5eb0: 20 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f   */.....pathinfo
5ec0: 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50  ->type = APPFS_P
5ed0: 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3b  ATHTYPE_SYMLINK;
5ee0: 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
5ef0: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e  ypeinfo.symlink.
5f00: 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 09 70 61  size = 0;.....pa
5f10: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
5f20: 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b  .symlink.source[
5f30: 30 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09 09 09 09  0] = '\0';......
5f40: 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69  Tcl_DictObjGet(i
5f50: 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63  nterp, attrs_dic
5f60: 74 2c 20 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72  t, attr_key_sour
5f70: 63 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29  ce, &attr_value)
5f80: 3b 0a 09 09 09 09 69 66 20 28 61 74 74 72 5f 76  ;.....if (attr_v
5f90: 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  alue != NULL) {.
5fa0: 09 09 09 09 09 61 74 74 72 5f 76 61 6c 75 65 5f  .....attr_value_
5fb0: 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  str = Tcl_GetStr
5fc0: 69 6e 67 46 72 6f 6d 4f 62 6a 28 61 74 74 72 5f  ingFromObj(attr_
5fd0: 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c  value, &attr_val
5fe0: 75 65 5f 69 6e 74 29 3b 20 0a 0a 09 09 09 09 09  ue_int); .......
5ff0: 69 66 20 28 28 61 74 74 72 5f 76 61 6c 75 65 5f  if ((attr_value_
6000: 69 6e 74 20 2b 20 31 29 20 3c 3d 20 73 69 7a 65  int + 1) <= size
6010: 6f 66 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  of(pathinfo->typ
6020: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f  einfo.symlink.so
6030: 75 72 63 65 29 29 20 7b 0a 09 09 09 09 09 09 70  urce)) {.......p
6040: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
6050: 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d  o.symlink.size =
6060: 20 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b   attr_value_int;
6070: 0a 09 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  .......pathinfo-
6080: 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e  >typeinfo.symlin
6090: 6b 2e 73 6f 75 72 63 65 5b 61 74 74 72 5f 76 61  k.source[attr_va
60a0: 6c 75 65 5f 69 6e 74 5d 20 3d 20 27 5c 30 27 3b  lue_int] = '\0';
60b0: 0a 0a 09 09 09 09 09 09 6d 65 6d 63 70 79 28 70  ........memcpy(p
60c0: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
60d0: 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65  o.symlink.source
60e0: 2c 20 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72  , attr_value_str
60f0: 2c 20 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74  , attr_value_int
6100: 29 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a  );......}.....}.
6110: 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61  ....break;....ca
6120: 73 65 20 27 46 27 3a 20 2f 2a 20 70 69 70 65 2f  se 'F': /* pipe/
6130: 66 69 66 6f 20 2a 2f 0a 09 09 09 09 70 61 74 68  fifo */.....path
6140: 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50  info->type = APP
6150: 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f  FS_PATHTYPE_FIFO
6160: 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09  ;.....break;....
6170: 63 61 73 65 20 27 53 27 3a 20 2f 2a 20 55 4e 49  case 'S': /* UNI
6180: 58 20 64 6f 6d 61 69 6e 20 73 6f 63 6b 65 74 20  X domain socket 
6190: 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  */.....pathinfo-
61a0: 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41  >type = APPFS_PA
61b0: 54 48 54 59 50 45 5f 53 4f 43 4b 45 54 3b 0a 09  THTYPE_SOCKET;..
61c0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 64 65 66  ...break;....def
61d0: 61 75 6c 74 3a 0a 09 09 09 09 72 65 74 76 61 6c  ault:.....retval
61e0: 20 3d 20 2d 45 49 4f 3b 0a 09 09 7d 0a 0a 09 09   = -EIO;...}....
61f0: 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69  Tcl_DictObjGet(i
6200: 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63  nterp, attrs_dic
6210: 74 2c 20 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b  t, attr_key_pack
6220: 61 67 65 64 2c 20 26 61 74 74 72 5f 76 61 6c 75  aged, &attr_valu
6230: 65 29 3b 0a 09 09 69 66 20 28 61 74 74 72 5f 76  e);...if (attr_v
6240: 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  alue != NULL) {.
6250: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63  ...pathinfo->pac
6260: 6b 61 67 65 64 20 3d 20 31 3b 0a 09 09 7d 0a 0a  kaged = 1;...}..
6270: 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74  ..Tcl_DictObjGet
6280: 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64  (interp, attrs_d
6290: 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74 69  ict, attr_key_ti
62a0: 6d 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29  me, &attr_value)
62b0: 3b 0a 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c  ;...if (attr_val
62c0: 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  ue != NULL) {...
62d0: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47  .tcl_ret = Tcl_G
62e0: 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a  etWideIntFromObj
62f0: 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75  (NULL, attr_valu
6300: 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77  e, &attr_value_w
6310: 69 64 65 29 3b 0a 09 09 09 69 66 20 28 74 63 6c  ide);....if (tcl
6320: 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20  _ret == TCL_OK) 
6330: 7b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  {.....pathinfo->
6340: 74 69 6d 65 20 3d 20 61 74 74 72 5f 76 61 6c 75  time = attr_valu
6350: 65 5f 77 69 64 65 3b 0a 09 09 09 7d 0a 09 09 7d  e_wide;....}...}
6360: 20 65 6c 73 65 20 7b 0a 09 09 09 70 61 74 68 69   else {....pathi
6370: 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20 61 70 70 66  nfo->time = appf
6380: 73 5f 62 6f 6f 74 74 69 6d 65 3b 0a 09 09 7d 0a  s_boottime;...}.
6390: 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69  ...Tcl_Release(i
63a0: 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 69 66 20  nterp);..)...if 
63b0: 28 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61  (pathinfo->packa
63c0: 67 65 64 29 20 7b 0a 09 09 70 61 74 68 69 6e 66  ged) {...pathinf
63d0: 6f 2d 3e 69 6e 6f 64 65 20 3d 20 61 70 70 66 73  o->inode = appfs
63e0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28  _get_path_inode(
63f0: 70 61 74 68 2c 20 2d 31 29 3b 0a 09 7d 20 65 6c  path, -1);..} el
6400: 73 65 20 7b 0a 09 09 70 61 74 68 69 6e 66 6f 2d  se {...pathinfo-
6410: 3e 69 6e 6f 64 65 20 3d 20 61 70 70 66 73 5f 67  >inode = appfs_g
6420: 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61  et_path_inode(pa
6430: 74 68 2c 20 66 73 75 69 64 29 3b 0a 09 7d 0a 0a  th, fsuid);..}..
6440: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 61  .APPFS_DEBUG("Ca
6450: 63 68 69 6e 67 20 69 6e 6f 64 65 20 66 6f 72 20  ching inode for 
6460: 70 61 74 68 3d 25 73 2c 75 69 64 3d 25 6c 6c 69  path=%s,uid=%lli
6470: 20 61 73 20 25 6c 6c 75 20 28 70 61 63 6b 61 67   as %llu (packag
6480: 65 64 20 3d 20 25 69 29 22 2c 20 70 61 74 68 2c  ed = %i)", path,
6490: 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75   (long long) fsu
64a0: 69 64 2c 20 70 61 74 68 69 6e 66 6f 2d 3e 69 6e  id, pathinfo->in
64b0: 6f 64 65 2c 20 70 61 74 68 69 6e 66 6f 2d 3e 70  ode, pathinfo->p
64c0: 61 63 6b 61 67 65 64 29 3b 0a 0a 09 69 66 20 28  ackaged);...if (
64d0: 72 65 74 76 61 6c 20 3d 3d 20 30 29 20 7b 0a 09  retval == 0) {..
64e0: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  .appfs_get_path_
64f0: 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64 64 28 70  info_cache_add(p
6500: 61 74 68 2c 20 66 73 75 69 64 2c 20 70 61 74 68  ath, fsuid, path
6510: 69 6e 66 6f 29 3b 0a 09 7d 20 65 6c 73 65 20 7b  info);..} else {
6520: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
6530: 65 72 72 6f 72 3a 20 49 6e 76 61 6c 69 64 20 74  error: Invalid t
6540: 79 70 65 20 66 6f 72 20 5c 22 25 73 5c 22 20 66  ype for \"%s\" f
6550: 72 6f 6d 20 54 63 6c 22 2c 20 70 61 74 68 29 3b  rom Tcl", path);
6560: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74  ..}...return(ret
6570: 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  val);.}..static 
6580: 63 68 61 72 20 2a 61 70 70 66 73 5f 70 72 65 70  char *appfs_prep
6590: 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 63 6f  are_to_create(co
65a0: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 29 20  nst char *path) 
65b0: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
65c0: 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68  nterp;..const ch
65d0: 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09  ar *real_path;..
65e0: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 61  int tcl_ret;...a
65f0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
6600: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 61  fo_cache_flush(a
6610: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
6620: 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74 65 72 70 20  , -1);...interp 
6630: 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72  = appfs_TclInter
6640: 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  p();..if (interp
6650: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
6660: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
6670: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
6680: 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28  cl(Tcl_Preserve(
6690: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 61 70 70 66  interp);)...appf
66a0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
66b0: 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73  .tcl_ret = appfs
66c0: 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70  _Tcl_Eval(interp
66d0: 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 70  , 2, "::appfs::p
66e0: 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65  repare_to_create
66f0: 22 2c 20 70 61 74 68 29 3b 0a 09 29 0a 09 69 66  ", path);..)..if
6700: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
6710: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
6720: 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 70  EBUG("::appfs::p
6730: 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65  repare_to_create
6740: 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70  (%s) failed.", p
6750: 61 74 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61  ath);...appfs_ca
6760: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50  ll_libtcl(....AP
6770: 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45  PFS_DEBUG("Tcl E
6780: 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63  rror is: %s", Tc
6790: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
67a0: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a  t(interp));...).
67b0: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
67c0: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
67d0: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65  (interp);)....re
67e0: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
67f0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
6800: 63 6c 28 0a 09 09 72 65 61 6c 5f 70 61 74 68 20  cl(...real_path 
6810: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  = Tcl_GetStringR
6820: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09  esult(interp);..
6830: 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  )...appfs_call_l
6840: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
6850: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 69 66  e(interp);)...if
6860: 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e   (real_path == N
6870: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
6880: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  NULL);..}...retu
6890: 72 6e 28 73 74 72 64 75 70 28 72 65 61 6c 5f 70  rn(strdup(real_p
68a0: 61 74 68 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  ath));.}..static
68b0: 20 63 68 61 72 20 2a 61 70 70 66 73 5f 6c 6f 63   char *appfs_loc
68c0: 61 6c 70 61 74 68 28 63 6f 6e 73 74 20 63 68 61  alpath(const cha
68d0: 72 20 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f  r *path) {..Tcl_
68e0: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
68f0: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61  .const char *rea
6900: 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c  l_path;..int tcl
6910: 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d  _ret;...interp =
6920: 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70   appfs_TclInterp
6930: 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  ();..if (interp 
6940: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
6950: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
6960: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
6970: 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69  l(Tcl_Preserve(i
6980: 6e 74 65 72 70 29 3b 29 0a 0a 09 61 70 70 66 73  nterp);)...appfs
6990: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
69a0: 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f  tcl_ret = appfs_
69b0: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
69c0: 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f   2, "::appfs::lo
69d0: 63 61 6c 70 61 74 68 22 2c 20 70 61 74 68 29 3b  calpath", path);
69e0: 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ..)..if (tcl_ret
69f0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
6a00: 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61  APPFS_DEBUG("::a
6a10: 70 70 66 73 3a 3a 6c 6f 63 61 6c 70 61 74 68 28  ppfs::localpath(
6a20: 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61  %s) failed.", pa
6a30: 74 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c  th);...appfs_cal
6a40: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50  l_libtcl(....APP
6a50: 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72  FS_DEBUG("Tcl Er
6a60: 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c  ror is: %s", Tcl
6a70: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
6a80: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a  (interp));...)..
6a90: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
6aa0: 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .}...appfs_call_
6ab0: 6c 69 62 74 63 6c 28 0a 09 09 72 65 61 6c 5f 70  libtcl(...real_p
6ac0: 61 74 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  ath = Tcl_GetStr
6ad0: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
6ae0: 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61  );..)...appfs_ca
6af0: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
6b00: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
6b10: 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20  ..if (real_path 
6b20: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
6b30: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
6b40: 72 65 74 75 72 6e 28 73 74 72 64 75 70 28 72 65  return(strdup(re
6b50: 61 6c 5f 70 61 74 68 29 29 3b 0a 7d 0a 0a 23 69  al_path));.}..#i
6b60: 66 20 28 64 65 66 69 6e 65 64 28 44 45 42 55 47  f (defined(DEBUG
6b70: 29 20 26 26 20 64 65 66 69 6e 65 64 28 41 50 50  ) && defined(APP
6b80: 46 53 5f 45 58 49 54 5f 50 41 54 48 29 29 20 7c  FS_EXIT_PATH)) |
6b90: 7c 20 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f  | defined(APPFS_
6ba0: 45 58 49 54 5f 50 41 54 48 5f 45 4e 41 42 4c 45  EXIT_PATH_ENABLE
6bb0: 5f 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f  _MAJOR_SECURITY_
6bc0: 48 4f 4c 45 29 0a 73 74 61 74 69 63 20 76 6f 69  HOLE).static voi
6bd0: 64 20 61 70 70 66 73 5f 65 78 69 74 28 76 6f 69  d appfs_exit(voi
6be0: 64 29 20 7b 0a 09 69 6e 74 20 67 6c 6f 62 61 6c  d) {..int global
6bf0: 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65  _interp_reset_ke
6c00: 79 3b 0a 0a 09 67 6c 6f 62 61 6c 5f 69 6e 74 65  y;...global_inte
6c10: 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 5f  rp_reset_key = _
6c20: 5f 73 79 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f  _sync_fetch_and_
6c30: 61 64 64 28 26 69 6e 74 65 72 70 5f 72 65 73 65  add(&interp_rese
6c40: 74 5f 6b 65 79 2c 20 30 29 3b 0a 09 5f 5f 73 79  t_key, 0);..__sy
6c50: 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 73 75 62  nc_fetch_and_sub
6c60: 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  (&interp_reset_k
6c70: 65 79 2c 20 67 6c 6f 62 61 6c 5f 69 6e 74 65 72  ey, global_inter
6c80: 70 5f 72 65 73 65 74 5f 6b 65 79 29 3b 0a 0a 09  p_reset_key);...
6c90: 77 68 69 6c 65 20 28 5f 5f 73 79 6e 63 5f 73 75  while (__sync_su
6ca0: 62 5f 61 6e 64 5f 66 65 74 63 68 28 26 69 6e 74  b_and_fetch(&int
6cb0: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 31  erp_reset_key, 1
6cc0: 29 20 3e 3d 20 30 29 20 7b 0a 09 09 2f 2a 20 42  ) >= 0) {.../* B
6cd0: 75 73 79 20 4c 6f 6f 70 20 2a 2f 0a 09 7d 0a 0a  usy Loop */..}..
6ce0: 09 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72  .global_interp_r
6cf0: 65 73 65 74 5f 6b 65 79 20 3d 20 5f 5f 73 79 6e  eset_key = __syn
6d00: 63 5f 66 65 74 63 68 5f 61 6e 64 5f 61 64 64 28  c_fetch_and_add(
6d10: 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65  &interp_reset_ke
6d20: 79 2c 20 30 29 3b 0a 09 69 66 20 28 67 6c 6f 62  y, 0);..if (glob
6d30: 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f  al_interp_reset_
6d40: 6b 65 79 20 21 3d 20 2d 31 29 20 7b 0a 09 09 41  key != -1) {...A
6d50: 50 50 46 53 5f 44 45 42 55 47 28 22 45 72 72 6f  PPFS_DEBUG("Erro
6d60: 72 20 73 65 6e 64 69 6e 67 20 6b 69 6c 6c 20 73  r sending kill s
6d70: 69 67 6e 61 6c 20 74 6f 20 61 6c 6c 20 74 68 72  ignal to all thr
6d80: 65 61 64 73 2c 20 61 62 6f 72 74 69 6e 67 20 61  eads, aborting a
6d90: 6e 79 77 61 79 2e 22 29 3b 0a 09 7d 0a 0a 09 61  nyway.");..}...a
6da0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
6db0: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d  fo_cache_flush(-
6dc0: 31 2c 20 2d 31 29 3b 0a 0a 09 66 75 73 65 5f 65  1, -1);...fuse_e
6dd0: 78 69 74 28 66 75 73 65 5f 67 65 74 5f 63 6f 6e  xit(fuse_get_con
6de0: 74 65 78 74 28 29 2d 3e 66 75 73 65 29 3b 0a 0a  text()->fuse);..
6df0: 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 23 65 6e 64  .return;.}..#end
6e00: 69 66 0a 0a 23 69 66 20 64 65 66 69 6e 65 64 28  if..#if defined(
6e10: 41 50 50 46 53 5f 45 58 45 43 5f 50 41 54 48 5f  APPFS_EXEC_PATH_
6e20: 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f 53 45 43  ENABLE_MAJOR_SEC
6e30: 55 52 49 54 59 5f 48 4f 4c 45 29 0a 73 74 61 74  URITY_HOLE).stat
6e40: 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 72 75  ic void appfs_ru
6e50: 6e 54 63 6c 28 63 6f 6e 73 74 20 63 68 61 72 20  nTcl(const char 
6e60: 2a 73 63 72 69 70 74 2c 20 73 69 7a 65 5f 74 20  *script, size_t 
6e70: 73 63 72 69 70 74 4c 65 6e 29 20 7b 0a 09 54 63  scriptLen) {..Tc
6e80: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
6e90: 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 73 63 72 69  ;..Tcl_Obj *scri
6ea0: 70 74 4f 62 6a 3b 0a 09 69 6e 74 20 74 63 6c 5f  ptObj;..int tcl_
6eb0: 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20  ret;...interp = 
6ec0: 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28  appfs_TclInterp(
6ed0: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  );..if (interp =
6ee0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46  = NULL) {...APPF
6ef0: 53 5f 44 45 42 55 47 28 22 45 72 72 6f 72 20 63  S_DEBUG("Error c
6f00: 72 65 61 74 69 6e 67 20 61 6e 20 69 6e 74 65 72  reating an inter
6f10: 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 72 65  preter.");....re
6f20: 74 75 72 6e 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  turn;..}...appfs
6f30: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
6f40: 73 63 72 69 70 74 4f 62 6a 20 3d 20 54 63 6c 5f  scriptObj = Tcl_
6f50: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 73 63 72  NewStringObj(scr
6f60: 69 70 74 2c 20 73 63 72 69 70 74 4c 65 6e 29 3b  ipt, scriptLen);
6f70: 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43  ....Tcl_IncrRefC
6f80: 6f 75 6e 74 28 73 63 72 69 70 74 4f 62 6a 29 3b  ount(scriptObj);
6f90: 0a 09 29 0a 0a 09 69 66 20 28 73 63 72 69 70 74  ..)...if (script
6fa0: 4f 62 6a 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  Obj == NULL) {..
6fb0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 72  .APPFS_DEBUG("Er
6fc0: 72 6f 72 20 63 72 65 61 74 69 6e 67 20 61 20 73  ror creating a s
6fd0: 63 72 69 70 74 20 6f 62 6a 65 63 74 2e 22 29 3b  cript object.");
6fe0: 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a  ....return;..}..
6ff0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
7000: 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20  cl(...tcl_ret = 
7010: 54 63 6c 5f 45 76 61 6c 4f 62 6a 45 78 28 69 6e  Tcl_EvalObjEx(in
7020: 74 65 72 70 2c 20 73 63 72 69 70 74 4f 62 6a 2c  terp, scriptObj,
7030: 20 54 43 4c 5f 45 56 41 4c 5f 44 49 52 45 43 54   TCL_EVAL_DIRECT
7040: 29 3b 0a 09 09 54 63 6c 5f 44 65 63 72 52 65 66  );...Tcl_DecrRef
7050: 43 6f 75 6e 74 28 73 63 72 69 70 74 4f 62 6a 29  Count(scriptObj)
7060: 3b 0a 09 29 0a 0a 09 69 66 20 28 74 63 6c 5f 72  ;..)...if (tcl_r
7070: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
7080: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
7090: 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45  tcl(....APPFS_DE
70a0: 42 55 47 28 22 53 63 72 69 70 74 20 72 65 74 75  BUG("Script retu
70b0: 72 6e 65 64 20 65 72 72 6f 72 20 25 69 3a 20 25  rned error %i: %
70c0: 73 22 2c 20 74 63 6c 5f 72 65 74 2c 20 54 63 6c  s", tcl_ret, Tcl
70d0: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
70e0: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 09  (interp));...)..
70f0: 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 23 65  }...return;.}.#e
7100: 6e 64 69 66 0a 0a 73 74 61 74 69 63 20 69 6e 74  ndif..static int
7110: 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64   appfs_fuse_read
7120: 6c 69 6e 6b 28 63 6f 6e 73 74 20 63 68 61 72 20  link(const char 
7130: 2a 70 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66  *path, char *buf
7140: 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65 29 20 7b  , size_t size) {
7150: 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70  ..struct appfs_p
7160: 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f  athinfo pathinfo
7170: 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 20 3d 20  ;..int retval = 
7180: 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  0;...APPFS_DEBUG
7190: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
71a0: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
71b0: 3b 0a 0a 09 70 61 74 68 69 6e 66 6f 2e 74 79 70  ;...pathinfo.typ
71c0: 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59  e = APPFS_PATHTY
71d0: 50 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a 09 72 65  PE_INVALID;...re
71e0: 74 76 61 6c 20 3d 20 61 70 70 66 73 5f 67 65 74  tval = appfs_get
71f0: 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c  _path_info(path,
7200: 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a 09 69 66   &pathinfo);..if
7210: 20 28 72 65 74 76 61 6c 20 21 3d 20 30 29 20 7b   (retval != 0) {
7220: 0a 09 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
7230: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68  );..}...if (path
7240: 69 6e 66 6f 2e 74 79 70 65 20 21 3d 20 41 50 50  info.type != APP
7250: 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c  FS_PATHTYPE_SYML
7260: 49 4e 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  INK) {...return(
7270: 2d 45 49 4e 56 41 4c 29 3b 0a 09 7d 0a 0a 09 69  -EINVAL);..}...i
7280: 66 20 28 28 73 74 72 6c 65 6e 28 70 61 74 68 69  f ((strlen(pathi
7290: 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  nfo.typeinfo.sym
72a0: 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31  link.source) + 1
72b0: 29 20 3e 20 73 69 7a 65 29 20 7b 0a 09 09 72 65  ) > size) {...re
72c0: 74 75 72 6e 28 2d 45 4e 41 4d 45 54 4f 4f 4c 4f  turn(-ENAMETOOLO
72d0: 4e 47 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79  NG);..}...memcpy
72e0: 28 62 75 66 2c 20 70 61 74 68 69 6e 66 6f 2e 74  (buf, pathinfo.t
72f0: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e  ypeinfo.symlink.
7300: 73 6f 75 72 63 65 2c 20 73 74 72 6c 65 6e 28 70  source, strlen(p
7310: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
7320: 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29  .symlink.source)
7330: 20 2b 20 31 29 3b 0a 0a 09 72 65 74 75 72 6e 28   + 1);...return(
7340: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
7350: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74  t appfs_fuse_get
7360: 61 74 74 72 28 63 6f 6e 73 74 20 63 68 61 72 20  attr(const char 
7370: 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20 73 74  *path, struct st
7380: 61 74 20 2a 73 74 62 75 66 29 20 7b 0a 09 73 74  at *stbuf) {..st
7390: 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69  ruct appfs_pathi
73a0: 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69  nfo pathinfo;..i
73b0: 6e 74 20 63 68 61 6e 67 65 4f 77 6e 65 72 54 6f  nt changeOwnerTo
73c0: 55 73 65 72 49 66 50 61 63 6b 61 67 65 64 3b 0a  UserIfPackaged;.
73d0: 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09 72  .int retval;...r
73e0: 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 41 50 50  etval = 0;...APP
73f0: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
7400: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
7410: 22 2c 20 70 61 74 68 29 3b 0a 0a 23 69 66 20 28  ", path);..#if (
7420: 64 65 66 69 6e 65 64 28 44 45 42 55 47 29 20 26  defined(DEBUG) &
7430: 26 20 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f  & defined(APPFS_
7440: 45 58 49 54 5f 50 41 54 48 29 29 20 7c 7c 20 64  EXIT_PATH)) || d
7450: 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58 49  efined(APPFS_EXI
7460: 54 5f 50 41 54 48 5f 45 4e 41 42 4c 45 5f 4d 41  T_PATH_ENABLE_MA
7470: 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f 48 4f 4c  JOR_SECURITY_HOL
7480: 45 29 0a 09 2f 2a 0a 09 20 2a 20 54 68 69 73 20  E)../*.. * This 
7490: 69 73 20 61 20 6d 61 6a 6f 72 20 73 65 63 75 72  is a major secur
74a0: 69 74 79 20 69 73 73 75 65 20 73 6f 20 77 65 20  ity issue so we 
74b0: 63 61 6e 6e 6f 74 20 6c 65 74 20 69 74 20 62 65  cannot let it be
74c0: 20 63 6f 6d 70 69 6c 65 64 20 69 6e 74 6f 0a 09   compiled into..
74d0: 20 2a 20 61 6e 79 20 72 65 6c 65 61 73 65 0a 09   * any release..
74e0: 20 2a 2f 0a 09 69 66 20 28 73 74 72 63 6d 70 28   */..if (strcmp(
74f0: 70 61 74 68 2c 20 22 2f 65 78 69 74 22 29 20 3d  path, "/exit") =
7500: 3d 20 30 29 20 7b 0a 09 09 61 70 70 66 73 5f 65  = 0) {...appfs_e
7510: 78 69 74 28 29 3b 0a 09 7d 0a 23 65 6e 64 69 66  xit();..}.#endif
7520: 0a 23 69 66 20 64 65 66 69 6e 65 64 28 41 50 50  .#if defined(APP
7530: 46 53 5f 45 58 45 43 5f 50 41 54 48 5f 45 4e 41  FS_EXEC_PATH_ENA
7540: 42 4c 45 5f 4d 41 4a 4f 52 5f 53 45 43 55 52 49  BLE_MAJOR_SECURI
7550: 54 59 5f 48 4f 4c 45 29 0a 09 69 66 20 28 73 74  TY_HOLE)..if (st
7560: 72 63 6d 70 28 70 61 74 68 2c 20 22 2f 65 78 65  rcmp(path, "/exe
7570: 63 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 6d 65  c") == 0) {...me
7580: 6d 73 65 74 28 73 74 62 75 66 2c 20 30 2c 20 73  mset(stbuf, 0, s
7590: 69 7a 65 6f 66 28 73 74 72 75 63 74 20 73 74 61  izeof(struct sta
75a0: 74 29 29 3b 0a 0a 09 09 73 74 62 75 66 2d 3e 73  t));....stbuf->s
75b0: 74 5f 6d 74 69 6d 65 20 3d 20 30 3b 0a 09 09 73  t_mtime = 0;...s
75c0: 74 62 75 66 2d 3e 73 74 5f 63 74 69 6d 65 20 3d  tbuf->st_ctime =
75d0: 20 30 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f   0;...stbuf->st_
75e0: 61 74 69 6d 65 20 3d 20 30 3b 0a 09 09 73 74 62  atime = 0;...stb
75f0: 75 66 2d 3e 73 74 5f 69 6e 6f 20 20 20 3d 20 33  uf->st_ino   = 3
7600: 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ;...stbuf->st_mo
7610: 64 65 20 20 3d 20 30 3b 0a 09 09 73 74 62 75 66  de  = 0;...stbuf
7620: 2d 3e 73 74 5f 6d 6f 64 65 20 20 3d 20 53 5f 49  ->st_mode  = S_I
7630: 46 52 45 47 20 7c 20 30 36 30 30 3b 0a 09 09 73  FREG | 0600;...s
7640: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d  tbuf->st_nlink =
7650: 20 31 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f   1;...stbuf->st_
7660: 73 69 7a 65 20 20 3d 20 30 3b 0a 0a 09 09 72 65  size  = 0;....re
7670: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d  turn(retval);..}
7680: 0a 23 65 6e 64 69 66 0a 0a 09 70 61 74 68 69 6e  .#endif...pathin
7690: 66 6f 2e 74 79 70 65 20 3d 20 41 50 50 46 53 5f  fo.type = APPFS_
76a0: 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44  PATHTYPE_INVALID
76b0: 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 61 70 70  ;...retval = app
76c0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
76d0: 28 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f  (path, &pathinfo
76e0: 29 3b 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21  );..if (retval !
76f0: 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 72 65 74  = 0) {...if (ret
7700: 76 61 6c 20 3d 3d 20 2d 45 4e 4f 45 4e 54 29 20  val == -ENOENT) 
7710: 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  {....APPFS_DEBUG
7720: 28 22 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20  ("get_path_info 
7730: 72 65 74 75 72 6e 65 64 20 45 4e 4f 45 4e 54 2c  returned ENOENT,
7740: 20 72 65 74 75 72 6e 69 6e 67 20 69 74 20 61 73   returning it as
7750: 20 77 65 6c 6c 2e 22 29 3b 0a 09 09 7d 20 65 6c   well.");...} el
7760: 73 65 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45  se {....APPFS_DE
7770: 42 55 47 28 22 65 72 72 6f 72 3a 20 67 65 74 5f  BUG("error: get_
7780: 70 61 74 68 5f 69 6e 66 6f 20 66 61 69 6c 65 64  path_info failed
7790: 22 29 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 75 72  ");...}....retur
77a0: 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09  n(retval);..}...
77b0: 6d 65 6d 73 65 74 28 73 74 62 75 66 2c 20 30 2c  memset(stbuf, 0,
77c0: 20 73 69 7a 65 6f 66 28 73 74 72 75 63 74 20 73   sizeof(struct s
77d0: 74 61 74 29 29 3b 0a 0a 09 73 74 62 75 66 2d 3e  tat));...stbuf->
77e0: 73 74 5f 6d 74 69 6d 65 20 3d 20 70 61 74 68 69  st_mtime = pathi
77f0: 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66  nfo.time;..stbuf
7800: 2d 3e 73 74 5f 63 74 69 6d 65 20 3d 20 70 61 74  ->st_ctime = pat
7810: 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62  hinfo.time;..stb
7820: 75 66 2d 3e 73 74 5f 61 74 69 6d 65 20 3d 20 70  uf->st_atime = p
7830: 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73  athinfo.time;..s
7840: 74 62 75 66 2d 3e 73 74 5f 69 6e 6f 20 20 20 3d  tbuf->st_ino   =
7850: 20 70 61 74 68 69 6e 66 6f 2e 69 6e 6f 64 65 3b   pathinfo.inode;
7860: 0a 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65  ..stbuf->st_mode
7870: 20 20 3d 20 30 3b 0a 0a 09 63 68 61 6e 67 65 4f    = 0;...changeO
7880: 77 6e 65 72 54 6f 55 73 65 72 49 66 50 61 63 6b  wnerToUserIfPack
7890: 61 67 65 64 20 3d 20 31 3b 0a 0a 09 73 77 69 74  aged = 1;...swit
78a0: 63 68 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70  ch (pathinfo.typ
78b0: 65 29 20 7b 0a 09 09 63 61 73 65 20 41 50 50 46  e) {...case APPF
78c0: 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45 43  S_PATHTYPE_DIREC
78d0: 54 4f 52 59 3a 0a 09 09 09 73 74 62 75 66 2d 3e  TORY:....stbuf->
78e0: 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 44 49  st_mode = S_IFDI
78f0: 52 20 7c 20 30 35 35 35 3b 0a 09 09 09 73 74 62  R | 0555;....stb
7900: 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 32  uf->st_nlink = 2
7910: 20 2b 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65   + pathinfo.type
7920: 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f  info.dir.childco
7930: 75 6e 74 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09  unt;....break;..
7940: 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48  .case APPFS_PATH
7950: 54 59 50 45 5f 46 49 4c 45 3a 0a 09 09 09 73 74  TYPE_FILE:....st
7960: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53  buf->st_mode = S
7970: 5f 49 46 52 45 47 20 7c 20 30 34 34 34 3b 0a 0a  _IFREG | 0444;..
7980: 09 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e  ...if (pathinfo.
7990: 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 65 78  typeinfo.file.ex
79a0: 65 63 75 74 61 62 6c 65 29 20 7b 0a 09 09 09 09  ecutable) {.....
79b0: 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 7c  stbuf->st_mode |
79c0: 3d 20 30 31 31 31 3b 0a 09 09 09 7d 0a 0a 09 09  = 0111;....}....
79d0: 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 70 61  .if (pathinfo.pa
79e0: 63 6b 61 67 65 64 29 20 7b 0a 09 09 09 09 69 66  ckaged) {.....if
79f0: 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69   (pathinfo.typei
7a00: 6e 66 6f 2e 66 69 6c 65 2e 73 75 69 64 52 6f 6f  nfo.file.suidRoo
7a10: 74 29 20 7b 0a 09 09 09 09 09 63 68 61 6e 67 65  t) {......change
7a20: 4f 77 6e 65 72 54 6f 55 73 65 72 49 66 50 61 63  OwnerToUserIfPac
7a30: 6b 61 67 65 64 20 3d 20 30 3b 0a 0a 09 09 09 09  kaged = 0;......
7a40: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
7a50: 7c 3d 20 30 34 30 30 30 3b 0a 09 09 09 09 7d 0a  |= 04000;.....}.
7a60: 09 09 09 7d 0a 0a 09 09 09 69 66 20 28 70 61 74  ...}.....if (pat
7a70: 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66  hinfo.typeinfo.f
7a80: 69 6c 65 2e 77 6f 72 6c 64 61 63 63 65 73 73 69  ile.worldaccessi
7a90: 62 6c 65 29 20 7b 0a 09 09 09 09 73 74 62 75 66  ble) {.....stbuf
7aa0: 2d 3e 73 74 5f 6d 6f 64 65 20 26 3d 20 7e 30 37  ->st_mode &= ~07
7ab0: 37 3b 0a 09 09 09 7d 0a 0a 09 09 09 73 74 62 75  7;....}.....stbu
7ac0: 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b  f->st_nlink = 1;
7ad0: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69  ....stbuf->st_si
7ae0: 7a 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 79  ze = pathinfo.ty
7af0: 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65  peinfo.file.size
7b00: 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63  ;.....break;...c
7b10: 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59  ase APPFS_PATHTY
7b20: 50 45 5f 53 59 4d 4c 49 4e 4b 3a 0a 09 09 09 73  PE_SYMLINK:....s
7b30: 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20  tbuf->st_mode = 
7b40: 53 5f 49 46 4c 4e 4b 20 7c 20 30 35 35 35 3b 0a  S_IFLNK | 0555;.
7b50: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69  ...stbuf->st_nli
7b60: 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66  nk = 1;....stbuf
7b70: 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 70 61 74 68  ->st_size = path
7b80: 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79  info.typeinfo.sy
7b90: 6d 6c 69 6e 6b 2e 73 69 7a 65 3b 0a 09 09 09 62  mlink.size;....b
7ba0: 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50  reak;...case APP
7bb0: 46 53 5f 50 41 54 48 54 59 50 45 5f 53 4f 43 4b  FS_PATHTYPE_SOCK
7bc0: 45 54 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74  ET:....stbuf->st
7bd0: 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 53 4f 43 4b  _mode = S_IFSOCK
7be0: 20 7c 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75   | 0555;....stbu
7bf0: 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b  f->st_nlink = 1;
7c00: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69  ....stbuf->st_si
7c10: 7a 65 20 3d 20 30 3b 0a 09 09 09 62 72 65 61 6b  ze = 0;....break
7c20: 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50  ;...case APPFS_P
7c30: 41 54 48 54 59 50 45 5f 46 49 46 4f 3a 0a 09 09  ATHTYPE_FIFO:...
7c40: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
7c50: 3d 20 53 5f 49 46 49 46 4f 20 7c 20 30 35 35 35  = S_IFIFO | 0555
7c60: 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e  ;....stbuf->st_n
7c70: 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62  link = 1;....stb
7c80: 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 30 3b  uf->st_size = 0;
7c90: 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73  ....break;...cas
7ca0: 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  e APPFS_PATHTYPE
7cb0: 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 3a  _DOES_NOT_EXIST:
7cc0: 0a 09 09 09 72 65 74 76 61 6c 20 3d 20 2d 45 4e  ....retval = -EN
7cd0: 4f 45 4e 54 3b 0a 0a 09 09 09 62 72 65 61 6b 3b  OENT;.....break;
7ce0: 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41  ...case APPFS_PA
7cf0: 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3a 0a  THTYPE_INVALID:.
7d00: 09 09 09 72 65 74 76 61 6c 20 3d 20 2d 45 49 4f  ...retval = -EIO
7d10: 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a 09 7d 0a  ;.....break;..}.
7d20: 0a 09 69 66 20 28 28 70 61 74 68 69 6e 66 6f 2e  ..if ((pathinfo.
7d30: 70 61 63 6b 61 67 65 64 20 26 26 20 63 68 61 6e  packaged && chan
7d40: 67 65 4f 77 6e 65 72 54 6f 55 73 65 72 49 66 50  geOwnerToUserIfP
7d50: 61 63 6b 61 67 65 64 29 20 7c 7c 20 28 21 70 61  ackaged) || (!pa
7d60: 74 68 69 6e 66 6f 2e 70 61 63 6b 61 67 65 64 29  thinfo.packaged)
7d70: 29 20 7b 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f  ) {...stbuf->st_
7d80: 75 69 64 20 20 20 3d 20 61 70 70 66 73 5f 67 65  uid   = appfs_ge
7d90: 74 5f 66 73 75 69 64 28 29 3b 0a 09 09 73 74 62  t_fsuid();...stb
7da0: 75 66 2d 3e 73 74 5f 67 69 64 20 20 20 3d 20 61  uf->st_gid   = a
7db0: 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28 29  ppfs_get_fsgid()
7dc0: 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ;...stbuf->st_mo
7dd0: 64 65 20 7c 3d 20 30 32 30 30 3b 0a 09 7d 0a 0a  de |= 0200;..}..
7de0: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
7df0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
7e00: 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 64 69  ppfs_fuse_readdi
7e10: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  r(const char *pa
7e20: 74 68 2c 20 76 6f 69 64 20 2a 62 75 66 2c 20 66  th, void *buf, f
7e30: 75 73 65 5f 66 69 6c 6c 5f 64 69 72 5f 74 20 66  use_fill_dir_t f
7e40: 69 6c 6c 65 72 2c 20 6f 66 66 5f 74 20 6f 66 66  iller, off_t off
7e50: 73 65 74 2c 20 73 74 72 75 63 74 20 66 75 73 65  set, struct fuse
7e60: 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20  _file_info *fi) 
7e70: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
7e80: 6e 74 65 72 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20  nterp;..Tcl_Obj 
7e90: 2a 2a 63 68 69 6c 64 72 65 6e 3b 0a 09 69 6e 74  **children;..int
7ea0: 20 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c   children_count,
7eb0: 20 69 64 78 3b 0a 09 69 6e 74 20 74 63 6c 5f 72   idx;..int tcl_r
7ec0: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  et;...APPFS_DEBU
7ed0: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
7ee0: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
7ef0: 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  );...interp = ap
7f00: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  pfs_TclInterp();
7f10: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
7f20: 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f  NULL) {...APPFS_
7f30: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 55 6e  DEBUG("error: Un
7f40: 61 62 6c 65 20 74 6f 20 67 65 74 20 61 6e 20 69  able to get an i
7f50: 6e 74 65 72 70 72 65 74 65 72 22 29 3b 0a 0a 09  nterpreter");...
7f60: 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a  .return(0);..}..
7f70: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
7f80: 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28  cl(Tcl_Preserve(
7f90: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 66 69 6c 6c  interp);)...fill
7fa0: 65 72 28 62 75 66 2c 20 22 2e 22 2c 20 4e 55 4c  er(buf, ".", NUL
7fb0: 4c 2c 20 30 29 3b 0a 09 66 69 6c 6c 65 72 28 62  L, 0);..filler(b
7fc0: 75 66 2c 20 22 2e 2e 22 2c 20 4e 55 4c 4c 2c 20  uf, "..", NULL, 
7fd0: 30 29 3b 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20  0);...tcl_ret = 
7fe0: 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69  appfs_Tcl_Eval(i
7ff0: 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70  nterp, 2, "::app
8000: 66 73 3a 3a 67 65 74 63 68 69 6c 64 72 65 6e 22  fs::getchildren"
8010: 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28 74 63  , path);..if (tc
8020: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
8030: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
8040: 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 63 68  ("::appfs::getch
8050: 69 6c 64 72 65 6e 28 25 73 29 20 66 61 69 6c 65  ildren(%s) faile
8060: 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61 70  d.", path);...ap
8070: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
8080: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
8090: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
80a0: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
80b0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
80c0: 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63  ;...)....appfs_c
80d0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
80e0: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
80f0: 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09  ....return(0);..
8100: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
8110: 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74  ibtcl(...tcl_ret
8120: 20 3d 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 47 65   = Tcl_ListObjGe
8130: 74 45 6c 65 6d 65 6e 74 73 28 69 6e 74 65 72 70  tElements(interp
8140: 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75  , Tcl_GetObjResu
8150: 6c 74 28 69 6e 74 65 72 70 29 2c 20 26 63 68 69  lt(interp), &chi
8160: 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c 20 26 63 68  ldren_count, &ch
8170: 69 6c 64 72 65 6e 29 3b 0a 09 29 0a 09 69 66 20  ildren);..)..if 
8180: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
8190: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
81a0: 42 55 47 28 22 50 61 72 73 69 6e 67 20 6c 69 73  BUG("Parsing lis
81b0: 74 20 6f 66 20 63 68 69 6c 64 72 65 6e 20 6f 6e  t of children on
81c0: 20 70 61 74 68 20 25 73 20 66 61 69 6c 65 64 2e   path %s failed.
81d0: 22 2c 20 70 61 74 68 29 3b 0a 09 09 61 70 70 66  ", path);...appf
81e0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
81f0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
8200: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22  cl Error is: %s"
8210: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
8220: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
8230: 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c  ..)....appfs_cal
8240: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
8250: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
8260: 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a  ..return(0);..}.
8270: 0a 09 66 6f 72 20 28 69 64 78 20 3d 20 30 3b 20  ..for (idx = 0; 
8280: 69 64 78 20 3c 20 63 68 69 6c 64 72 65 6e 5f 63  idx < children_c
8290: 6f 75 6e 74 3b 20 69 64 78 2b 2b 29 20 7b 0a 09  ount; idx++) {..
82a0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
82b0: 63 6c 28 0a 09 09 09 66 69 6c 6c 65 72 28 62 75  cl(....filler(bu
82c0: 66 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  f, Tcl_GetString
82d0: 28 63 68 69 6c 64 72 65 6e 5b 69 64 78 5d 29 2c  (children[idx]),
82e0: 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 09 29 0a 09   NULL, 0);...)..
82f0: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
8300: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
8310: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 72 65  e(interp);)...re
8320: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
8330: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
8340: 65 5f 6f 70 65 6e 28 63 6f 6e 73 74 20 63 68 61  e_open(const cha
8350: 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20  r *path, struct 
8360: 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a  fuse_file_info *
8370: 66 69 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72  fi) {..Tcl_Inter
8380: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 73 74 72 75  p *interp;..stru
8390: 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66  ct appfs_pathinf
83a0: 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 63 6f 6e  o pathinfo;..con
83b0: 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 61  st char *real_pa
83c0: 74 68 2c 20 2a 6d 6f 64 65 3b 0a 09 69 6e 74 20  th, *mode;..int 
83d0: 67 70 69 5f 72 65 74 2c 20 74 63 6c 5f 72 65 74  gpi_ret, tcl_ret
83e0: 3b 0a 09 69 6e 74 20 66 68 3b 0a 0a 09 41 50 50  ;..int fh;...APP
83f0: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
8400: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
8410: 22 2c 20 70 61 74 68 29 3b 0a 0a 23 69 66 20 64  ", path);..#if d
8420: 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58 45  efined(APPFS_EXE
8430: 43 5f 50 41 54 48 5f 45 4e 41 42 4c 45 5f 4d 41  C_PATH_ENABLE_MA
8440: 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f 48 4f 4c  JOR_SECURITY_HOL
8450: 45 29 0a 09 69 66 20 28 73 74 72 63 6d 70 28 70  E)..if (strcmp(p
8460: 61 74 68 2c 20 22 2f 65 78 65 63 22 29 20 3d 3d  ath, "/exec") ==
8470: 20 30 29 20 7b 0a 09 09 66 69 2d 3e 66 68 20 3d   0) {...fi->fh =
8480: 20 30 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30 29   0;....return(0)
8490: 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 67 70  ;..}.#endif...gp
84a0: 69 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 67 65  i_ret = appfs_ge
84b0: 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61 74 68  t_path_info(path
84c0: 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a 0a 09  , &pathinfo);...
84d0: 69 66 20 28 28 66 69 2d 3e 66 6c 61 67 73 20 26  if ((fi->flags &
84e0: 20 28 4f 5f 57 52 4f 4e 4c 59 7c 4f 5f 43 52 45   (O_WRONLY|O_CRE
84f0: 41 54 29 29 20 3d 3d 20 28 4f 5f 43 52 45 41 54  AT)) == (O_CREAT
8500: 7c 4f 5f 57 52 4f 4e 4c 59 29 29 20 7b 0a 09 09  |O_WRONLY)) {...
8510: 2f 2a 20 54 68 65 20 66 69 6c 65 20 77 69 6c 6c  /* The file will
8520: 20 62 65 20 63 72 65 61 74 65 64 20 69 66 20 69   be created if i
8530: 74 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74  t does not exist
8540: 20 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f 72 65   */...if (gpi_re
8550: 74 20 21 3d 20 30 20 26 26 20 67 70 69 5f 72 65  t != 0 && gpi_re
8560: 74 20 21 3d 20 2d 45 4e 4f 45 4e 54 29 20 7b 0a  t != -ENOENT) {.
8570: 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
8580: 65 72 72 6f 72 3a 20 67 65 74 5f 70 61 74 68 5f  error: get_path_
8590: 69 6e 66 6f 20 66 61 69 6c 65 64 22 29 3b 0a 0a  info failed");..
85a0: 09 09 09 72 65 74 75 72 6e 28 67 70 69 5f 72 65  ...return(gpi_re
85b0: 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d 6f 64 65 20  t);...}....mode 
85c0: 3d 20 22 63 72 65 61 74 65 22 3b 0a 0a 09 09 2f  = "create";..../
85d0: 2a 0a 09 09 20 2a 20 57 65 20 68 61 76 65 20 74  *... * We have t
85e0: 6f 20 63 6c 65 61 72 20 74 68 65 20 63 61 63 68  o clear the cach
85f0: 65 20 68 65 72 65 20 73 6f 20 74 68 61 74 20 74  e here so that t
8600: 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a 09 09 20  he number of... 
8610: 2a 20 6c 69 6e 6b 73 20 67 65 74 73 20 6d 61 69  * links gets mai
8620: 6e 74 61 69 6e 65 64 20 6f 6e 20 74 68 65 20 70  ntained on the p
8630: 61 72 65 6e 74 20 64 69 72 65 63 74 6f 72 79 0a  arent directory.
8640: 09 09 20 2a 2f 0a 09 09 61 70 70 66 73 5f 67 65  .. */...appfs_ge
8650: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
8660: 65 5f 66 6c 75 73 68 28 61 70 70 66 73 5f 67 65  e_flush(appfs_ge
8670: 74 5f 66 73 75 69 64 28 29 2c 20 2d 31 29 3b 0a  t_fsuid(), -1);.
8680: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 2f 2a 20 54  .} else {.../* T
8690: 68 65 20 66 69 6c 65 20 6d 75 73 74 20 61 6c 72  he file must alr
86a0: 65 61 64 79 20 65 78 69 73 74 20 2a 2f 0a 09 09  eady exist */...
86b0: 69 66 20 28 67 70 69 5f 72 65 74 20 21 3d 20 30  if (gpi_ret != 0
86c0: 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42  ) {....APPFS_DEB
86d0: 55 47 28 22 65 72 72 6f 72 3a 20 67 65 74 5f 70  UG("error: get_p
86e0: 61 74 68 5f 69 6e 66 6f 20 66 61 69 6c 65 64 22  ath_info failed"
86f0: 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 67 70  );.....return(gp
8700: 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d  i_ret);...}....m
8710: 6f 64 65 20 3d 20 22 22 3b 0a 0a 09 09 69 66 20  ode = "";....if 
8720: 28 28 66 69 2d 3e 66 6c 61 67 73 20 26 20 4f 5f  ((fi->flags & O_
8730: 57 52 4f 4e 4c 59 29 20 3d 3d 20 4f 5f 57 52 4f  WRONLY) == O_WRO
8740: 4e 4c 59 29 20 7b 0a 09 09 09 6d 6f 64 65 20 3d  NLY) {....mode =
8750: 20 22 77 72 69 74 65 22 3b 0a 09 09 7d 0a 09 7d   "write";...}..}
8760: 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e  ...if (pathinfo.
8770: 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50 41  type == APPFS_PA
8780: 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59  THTYPE_DIRECTORY
8790: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
87a0: 47 28 22 65 72 72 6f 72 3a 20 41 73 6b 65 64 20  G("error: Asked 
87b0: 74 6f 20 6f 70 65 6e 20 61 20 64 69 72 65 63 74  to open a direct
87c0: 6f 72 79 2e 22 29 3b 0a 0a 09 09 72 65 74 75 72  ory.");....retur
87d0: 6e 28 2d 45 49 53 44 49 52 29 3b 0a 09 7d 0a 0a  n(-EISDIR);..}..
87e0: 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f  .interp = appfs_
87f0: 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66  TclInterp();..if
8800: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
8810: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
8820: 47 28 22 65 72 72 6f 72 3a 20 55 6e 61 62 6c 65  G("error: Unable
8830: 20 74 6f 20 67 65 74 20 61 6e 20 69 6e 74 65 72   to get an inter
8840: 70 72 65 74 65 72 22 29 3b 0a 0a 09 09 72 65 74  preter");....ret
8850: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
8860: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
8870: 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69  l(Tcl_Preserve(i
8880: 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72  nterp);)...tcl_r
8890: 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45  et = appfs_Tcl_E
88a0: 76 61 6c 28 69 6e 74 65 72 70 2c 20 33 2c 20 22  val(interp, 3, "
88b0: 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74  ::appfs::openpat
88c0: 68 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65 29 3b  h", path, mode);
88d0: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
88e0: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
88f0: 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66  FS_DEBUG("::appf
8900: 73 3a 3a 6f 70 65 6e 70 61 74 68 28 25 73 2c 20  s::openpath(%s, 
8910: 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61  %s) failed.", pa
8920: 74 68 2c 20 6d 6f 64 65 29 3b 0a 09 09 61 70 70  th, mode);...app
8930: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
8940: 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
8950: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
8960: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
8970: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
8980: 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61  ...)....appfs_ca
8990: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
89a0: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
89b0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
89c0: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c  ..}...appfs_call
89d0: 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 61 6c 5f  _libtcl(...real_
89e0: 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74 53 74  path = Tcl_GetSt
89f0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
8a00: 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63  p);..)...appfs_c
8a10: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
8a20: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
8a30: 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68  ...if (real_path
8a40: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50   == NULL) {...AP
8a50: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
8a60: 3a 20 72 65 61 6c 5f 70 61 74 68 20 77 61 73 20  : real_path was 
8a70: 4e 55 4c 4c 2e 22 29 0a 0a 09 09 72 65 74 75 72  NULL.")....retur
8a80: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 41 50  n(-EIO);..}...AP
8a90: 50 46 53 5f 44 45 42 55 47 28 22 54 72 61 6e 73  PFS_DEBUG("Trans
8aa0: 6c 61 74 65 64 20 72 65 71 75 65 73 74 20 74 6f  lated request to
8ab0: 20 6f 70 65 6e 20 25 73 20 74 6f 20 6f 70 65 6e   open %s to open
8ac0: 69 6e 67 20 25 73 20 28 6d 6f 64 65 20 3d 20 5c  ing %s (mode = \
8ad0: 22 25 73 5c 22 29 22 2c 20 70 61 74 68 2c 20 72  "%s\")", path, r
8ae0: 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b  eal_path, mode);
8af0: 0a 0a 09 66 68 20 3d 20 6f 70 65 6e 28 72 65 61  ...fh = open(rea
8b00: 6c 5f 70 61 74 68 2c 20 66 69 2d 3e 66 6c 61 67  l_path, fi->flag
8b10: 73 2c 20 30 36 30 30 29 3b 0a 0a 09 69 66 20 28  s, 0600);...if (
8b20: 66 68 20 3c 20 30 29 20 7b 0a 09 09 41 50 50 46  fh < 0) {...APPF
8b30: 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20  S_DEBUG("error: 
8b40: 6f 70 65 6e 20 66 61 69 6c 65 64 22 29 3b 0a 0a  open failed");..
8b50: 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a  ..return(errno *
8b60: 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66 69 2d 3e 66   -1);..}...fi->f
8b70: 68 20 3d 20 66 68 3b 0a 0a 09 41 50 50 46 53 5f  h = fh;...APPFS_
8b80: 44 45 42 55 47 28 22 4f 70 65 6e 65 64 20 5c 22  DEBUG("Opened \"
8b90: 25 73 5c 22 20 28 66 6f 72 20 5c 22 25 73 5c 22  %s\" (for \"%s\"
8ba0: 29 20 77 69 74 68 20 66 69 6c 65 20 64 65 73 63  ) with file desc
8bb0: 72 69 70 74 6f 72 20 25 69 22 2c 20 72 65 61 6c  riptor %i", real
8bc0: 5f 70 61 74 68 2c 20 70 61 74 68 2c 20 66 68 29  _path, path, fh)
8bd0: 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  ;...return(0);.}
8be0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
8bf0: 66 73 5f 66 75 73 65 5f 63 6c 6f 73 65 28 63 6f  fs_fuse_close(co
8c00: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
8c10: 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65  struct fuse_file
8c20: 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 69 6e  _info *fi) {..in
8c30: 74 20 63 6c 6f 73 65 5f 72 65 74 3b 0a 0a 09 41  t close_ret;...A
8c40: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
8c50: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
8c60: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 23 69 66  .)", path);..#if
8c70: 20 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45   defined(APPFS_E
8c80: 58 45 43 5f 50 41 54 48 5f 45 4e 41 42 4c 45 5f  XEC_PATH_ENABLE_
8c90: 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f 48  MAJOR_SECURITY_H
8ca0: 4f 4c 45 29 0a 09 69 66 20 28 73 74 72 63 6d 70  OLE)..if (strcmp
8cb0: 28 70 61 74 68 2c 20 22 2f 65 78 65 63 22 29 20  (path, "/exec") 
8cc0: 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e  == 0) {...return
8cd0: 28 30 29 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a  (0);..}.#endif..
8ce0: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  .appfs_get_path_
8cf0: 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61  info_cache_rm(pa
8d00: 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73  th, appfs_get_fs
8d10: 75 69 64 28 29 29 3b 0a 0a 09 63 6c 6f 73 65 5f  uid());...close_
8d20: 72 65 74 20 3d 20 63 6c 6f 73 65 28 66 69 2d 3e  ret = close(fi->
8d30: 66 68 29 3b 0a 09 69 66 20 28 63 6c 6f 73 65 5f  fh);..if (close_
8d40: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ret != 0) {...AP
8d50: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
8d60: 3a 20 63 6c 6f 73 65 20 66 61 69 6c 65 64 22 29  : close failed")
8d70: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e  ;....return(errn
8d80: 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65  o * -1);..}...re
8d90: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
8da0: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
8db0: 65 5f 72 65 61 64 28 63 6f 6e 73 74 20 63 68 61  e_read(const cha
8dc0: 72 20 2a 70 61 74 68 2c 20 63 68 61 72 20 2a 62  r *path, char *b
8dd0: 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65 2c  uf, size_t size,
8de0: 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20 73   off_t offset, s
8df0: 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f  truct fuse_file_
8e00: 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 73 73 69  info *fi) {..ssi
8e10: 7a 65 5f 74 20 72 65 61 64 5f 72 65 74 3b 0a 09  ze_t read_ret;..
8e20: 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09 41 50  int retval;...AP
8e30: 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72  PFS_DEBUG("Enter
8e40: 20 28 70 61 74 68 20 3d 20 25 73 2c 20 62 75 66   (path = %s, buf
8e50: 2c 20 73 69 7a 65 20 3d 20 25 6c 6c 69 2c 20 6f  , size = %lli, o
8e60: 66 66 73 65 74 20 3d 20 25 6c 6c 69 2c 20 66 64  ffset = %lli, fd
8e70: 20 3d 20 25 6c 6c 69 29 22 2c 20 70 61 74 68 2c   = %lli)", path,
8e80: 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 69 7a   (long long) siz
8e90: 65 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 6f  e, (long long) o
8ea0: 66 66 73 65 74 2c 20 28 6c 6f 6e 67 20 6c 6f 6e  ffset, (long lon
8eb0: 67 29 20 66 69 2d 3e 66 68 29 3b 0a 0a 09 72 65  g) fi->fh);...re
8ec0: 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 77 68 69 6c  tval = 0;...whil
8ed0: 65 20 28 73 69 7a 65 20 21 3d 20 30 29 20 7b 0a  e (size != 0) {.
8ee0: 09 09 72 65 61 64 5f 72 65 74 20 3d 20 70 72 65  ..read_ret = pre
8ef0: 61 64 28 66 69 2d 3e 66 68 2c 20 62 75 66 2c 20  ad(fi->fh, buf, 
8f00: 73 69 7a 65 2c 20 6f 66 66 73 65 74 29 3b 0a 0a  size, offset);..
8f10: 09 09 69 66 20 28 72 65 61 64 5f 72 65 74 20 3c  ..if (read_ret <
8f20: 20 30 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44   0) {....APPFS_D
8f30: 45 42 55 47 28 22 65 72 72 6f 72 3a 20 72 65 61  EBUG("error: rea
8f40: 64 20 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09 09  d failed");.....
8f50: 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d  return(errno * -
8f60: 31 29 3b 0a 09 09 7d 0a 0a 09 09 69 66 20 28 72  1);...}....if (r
8f70: 65 61 64 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a  ead_ret == 0) {.
8f80: 09 09 09 62 72 65 61 6b 3b 0a 09 09 7d 0a 0a 09  ...break;...}...
8f90: 09 73 69 7a 65 20 2d 3d 20 72 65 61 64 5f 72 65  .size -= read_re
8fa0: 74 3b 0a 09 09 62 75 66 20 20 2b 3d 20 72 65 61  t;...buf  += rea
8fb0: 64 5f 72 65 74 3b 0a 09 09 6f 66 66 73 65 74 20  d_ret;...offset 
8fc0: 2b 3d 20 72 65 61 64 5f 72 65 74 3b 0a 09 09 72  += read_ret;...r
8fd0: 65 74 76 61 6c 20 2b 3d 20 72 65 61 64 5f 72 65  etval += read_re
8fe0: 74 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 69 7a 65  t;..}...if (size
8ff0: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53   != 0) {...APPFS
9000: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 69  _DEBUG("error: i
9010: 6e 63 6f 6d 70 6c 65 74 65 20 72 65 61 64 20 28  ncomplete read (
9020: 74 68 69 73 20 6d 69 67 68 74 20 62 65 20 61 6e  this might be an
9030: 20 65 72 72 6f 72 20 62 65 63 61 75 73 65 20 46   error because F
9040: 55 53 45 20 77 69 6c 6c 20 72 65 71 75 65 73 74  USE will request
9050: 20 74 68 65 20 65 78 61 63 74 20 6c 65 6e 67 74   the exact lengt
9060: 68 20 6f 66 20 74 68 65 20 66 69 6c 65 29 22 29  h of the file)")
9070: 3b 0a 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45 42  ;..}...APPFS_DEB
9080: 55 47 28 22 52 65 74 75 72 6e 69 6e 67 3a 20 25  UG("Returning: %
9090: 69 22 2c 20 72 65 74 76 61 6c 29 3b 0a 0a 09 72  i", retval);...r
90a0: 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d  eturn(retval);.}
90b0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
90c0: 66 73 5f 66 75 73 65 5f 77 72 69 74 65 28 63 6f  fs_fuse_write(co
90d0: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
90e0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 62 75 66 2c  const char *buf,
90f0: 20 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f 66   size_t size, of
9100: 66 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75  f_t offset, stru
9110: 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66  ct fuse_file_inf
9120: 6f 20 2a 66 69 29 20 7b 0a 09 73 73 69 7a 65 5f  o *fi) {..ssize_
9130: 74 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 69 6e  t write_ret;..in
9140: 74 20 72 65 74 76 61 6c 3b 0a 0a 09 41 50 50 46  t retval;...APPF
9150: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
9160: 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22  path = %s, ...)"
9170: 2c 20 70 61 74 68 29 3b 0a 0a 23 69 66 20 64 65  , path);..#if de
9180: 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58 45 43  fined(APPFS_EXEC
9190: 5f 50 41 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a  _PATH_ENABLE_MAJ
91a0: 4f 52 5f 53 45 43 55 52 49 54 59 5f 48 4f 4c 45  OR_SECURITY_HOLE
91b0: 29 0a 09 69 66 20 28 73 74 72 63 6d 70 28 70 61  )..if (strcmp(pa
91c0: 74 68 2c 20 22 2f 65 78 65 63 22 29 20 3d 3d 20  th, "/exec") == 
91d0: 30 29 20 7b 0a 09 09 61 70 70 66 73 5f 72 75 6e  0) {...appfs_run
91e0: 54 63 6c 28 62 75 66 2c 20 73 69 7a 65 29 3b 0a  Tcl(buf, size);.
91f0: 0a 09 09 72 65 74 75 72 6e 28 73 69 7a 65 29 3b  ...return(size);
9200: 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 61 70 70  ..}.#endif...app
9210: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
9220: 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20  _cache_rm(path, 
9230: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28  appfs_get_fsuid(
9240: 29 29 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 30  ));...retval = 0
9250: 3b 0a 0a 09 77 68 69 6c 65 20 28 73 69 7a 65 20  ;...while (size 
9260: 21 3d 20 30 29 20 7b 0a 09 09 77 72 69 74 65 5f  != 0) {...write_
9270: 72 65 74 20 3d 20 70 77 72 69 74 65 28 66 69 2d  ret = pwrite(fi-
9280: 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a 65 2c 20  >fh, buf, size, 
9290: 6f 66 66 73 65 74 29 3b 0a 0a 09 09 69 66 20 28  offset);....if (
92a0: 77 72 69 74 65 5f 72 65 74 20 3c 20 30 29 20 7b  write_ret < 0) {
92b0: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
92c0: 22 65 72 72 6f 72 3a 20 77 72 69 74 65 20 66 61  "error: write fa
92d0: 69 6c 65 64 22 29 3b 0a 0a 09 09 09 72 65 74 75  iled");.....retu
92e0: 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a  rn(errno * -1);.
92f0: 09 09 7d 0a 0a 09 09 69 66 20 28 77 72 69 74 65  ..}....if (write
9300: 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09 09 09  _ret == 0) {....
9310: 62 72 65 61 6b 3b 0a 09 09 7d 0a 0a 09 09 73 69  break;...}....si
9320: 7a 65 20 2d 3d 20 77 72 69 74 65 5f 72 65 74 3b  ze -= write_ret;
9330: 0a 09 09 62 75 66 20 20 2b 3d 20 77 72 69 74 65  ...buf  += write
9340: 5f 72 65 74 3b 0a 09 09 6f 66 66 73 65 74 20 2b  _ret;...offset +
9350: 3d 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 09 72  = write_ret;...r
9360: 65 74 76 61 6c 20 2b 3d 20 77 72 69 74 65 5f 72  etval += write_r
9370: 65 74 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 69 7a  et;..}...if (siz
9380: 65 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  e != 0) {...APPF
9390: 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20  S_DEBUG("error: 
93a0: 69 6e 63 6f 6d 70 6c 65 74 65 20 77 72 69 74 65  incomplete write
93b0: 22 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  ");..}...return(
93c0: 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74  retval);.}..stat
93d0: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
93e0: 65 5f 6d 6b 6e 6f 64 28 63 6f 6e 73 74 20 63 68  e_mknod(const ch
93f0: 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74  ar *path, mode_t
9400: 20 6d 6f 64 65 2c 20 64 65 76 5f 74 20 64 65 76   mode, dev_t dev
9410: 69 63 65 29 20 7b 0a 09 63 68 61 72 20 2a 72 65  ice) {..char *re
9420: 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 6d 6b  al_path;..int mk
9430: 6e 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53  nod_ret;...APPFS
9440: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
9450: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c  ath = %s, ...)",
9460: 20 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 28 6d   path);...if ((m
9470: 6f 64 65 20 26 20 53 5f 49 46 43 48 52 29 20 3d  ode & S_IFCHR) =
9480: 3d 20 53 5f 49 46 43 48 52 29 20 7b 0a 09 09 72  = S_IFCHR) {...r
9490: 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09  eturn(-EPERM);..
94a0: 7d 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20  }...if ((mode & 
94b0: 53 5f 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49 46  S_IFBLK) == S_IF
94c0: 42 4c 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  BLK) {...return(
94d0: 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65  -EPERM);..}...re
94e0: 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f  al_path = appfs_
94f0: 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74  prepare_to_creat
9500: 65 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65  e(path);..if (re
9510: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
9520: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f   {...return(-EIO
9530: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69  );..}...appfs_si
9540: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65  mulate_user_fs_e
9550: 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b 6e 6f 64 5f  nter();...mknod_
9560: 72 65 74 20 3d 20 6d 6b 6e 6f 64 28 72 65 61 6c  ret = mknod(real
9570: 5f 70 61 74 68 2c 20 6d 6f 64 65 2c 20 64 65 76  _path, mode, dev
9580: 69 63 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  ice);...appfs_si
9590: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
95a0: 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72  eave();...free(r
95b0: 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20  eal_path);...if 
95c0: 28 6d 6b 6e 6f 64 5f 72 65 74 20 21 3d 20 30 29  (mknod_ret != 0)
95d0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e   {...return(errn
95e0: 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65  o * -1);..}...re
95f0: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
9600: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
9610: 65 5f 63 72 65 61 74 65 28 63 6f 6e 73 74 20 63  e_create(const c
9620: 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f  har *path, mode_
9630: 74 20 6d 6f 64 65 2c 20 73 74 72 75 63 74 20 66  t mode, struct f
9640: 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66  use_file_info *f
9650: 69 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c  i) {..char *real
9660: 5f 70 61 74 68 3b 0a 09 69 6e 74 20 66 64 3b 0a  _path;..int fd;.
9670: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45  ..APPFS_DEBUG("E
9680: 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c  nter (path = %s,
9690: 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a   ...)", path);..
96a0: 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49  .if ((mode & S_I
96b0: 46 43 48 52 29 20 3d 3d 20 53 5f 49 46 43 48 52  FCHR) == S_IFCHR
96c0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50  ) {...return(-EP
96d0: 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28  ERM);..}...if ((
96e0: 6d 6f 64 65 20 26 20 53 5f 49 46 42 4c 4b 29 20  mode & S_IFBLK) 
96f0: 3d 3d 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09  == S_IFBLK) {...
9700: 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a  return(-EPERM);.
9710: 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d  .}...real_path =
9720: 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74   appfs_prepare_t
9730: 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a  o_create(path);.
9740: 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d  .if (real_path =
9750: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
9760: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
9770: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
9780: 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a  er_fs_enter();..
9790: 09 66 64 20 3d 20 63 72 65 61 74 28 72 65 61 6c  .fd = creat(real
97a0: 5f 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09  _path, mode);...
97b0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
97c0: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a  ser_fs_leave();.
97d0: 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68  ..free(real_path
97e0: 29 3b 0a 0a 09 69 66 20 28 66 64 20 3c 20 30 29  );...if (fd < 0)
97f0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e   {...return(errn
9800: 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66 69  o * -1);..}...fi
9810: 2d 3e 66 68 20 3d 20 66 64 3b 0a 0a 09 72 65 74  ->fh = fd;...ret
9820: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69  urn(0);.}..stati
9830: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
9840: 5f 74 72 75 6e 63 61 74 65 28 63 6f 6e 73 74 20  _truncate(const 
9850: 63 68 61 72 20 2a 70 61 74 68 2c 20 6f 66 66 5f  char *path, off_
9860: 74 20 73 69 7a 65 29 20 7b 0a 09 63 68 61 72 20  t size) {..char 
9870: 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74  *real_path;..int
9880: 20 74 72 75 6e 63 61 74 65 5f 72 65 74 3b 0a 0a   truncate_ret;..
9890: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
98a0: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
98b0: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 23  ...)", path);..#
98c0: 69 66 20 64 65 66 69 6e 65 64 28 41 50 50 46 53  if defined(APPFS
98d0: 5f 45 58 45 43 5f 50 41 54 48 5f 45 4e 41 42 4c  _EXEC_PATH_ENABL
98e0: 45 5f 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54 59  E_MAJOR_SECURITY
98f0: 5f 48 4f 4c 45 29 0a 09 69 66 20 28 73 74 72 63  _HOLE)..if (strc
9900: 6d 70 28 70 61 74 68 2c 20 22 2f 65 78 65 63 22  mp(path, "/exec"
9910: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  ) == 0) {...retu
9920: 72 6e 28 30 29 3b 0a 09 7d 0a 23 65 6e 64 69 66  rn(0);..}.#endif
9930: 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61  ...real_path = a
9940: 70 70 66 73 5f 6c 6f 63 61 6c 70 61 74 68 28 70  ppfs_localpath(p
9950: 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f  ath);..if (real_
9960: 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  path == NULL) {.
9970: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
9980: 09 7d 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70  .}...appfs_get_p
9990: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72  ath_info_cache_r
99a0: 6d 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65  m(path, appfs_ge
99b0: 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 61 70  t_fsuid());...ap
99c0: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
99d0: 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09  r_fs_enter();...
99e0: 74 72 75 6e 63 61 74 65 5f 72 65 74 20 3d 20 74  truncate_ret = t
99f0: 72 75 6e 63 61 74 65 28 72 65 61 6c 5f 70 61 74  runcate(real_pat
9a00: 68 2c 20 73 69 7a 65 29 3b 0a 0a 09 61 70 70 66  h, size);...appf
9a10: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
9a20: 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72  fs_leave();...fr
9a30: 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a  ee(real_path);..
9a40: 09 69 66 20 28 74 72 75 6e 63 61 74 65 5f 72 65  .if (truncate_re
9a50: 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  t != 0) {...retu
9a60: 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a  rn(errno * -1);.
9a70: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  .}...return(0);.
9a80: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
9a90: 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f  pfs_fuse_unlink_
9aa0: 72 6d 64 69 72 28 63 6f 6e 73 74 20 63 68 61 72  rmdir(const char
9ab0: 20 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49   *path) {..Tcl_I
9ac0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09  nterp *interp;..
9ad0: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 41  int tcl_ret;...A
9ae0: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
9af0: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
9b00: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70  .)", path);...ap
9b10: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
9b20: 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 61 70  o_cache_flush(ap
9b30: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 2c  pfs_get_fsuid(),
9b40: 20 2d 31 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d   -1);...interp =
9b50: 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70   appfs_TclInterp
9b60: 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  ();..if (interp 
9b70: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
9b80: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
9b90: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
9ba0: 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69  l(Tcl_Preserve(i
9bb0: 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72  nterp);)...tcl_r
9bc0: 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45  et = appfs_Tcl_E
9bd0: 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22  val(interp, 2, "
9be0: 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c 69 6e 6b 70  ::appfs::unlinkp
9bf0: 61 74 68 22 2c 20 70 61 74 68 29 3b 0a 09 69 66  ath", path);..if
9c00: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
9c10: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
9c20: 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 75  EBUG("::appfs::u
9c30: 6e 6c 69 6e 6b 70 61 74 68 28 25 73 29 20 66 61  nlinkpath(%s) fa
9c40: 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09  iled.", path);..
9c50: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
9c60: 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42  cl(....APPFS_DEB
9c70: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
9c80: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
9c90: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
9ca0: 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66  p));...)....appf
9cb0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
9cc0: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
9cd0: 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45  );)....return(-E
9ce0: 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  IO);..}...appfs_
9cf0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
9d00: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
9d10: 29 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  )...return(0);.}
9d20: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
9d30: 66 73 5f 66 75 73 65 5f 6d 6b 64 69 72 28 63 6f  fs_fuse_mkdir(co
9d40: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
9d50: 6d 6f 64 65 5f 74 20 6d 6f 64 65 29 20 7b 0a 09  mode_t mode) {..
9d60: 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b  char *real_path;
9d70: 0a 09 69 6e 74 20 6d 6b 64 69 72 5f 72 65 74 3b  ..int mkdir_ret;
9d80: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
9d90: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
9da0: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
9db0: 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70  ..real_path = ap
9dc0: 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63  pfs_prepare_to_c
9dd0: 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09 69 66  reate(path);..if
9de0: 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e   (real_path == N
9df0: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
9e00: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  -EIO);..}...appf
9e10: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
9e20: 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b  fs_enter();...mk
9e30: 64 69 72 5f 72 65 74 20 3d 20 6d 6b 64 69 72 28  dir_ret = mkdir(
9e40: 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29  real_path, mode)
9e50: 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61  ;...appfs_simula
9e60: 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65  te_user_fs_leave
9e70: 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f  ();...free(real_
9e80: 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 6d 6b 64  path);...if (mkd
9e90: 69 72 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ir_ret != 0) {..
9ea0: 09 69 66 20 28 65 72 72 6e 6f 20 21 3d 20 45 45  .if (errno != EE
9eb0: 58 49 53 54 29 20 7b 0a 09 09 09 72 65 74 75 72  XIST) {....retur
9ec0: 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09  n(errno * -1);..
9ed0: 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30  .}..}...return(0
9ee0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
9ef0: 20 61 70 70 66 73 5f 66 75 73 65 5f 63 68 6d 6f   appfs_fuse_chmo
9f00: 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  d(const char *pa
9f10: 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 29  th, mode_t mode)
9f20: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
9f30: 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63  interp;..const c
9f40: 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a  har *real_path;.
9f50: 09 69 6e 74 20 74 63 6c 5f 72 65 74 2c 20 63 68  .int tcl_ret, ch
9f60: 6d 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53  mod_ret;...APPFS
9f70: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
9f80: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c  ath = %s, ...)",
9f90: 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f   path);...appfs_
9fa0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
9fb0: 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70 70  che_rm(path, app
9fc0: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b  fs_get_fsuid());
9fd0: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66  ...interp = appf
9fe0: 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09  s_TclInterp();..
9ff0: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
a000: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  LL) {...return(-
a010: 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  EIO);..}...appfs
a020: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
a030: 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70  _Preserve(interp
a040: 29 3b 29 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20  );)...tcl_ret = 
a050: 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69  appfs_Tcl_Eval(i
a060: 6e 74 65 72 70 2c 20 33 2c 20 22 3a 3a 61 70 70  nterp, 3, "::app
a070: 66 73 3a 3a 6f 70 65 6e 70 61 74 68 22 2c 20 70  fs::openpath", p
a080: 61 74 68 2c 20 22 77 72 69 74 65 22 29 3b 0a 09  ath, "write");..
a090: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
a0a0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
a0b0: 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a  _DEBUG("::appfs:
a0c0: 3a 6f 70 65 6e 70 61 74 68 28 25 73 2c 20 25 73  :openpath(%s, %s
a0d0: 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68  ) failed.", path
a0e0: 2c 20 22 77 72 69 74 65 22 29 3b 0a 09 09 61 70  , "write");...ap
a0f0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
a100: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
a110: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
a120: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
a130: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
a140: 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63  ;...)....appfs_c
a150: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
a160: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
a170: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  ....return(-EIO)
a180: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
a190: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 61 6c  l_libtcl(...real
a1a0: 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74 53  _path = Tcl_GetS
a1b0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
a1c0: 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f  rp);..)...appfs_
a1d0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
a1e0: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
a1f0: 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74  )...if (real_pat
a200: 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  h == NULL) {...r
a210: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
a220: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  ..appfs_simulate
a230: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29  _user_fs_enter()
a240: 3b 0a 0a 09 63 68 6d 6f 64 5f 72 65 74 20 3d 20  ;...chmod_ret = 
a250: 63 68 6d 6f 64 28 72 65 61 6c 5f 70 61 74 68 2c  chmod(real_path,
a260: 20 6d 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f   mode);...appfs_
a270: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
a280: 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 72 65 74 75  _leave();...retu
a290: 72 6e 28 63 68 6d 6f 64 5f 72 65 74 29 3b 0a 7d  rn(chmod_ret);.}
a2a0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
a2b0: 66 73 5f 66 75 73 65 5f 73 79 6d 6c 69 6e 6b 28  fs_fuse_symlink(
a2c0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 6f 6c 64 70  const char *oldp
a2d0: 61 74 68 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  ath, const char 
a2e0: 2a 6e 65 77 70 61 74 68 29 20 7b 0a 09 63 68 61  *newpath) {..cha
a2f0: 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69  r *real_path;..i
a300: 6e 74 20 73 79 6d 6c 69 6e 6b 5f 72 65 74 3b 0a  nt symlink_ret;.
a310: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45  ..APPFS_DEBUG("E
a320: 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c  nter (path = %s,
a330: 20 25 73 29 22 2c 20 6f 6c 64 70 61 74 68 2c 20   %s)", oldpath, 
a340: 6e 65 77 70 61 74 68 29 3b 0a 0a 09 72 65 61 6c  newpath);...real
a350: 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72  _path = appfs_pr
a360: 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28  epare_to_create(
a370: 6e 65 77 70 61 74 68 29 3b 0a 09 69 66 20 28 72  newpath);..if (r
a380: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
a390: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
a3a0: 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73  O);..}...appfs_s
a3b0: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
a3c0: 65 6e 74 65 72 28 29 3b 0a 0a 09 73 79 6d 6c 69  enter();...symli
a3d0: 6e 6b 5f 72 65 74 20 3d 20 73 79 6d 6c 69 6e 6b  nk_ret = symlink
a3e0: 28 6f 6c 64 70 61 74 68 2c 20 72 65 61 6c 5f 70  (oldpath, real_p
a3f0: 61 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  ath);...appfs_si
a400: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
a410: 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72  eave();...free(r
a420: 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20  eal_path);...if 
a430: 28 73 79 6d 6c 69 6e 6b 5f 72 65 74 20 21 3d 20  (symlink_ret != 
a440: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72  0) {...return(er
a450: 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09  rno * -1);..}...
a460: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a  return(0);.}../*
a470: 0a 20 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64 65  . * SQLite3 mode
a480: 3a 20 45 78 65 63 75 74 65 20 72 61 77 20 53 51  : Execute raw SQ
a490: 4c 20 61 6e 64 20 72 65 74 75 72 6e 20 73 75 63  L and return suc
a4a0: 63 65 73 73 20 6f 72 20 66 61 69 6c 75 72 65 0a  cess or failure.
a4b0: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61   */.static int a
a4c0: 70 70 66 73 5f 73 71 6c 69 74 65 33 28 63 6f 6e  ppfs_sqlite3(con
a4d0: 73 74 20 63 68 61 72 20 2a 73 71 6c 29 20 7b 0a  st char *sql) {.
a4e0: 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  .Tcl_Interp *int
a4f0: 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72  erp;..const char
a500: 20 2a 73 71 6c 5f 72 65 74 3b 0a 09 69 6e 74 20   *sql_ret;..int 
a510: 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72  tcl_ret;...inter
a520: 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65  p = appfs_create
a530: 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29  _TclInterp(NULL)
a540: 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ;..if (interp ==
a550: 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e   NULL) {...fprin
a560: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
a570: 6c 65 20 74 6f 20 63 72 65 61 74 65 20 61 20 54  le to create a T
a580: 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20  cl interpreter. 
a590: 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a   Aborting.\n");.
a5a0: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
a5b0: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70  ...tcl_ret = app
a5c0: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65  fs_Tcl_Eval(inte
a5d0: 72 70 2c 20 35 2c 20 22 3a 3a 61 70 70 66 73 3a  rp, 5, "::appfs:
a5e0: 3a 64 62 22 2c 20 22 65 76 61 6c 22 2c 20 73 71  :db", "eval", sq
a5f0: 6c 2c 20 22 72 6f 77 22 2c 20 22 75 6e 73 65 74  l, "row", "unset
a600: 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 72 6f 77   -nocomplain row
a610: 28 2a 29 3b 20 70 61 72 72 61 79 20 72 6f 77 3b  (*); parray row;
a620: 20 70 75 74 73 20 5c 22 2d 2d 2d 2d 5c 22 22 29   puts \"----\"")
a630: 3b 0a 09 73 71 6c 5f 72 65 74 20 3d 20 54 63 6c  ;..sql_ret = Tcl
a640: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
a650: 28 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28  (interp);...if (
a660: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
a670: 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  K) {...fprintf(s
a680: 74 64 65 72 72 2c 20 22 5b 65 72 72 6f 72 5d 20  tderr, "[error] 
a690: 25 73 5c 6e 22 2c 20 73 71 6c 5f 72 65 74 29 3b  %s\n", sql_ret);
a6a0: 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  ....return(1);..
a6b0: 7d 0a 0a 09 69 66 20 28 73 71 6c 5f 72 65 74 20  }...if (sql_ret 
a6c0: 26 26 20 73 71 6c 5f 72 65 74 5b 30 5d 20 21 3d  && sql_ret[0] !=
a6d0: 20 27 5c 30 27 29 20 7b 0a 09 09 70 72 69 6e 74   '\0') {...print
a6e0: 66 28 22 25 73 5c 6e 22 2c 20 73 71 6c 5f 72 65  f("%s\n", sql_re
a6f0: 74 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  t);..}...return(
a700: 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 63 6c  0);.}../*. * Tcl
a710: 20 6d 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72   mode: Execute r
a720: 61 77 20 54 63 6c 20 61 6e 64 20 72 65 74 75 72  aw Tcl and retur
a730: 6e 20 73 75 63 63 65 73 73 20 6f 72 20 66 61 69  n success or fai
a740: 6c 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20  lure. */.static 
a750: 69 6e 74 20 61 70 70 66 73 5f 74 63 6c 28 63 6f  int appfs_tcl(co
a760: 6e 73 74 20 63 68 61 72 20 2a 74 63 6c 29 20 7b  nst char *tcl) {
a770: 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  ..Tcl_Interp *in
a780: 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61  terp;..const cha
a790: 72 20 2a 74 63 6c 5f 72 65 73 75 6c 74 3b 0a 09  r *tcl_result;..
a7a0: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69  int tcl_ret;...i
a7b0: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72  nterp = appfs_cr
a7c0: 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e  eate_TclInterp(N
a7d0: 55 4c 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65 72  ULL);..if (inter
a7e0: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66  p == NULL) {...f
a7f0: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
a800: 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65  Unable to create
a810: 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74   a Tcl interpret
a820: 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e  er.  Aborting.\n
a830: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29  ");....return(1)
a840: 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d  ;..}...tcl_ret =
a850: 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70   Tcl_Eval(interp
a860: 2c 20 74 63 6c 29 3b 0a 09 74 63 6c 5f 72 65 73  , tcl);..tcl_res
a870: 75 6c 74 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  ult = Tcl_GetStr
a880: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
a890: 29 3b 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  );...if (tcl_ret
a8a0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
a8b0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
a8c0: 22 5b 65 72 72 6f 72 5d 20 25 73 5c 6e 22 2c 20  "[error] %s\n", 
a8d0: 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72  Tcl_GetVar(inter
a8e0: 70 2c 20 22 65 72 72 6f 72 49 6e 66 6f 22 2c 20  p, "errorInfo", 
a8f0: 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29  TCL_GLOBAL_ONLY)
a900: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b  );....return(1);
a910: 0a 09 7d 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65  ..}...if (tcl_re
a920: 73 75 6c 74 20 26 26 20 74 63 6c 5f 72 65 73 75  sult && tcl_resu
a930: 6c 74 5b 30 5d 20 21 3d 20 27 5c 30 27 29 20 7b  lt[0] != '\0') {
a940: 0a 09 09 70 72 69 6e 74 66 28 22 25 73 5c 6e 22  ...printf("%s\n"
a950: 2c 20 74 63 6c 5f 72 65 73 75 6c 74 29 3b 0a 09  , tcl_result);..
a960: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  }...return(0);.}
a970: 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 64 20 50  ../*. * AppFSd P
a980: 61 63 6b 61 67 65 20 66 6f 72 20 54 63 6c 3a 0a  ackage for Tcl:.
a990: 20 2a 20 20 20 20 20 20 20 20 20 42 72 69 64 67   *         Bridg
a9a0: 65 20 66 6f 72 20 49 2f 4f 20 6f 70 65 72 61 74  e for I/O operat
a9b0: 69 6f 6e 73 20 74 6f 20 72 65 71 75 65 73 74 20  ions to request 
a9c0: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75  information abou
a9d0: 74 20 74 68 65 20 63 75 72 72 65 6e 74 0a 20 2a  t the current. *
a9e0: 20 20 20 20 20 20 20 20 20 74 72 61 6e 73 61 63           transac
a9f0: 74 69 6f 6e 0a 20 2a 2f 0a 2f 2a 0a 20 2a 20 54  tion. */./*. * T
aa00: 63 6c 20 69 6e 74 65 72 66 61 63 65 20 74 6f 20  cl interface to 
aa10: 67 65 74 20 74 68 65 20 68 6f 6d 65 20 64 69 72  get the home dir
aa20: 65 63 74 6f 72 79 20 66 6f 72 20 74 68 65 20 75  ectory for the u
aa30: 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 22  ser making the "
aa40: 63 75 72 72 65 6e 74 22 0a 20 2a 20 46 55 53 45  current". * FUSE
aa50: 20 49 2f 4f 20 72 65 71 75 65 73 74 0a 20 2a 2f   I/O request. */
aa60: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f  .static int tcl_
aa70: 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69  appfs_get_homedi
aa80: 72 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c  r(ClientData cd,
aa90: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
aaa0: 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54  erp, int objc, T
aab0: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
aac0: 6a 76 5b 5d 29 20 7b 0a 09 63 68 61 72 20 2a 68  jv[]) {..char *h
aad0: 6f 6d 65 64 69 72 3b 0a 09 54 63 6c 5f 4f 62 6a  omedir;..Tcl_Obj
aae0: 20 2a 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09   *homedir_obj;..
aaf0: 75 69 64 5f 74 20 66 73 75 69 64 3b 0a 09 73 74  uid_t fsuid;..st
ab00: 61 74 69 63 20 5f 5f 74 68 72 65 61 64 20 54 63  atic __thread Tc
ab10: 6c 5f 4f 62 6a 20 2a 6c 61 73 74 5f 68 6f 6d 65  l_Obj *last_home
ab20: 64 69 72 5f 6f 62 6a 20 3d 20 4e 55 4c 4c 3b 0a  dir_obj = NULL;.
ab30: 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64  .static __thread
ab40: 20 75 69 64 5f 74 20 6c 61 73 74 5f 66 73 75 69   uid_t last_fsui
ab50: 64 20 3d 20 2d 31 3b 0a 0a 20 20 20 20 20 20 20  d = -1;..       
ab60: 20 69 66 20 28 6f 62 6a 63 20 21 3d 20 31 29 20   if (objc != 1) 
ab70: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  {.              
ab80: 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72    Tcl_WrongNumAr
ab90: 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62  gs(interp, 1, ob
aba0: 6a 76 2c 20 4e 55 4c 4c 29 3b 0a 20 20 20 20 20  jv, NULL);.     
abb0: 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72             retur
abc0: 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 20 20  n(TCL_ERROR);.  
abd0: 20 20 20 20 20 20 7d 0a 0a 09 66 73 75 69 64 20        }...fsuid 
abe0: 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  = appfs_get_fsui
abf0: 64 28 29 3b 0a 0a 09 69 66 20 28 66 73 75 69 64  d();...if (fsuid
ac00: 20 3d 3d 20 6c 61 73 74 5f 66 73 75 69 64 20 26   == last_fsuid &
ac10: 26 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f  & last_homedir_o
ac20: 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  bj != NULL) {...
ac30: 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 6c 61  homedir_obj = la
ac40: 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b 0a  st_homedir_obj;.
ac50: 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f  ...Tcl_IncrRefCo
ac60: 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29  unt(homedir_obj)
ac70: 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 68 6f  ;..} else {...ho
ac80: 6d 65 64 69 72 20 3d 20 61 70 70 66 73 5f 67 65  medir = appfs_ge
ac90: 74 5f 68 6f 6d 65 64 69 72 28 61 70 70 66 73 5f  t_homedir(appfs_
aca0: 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09  get_fsuid());...
acb0: 09 69 66 20 28 68 6f 6d 65 64 69 72 20 3d 3d 20  .if (homedir == 
acc0: 4e 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74 75 72  NULL) {....retur
acd0: 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 09  n(TCL_ERROR);...
ace0: 7d 0a 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a  }....homedir_obj
acf0: 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67   = Tcl_NewString
ad00: 4f 62 6a 28 68 6f 6d 65 64 69 72 2c 20 2d 31 29  Obj(homedir, -1)
ad10: 3b 0a 0a 09 09 66 72 65 65 28 68 6f 6d 65 64 69  ;....free(homedi
ad20: 72 29 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52  r);....Tcl_IncrR
ad30: 65 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f  efCount(homedir_
ad40: 6f 62 6a 29 3b 0a 0a 09 09 69 66 20 28 6c 61 73  obj);....if (las
ad50: 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 21 3d  t_homedir_obj !=
ad60: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 54 63 6c 5f   NULL) {....Tcl_
ad70: 44 65 63 72 52 65 66 43 6f 75 6e 74 28 6c 61 73  DecrRefCount(las
ad80: 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a  t_homedir_obj);.
ad90: 09 09 7d 0a 0a 09 09 6c 61 73 74 5f 68 6f 6d 65  ..}....last_home
ada0: 64 69 72 5f 6f 62 6a 20 3d 20 68 6f 6d 65 64 69  dir_obj = homedi
adb0: 72 5f 6f 62 6a 3b 0a 09 09 6c 61 73 74 5f 66 73  r_obj;...last_fs
adc0: 75 69 64 20 3d 20 66 73 75 69 64 3b 0a 0a 09 09  uid = fsuid;....
add0: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74  Tcl_IncrRefCount
ade0: 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09  (homedir_obj);..
adf0: 7d 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53  }..       .Tcl_S
ae00: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65  etObjResult(inte
ae10: 72 70 2c 20 68 6f 6d 65 64 69 72 5f 6f 62 6a 29  rp, homedir_obj)
ae20: 3b 0a 0a 09 54 63 6c 5f 44 65 63 72 52 65 66 43  ;...Tcl_DecrRefC
ae30: 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a  ount(homedir_obj
ae40: 29 3b 0a 0a 20 20 20 20 20 20 20 20 72 65 74 75  );..        retu
ae50: 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73  rn(TCL_OK);.}..s
ae60: 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70  tatic int tcl_ap
ae70: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
ae80: 72 5f 66 73 5f 65 6e 74 65 72 28 43 6c 69 65 6e  r_fs_enter(Clien
ae90: 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e  tData cd, Tcl_In
aea0: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e  terp *interp, in
aeb0: 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20  t objc, Tcl_Obj 
aec0: 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b  *CONST objv[]) {
aed0: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  ..appfs_simulate
aee0: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29  _user_fs_enter()
aef0: 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f  ;...return(TCL_O
af00: 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  K);.}..static in
af10: 74 20 74 63 6c 5f 61 70 70 66 73 5f 73 69 6d 75  t tcl_appfs_simu
af20: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
af30: 76 65 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64  ve(ClientData cd
af40: 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  , Tcl_Interp *in
af50: 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20  terp, int objc, 
af60: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
af70: 62 6a 76 5b 5d 29 20 7b 0a 09 61 70 70 66 73 5f  bjv[]) {..appfs_
af80: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
af90: 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 72 65 74 75  _leave();...retu
afa0: 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73  rn(TCL_OK);.}..s
afb0: 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70  tatic int tcl_ap
afc0: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 43 6c  pfs_get_fsuid(Cl
afd0: 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c  ientData cd, Tcl
afe0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
aff0: 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f   int objc, Tcl_O
b000: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
b010: 29 20 7b 0a 09 75 69 64 5f 74 20 66 73 75 69 64  ) {..uid_t fsuid
b020: 3b 0a 0a 09 66 73 75 69 64 20 3d 20 61 70 70 66  ;...fsuid = appf
b030: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 0a  s_get_fsuid();..
b040: 20 20 20 20 20 20 20 09 54 63 6c 5f 53 65 74 4f         .Tcl_SetO
b050: 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c  bjResult(interp,
b060: 20 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f   Tcl_NewWideIntO
b070: 62 6a 28 66 73 75 69 64 29 29 3b 0a 0a 09 72 65  bj(fsuid));...re
b080: 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a  turn(TCL_OK);.}.
b090: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f  .static int tcl_
b0a0: 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28  appfs_get_fsgid(
b0b0: 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54  ClientData cd, T
b0c0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
b0d0: 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c  p, int objc, Tcl
b0e0: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
b0f0: 5b 5d 29 20 7b 0a 09 67 69 64 5f 74 20 66 73 67  []) {..gid_t fsg
b100: 69 64 3b 0a 0a 09 66 73 67 69 64 20 3d 20 61 70  id;...fsgid = ap
b110: 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28 29 3b  pfs_get_fsgid();
b120: 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53 65  ..       .Tcl_Se
b130: 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72  tObjResult(inter
b140: 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e  p, Tcl_NewWideIn
b150: 74 4f 62 6a 28 66 73 67 69 64 29 29 3b 0a 0a 09  tObj(fsgid));...
b160: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a  return(TCL_OK);.
b170: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  }..static int tc
b180: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  l_appfs_get_path
b190: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73  _info_cache_flus
b1a0: 68 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c  h(ClientData cd,
b1b0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
b1c0: 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54  erp, int objc, T
b1d0: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
b1e0: 6a 76 5b 5d 29 20 7b 0a 09 69 6e 74 20 74 63 6c  jv[]) {..int tcl
b1f0: 5f 72 65 74 3b 0a 09 69 6e 74 20 6e 65 77 5f 73  _ret;..int new_s
b200: 69 7a 65 3b 0a 0a 09 6e 65 77 5f 73 69 7a 65 20  ize;...new_size 
b210: 3d 20 2d 31 3b 0a 0a 09 69 66 20 28 6f 62 6a 63  = -1;...if (objc
b220: 20 3d 3d 20 32 29 20 7b 0a 09 09 74 63 6c 5f 72   == 2) {...tcl_r
b230: 65 74 20 3d 20 54 63 6c 5f 47 65 74 49 6e 74 46  et = Tcl_GetIntF
b240: 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f  romObj(interp, o
b250: 62 6a 76 5b 31 5d 2c 20 26 6e 65 77 5f 73 69 7a  bjv[1], &new_siz
b260: 65 29 3b 0a 09 09 69 66 20 28 74 63 6c 5f 72 65  e);...if (tcl_re
b270: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
b280: 09 09 72 65 74 75 72 6e 28 74 63 6c 5f 72 65 74  ..return(tcl_ret
b290: 29 3b 0a 09 09 7d 0a 09 7d 20 65 6c 73 65 20 69  );...}..} else i
b2a0: 66 20 28 6f 62 6a 63 20 3e 20 32 20 7c 7c 20 6f  f (objc > 2 || o
b2b0: 62 6a 63 20 3c 20 31 29 20 7b 0a 20 20 20 20 20  bjc < 1) {.     
b2c0: 20 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f 57             Tcl_W
b2d0: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
b2e0: 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 3f 6e  rp, 1, objv, "?n
b2f0: 65 77 5f 63 61 63 68 65 5f 73 69 7a 65 3f 22 29  ew_cache_size?")
b300: 3b 0a 09 09 72 65 74 75 72 6e 28 54 43 4c 5f 45  ;...return(TCL_E
b310: 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  RROR);..}...appf
b320: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
b330: 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c 20  cache_flush(-1, 
b340: 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a 09 72 65 74  new_size);...ret
b350: 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a  urn(TCL_OK);.}..
b360: 73 74 61 74 69 63 20 69 6e 74 20 41 70 70 66 73  static int Appfs
b370: 64 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72  d_Init(Tcl_Inter
b380: 70 20 2a 69 6e 74 65 72 70 29 20 7b 0a 23 69 66  p *interp) {.#if
b390: 64 65 66 20 55 53 45 5f 54 43 4c 5f 53 54 55 42  def USE_TCL_STUB
b3a0: 53 0a 09 69 66 20 28 54 63 6c 5f 49 6e 69 74 53  S..if (Tcl_InitS
b3b0: 74 75 62 73 28 69 6e 74 65 72 70 2c 20 54 43 4c  tubs(interp, TCL
b3c0: 5f 56 45 52 53 49 4f 4e 2c 20 30 29 20 3d 3d 20  _VERSION, 0) == 
b3d0: 30 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 54  0L) {...return(T
b3e0: 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 23 65  CL_ERROR);..}.#e
b3f0: 6e 64 69 66 0a 0a 09 54 63 6c 5f 43 72 65 61 74  ndif...Tcl_Creat
b400: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
b410: 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74  rp, "appfsd::get
b420: 5f 68 6f 6d 65 64 69 72 22 2c 20 74 63 6c 5f 61  _homedir", tcl_a
b430: 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72  ppfs_get_homedir
b440: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09  , NULL, NULL);..
b450: 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d  Tcl_CreateObjCom
b460: 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70  mand(interp, "ap
b470: 70 66 73 64 3a 3a 67 65 74 5f 66 73 75 69 64 22  pfsd::get_fsuid"
b480: 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f  , tcl_appfs_get_
b490: 66 73 75 69 64 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  fsuid, NULL, NUL
b4a0: 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f  L);..Tcl_CreateO
b4b0: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
b4c0: 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 66  , "appfsd::get_f
b4d0: 73 67 69 64 22 2c 20 74 63 6c 5f 61 70 70 66 73  sgid", tcl_appfs
b4e0: 5f 67 65 74 5f 66 73 67 69 64 2c 20 4e 55 4c 4c  _get_fsgid, NULL
b4f0: 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72  , NULL);..Tcl_Cr
b500: 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69  eateObjCommand(i
b510: 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a  nterp, "appfsd::
b520: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
b530: 5f 65 6e 74 65 72 22 2c 20 74 63 6c 5f 61 70 70  _enter", tcl_app
b540: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
b550: 5f 66 73 5f 65 6e 74 65 72 2c 20 4e 55 4c 4c 2c  _fs_enter, NULL,
b560: 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65   NULL);..Tcl_Cre
b570: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
b580: 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 73  terp, "appfsd::s
b590: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
b5a0: 6c 65 61 76 65 22 2c 20 74 63 6c 5f 61 70 70 66  leave", tcl_appf
b5b0: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
b5c0: 66 73 5f 6c 65 61 76 65 2c 20 4e 55 4c 4c 2c 20  fs_leave, NULL, 
b5d0: 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61  NULL);..Tcl_Crea
b5e0: 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74  teObjCommand(int
b5f0: 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65  erp, "appfsd::ge
b600: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
b610: 65 5f 66 6c 75 73 68 22 2c 20 74 63 6c 5f 61 70  e_flush", tcl_ap
b620: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
b630: 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 2c 20 4e  o_cache_flush, N
b640: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 54 63  ULL, NULL);...Tc
b650: 6c 5f 50 6b 67 50 72 6f 76 69 64 65 28 69 6e 74  l_PkgProvide(int
b660: 65 72 70 2c 20 22 61 70 70 66 73 64 22 2c 20 22  erp, "appfsd", "
b670: 31 2e 30 22 29 3b 0a 0a 09 72 65 74 75 72 6e 28  1.0");...return(
b680: 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 2f 2a 0a 20  TCL_OK);.}../*. 
b690: 2a 20 48 6f 74 2d 72 65 73 74 61 72 74 20 73 75  * Hot-restart su
b6a0: 70 70 6f 72 74 0a 20 2a 2f 0a 2f 2a 20 49 6e 69  pport. */./* Ini
b6b0: 74 69 61 74 65 20 61 20 68 6f 74 2d 72 65 73 74  tiate a hot-rest
b6c0: 61 72 74 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f  art */.static vo
b6d0: 69 64 20 61 70 70 66 73 5f 68 6f 74 5f 72 65 73  id appfs_hot_res
b6e0: 74 61 72 74 28 76 6f 69 64 29 20 7b 0a 09 41 50  tart(void) {..AP
b6f0: 50 46 53 5f 44 45 42 55 47 28 22 41 73 6b 65 64  PFS_DEBUG("Asked
b700: 20 74 6f 20 69 6e 69 74 69 61 74 65 20 68 6f 74   to initiate hot
b710: 20 72 65 73 74 61 72 74 22 29 3b 0a 0a 09 61 70   restart");...ap
b720: 70 66 73 5f 74 63 6c 5f 52 65 73 65 74 49 6e 74  pfs_tcl_ResetInt
b730: 65 72 70 73 28 29 3b 0a 0a 09 61 70 70 66 73 5f  erps();...appfs_
b740: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
b750: 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c 20 2d 31  che_flush(-1, -1
b760: 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a  );...return;.}..
b770: 2f 2a 0a 20 2a 20 53 69 67 6e 61 6c 20 68 61 6e  /*. * Signal han
b780: 64 6c 65 72 0a 20 2a 20 20 20 20 20 20 20 20 20  dler. *         
b790: 53 49 47 48 55 50 20 69 6e 69 74 69 61 74 65 73  SIGHUP initiates
b7a0: 20 61 20 68 6f 74 20 72 65 73 74 61 72 74 0a 20   a hot restart. 
b7b0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  */.static void a
b7c0: 70 70 66 73 5f 73 69 67 6e 61 6c 5f 68 61 6e 64  ppfs_signal_hand
b7d0: 6c 65 72 28 69 6e 74 20 73 69 67 29 20 7b 0a 09  ler(int sig) {..
b7e0: 2f 2a 20 44 6f 20 6e 6f 74 20 68 61 6e 64 6c 65  /* Do not handle
b7f0: 20 73 69 67 6e 61 6c 73 20 75 6e 74 69 6c 20 46   signals until F
b800: 55 53 45 20 68 61 73 20 62 65 65 6e 20 73 74 61  USE has been sta
b810: 72 74 65 64 20 2a 2f 0a 09 69 66 20 28 21 61 70  rted */..if (!ap
b820: 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64  pfs_fuse_started
b830: 29 20 7b 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d  ) {...return;..}
b840: 0a 0a 09 2f 2a 20 52 65 71 75 65 73 74 20 74 6f  .../* Request to
b850: 20 70 65 72 66 6f 72 6d 20 61 20 22 68 6f 74 22   perform a "hot"
b860: 20 72 65 73 74 61 72 74 20 2a 2f 0a 09 69 66 20   restart */..if 
b870: 28 73 69 67 20 3d 3d 20 53 49 47 48 55 50 29 20  (sig == SIGHUP) 
b880: 7b 0a 09 09 61 70 70 66 73 5f 68 6f 74 5f 72 65  {...appfs_hot_re
b890: 73 74 61 72 74 28 29 3b 0a 09 7d 0a 0a 09 72 65  start();..}...re
b8a0: 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54  turn;.}../*. * T
b8b0: 65 72 6d 69 6e 61 74 65 20 61 20 74 68 72 65 61  erminate a threa
b8c0: 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  d. */.static voi
b8d0: 64 20 61 70 70 66 73 5f 74 65 72 6d 69 6e 61 74  d appfs_terminat
b8e0: 65 5f 69 6e 74 65 72 70 5f 61 6e 64 5f 74 68 72  e_interp_and_thr
b8f0: 65 61 64 28 76 6f 69 64 20 2a 5f 69 6e 74 65 72  ead(void *_inter
b900: 70 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  p) {..Tcl_Interp
b910: 20 2a 69 6e 74 65 72 70 3b 0a 0a 09 41 50 50 46   *interp;...APPF
b920: 53 5f 44 45 42 55 47 28 22 43 61 6c 6c 65 64 3a  S_DEBUG("Called:
b930: 20 5f 69 6e 74 65 72 70 20 3d 20 25 70 22 2c 20   _interp = %p", 
b940: 5f 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28  _interp);...if (
b950: 5f 69 6e 74 65 72 70 20 21 3d 20 4e 55 4c 4c 29  _interp != NULL)
b960: 20 7b 0a 09 09 69 6e 74 65 72 70 20 3d 20 5f 69   {...interp = _i
b970: 6e 74 65 72 70 3b 0a 0a 09 09 41 50 50 46 53 5f  nterp;....APPFS_
b980: 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69  DEBUG("Terminati
b990: 6e 67 20 69 6e 74 65 72 70 72 65 74 65 72 20 64  ng interpreter d
b9a0: 75 65 20 74 6f 20 74 68 72 65 61 64 20 74 65 72  ue to thread ter
b9b0: 6d 69 6e 61 74 69 6f 6e 22 29 3b 0a 0a 09 09 61  mination");....a
b9c0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
b9d0: 28 0a 09 09 09 54 63 6c 5f 44 65 6c 65 74 65 49  (....Tcl_DeleteI
b9e0: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 09  nterp(interp);..
b9f0: 09 29 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 41  .)..} else {...A
ba00: 50 50 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d  PPFS_DEBUG("Term
ba10: 69 6e 61 74 69 6e 67 20 74 68 72 65 61 64 20 77  inating thread w
ba20: 69 74 68 20 6e 6f 20 69 6e 74 65 72 70 72 65 74  ith no interpret
ba30: 65 72 22 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  er");..}...appfs
ba40: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
ba50: 54 63 6c 5f 46 69 6e 61 6c 69 7a 65 54 68 72 65  Tcl_FinalizeThre
ba60: 61 64 28 29 3b 0a 09 29 0a 0a 09 72 65 74 75 72  ad();..)...retur
ba70: 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 6f 6d 6d  n;.}../*. * Comm
ba80: 61 6e 64 2d 6c 69 6e 65 20 70 61 72 73 69 6e 67  and-line parsing
ba90: 20 74 6f 6f 6c 73 0a 20 2a 2f 0a 73 74 61 74 69   tools. */.stati
baa0: 63 20 76 6f 69 64 20 61 70 70 66 73 5f 70 72 69  c void appfs_pri
bab0: 6e 74 5f 68 65 6c 70 28 46 49 4c 45 20 2a 63 68  nt_help(FILE *ch
bac0: 61 6e 6e 65 6c 29 20 7b 0a 09 66 70 72 69 6e 74  annel) {..fprint
bad0: 66 28 63 68 61 6e 6e 65 6c 2c 20 22 55 73 61 67  f(channel, "Usag
bae0: 65 3a 20 7b 61 70 70 66 73 64 7c 6d 6f 75 6e 74  e: {appfsd|mount
baf0: 2e 61 70 70 66 73 7d 20 5b 2d 6f 20 3c 6f 70 74  .appfs} [-o <opt
bb00: 69 6f 6e 3e 5d 20 5b 2d 64 66 73 68 5d 20 3c 63  ion>] [-dfsh] <c
bb10: 61 63 68 65 64 69 72 3e 20 3c 6d 6f 75 6e 74 70  achedir> <mountp
bb20: 6f 69 6e 74 3e 5c 6e 22 29 3b 0a 09 66 70 72 69  oint>\n");..fpri
bb30: 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 5c 6e  ntf(channel, "\n
bb40: 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61  ");..fprintf(cha
bb50: 6e 6e 65 6c 2c 20 22 4f 70 74 69 6f 6e 73 3a 5c  nnel, "Options:\
bb60: 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68  n");..fprintf(ch
bb70: 61 6e 6e 65 6c 2c 20 22 20 20 2d 64 20 20 20 20  annel, "  -d    
bb80: 20 20 20 20 20 20 20 20 20 20 45 6e 61 62 6c 65            Enable
bb90: 20 46 55 53 45 20 64 65 62 75 67 20 6d 6f 64 65   FUSE debug mode
bba0: 2e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28  .\n");..fprintf(
bbb0: 63 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 66 20 20  channel, "  -f  
bbc0: 20 20 20 20 20 20 20 20 20 20 20 20 52 75 6e 20              Run 
bbd0: 69 6e 20 66 6f 72 65 67 72 6f 75 6e 64 2e 5c 6e  in foreground.\n
bbe0: 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61  ");..fprintf(cha
bbf0: 6e 6e 65 6c 2c 20 22 20 20 2d 73 20 20 20 20 20  nnel, "  -s     
bc00: 20 20 20 20 20 20 20 20 20 45 6e 61 62 6c 65 20           Enable 
bc10: 73 69 6e 67 6c 65 20 74 68 72 65 61 64 65 64 20  single threaded 
bc20: 6d 6f 64 65 2e 5c 6e 22 29 3b 0a 09 66 70 72 69  mode.\n");..fpri
bc30: 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20 20  ntf(channel, "  
bc40: 2d 68 20 20 20 20 20 20 20 20 20 20 20 20 20 20  -h              
bc50: 47 69 76 65 20 74 68 69 73 20 68 65 6c 70 2e 5c  Give this help.\
bc60: 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68  n");..fprintf(ch
bc70: 61 6e 6e 65 6c 2c 20 22 20 20 2d 6f 20 6e 6f 74  annel, "  -o not
bc80: 68 72 65 61 64 73 20 20 20 20 45 6e 61 62 6c 65  hreads    Enable
bc90: 20 73 69 6e 67 6c 65 20 74 68 72 65 61 64 65 64   single threaded
bca0: 20 6d 6f 64 65 2e 5c 6e 22 29 3b 0a 09 66 70 72   mode.\n");..fpr
bcb0: 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20  intf(channel, " 
bcc0: 20 2d 6f 20 61 6c 6c 6f 77 5f 6f 74 68 65 72 20   -o allow_other 
bcd0: 20 41 6c 6c 6f 77 20 6f 74 68 65 72 20 75 73 65   Allow other use
bce0: 72 73 20 74 6f 20 61 63 63 65 73 73 20 74 68 69  rs to access thi
bcf0: 73 20 6d 6f 75 6e 74 70 6f 69 6e 74 20 28 64 65  s mountpoint (de
bd00: 66 61 75 6c 74 5c 6e 22 29 3b 0a 09 66 70 72 69  fault\n");..fpri
bd10: 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20 20  ntf(channel, "  
bd20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
bd30: 69 66 20 72 6f 6f 74 29 2e 5c 6e 22 29 3b 0a 0a  if root).\n");..
bd40: 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74  .return;.}..stat
bd50: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 6f 70 74  ic int appfs_opt
bd60: 5f 70 61 72 73 65 28 69 6e 74 20 61 72 67 63 2c  _parse(int argc,
bd70: 20 63 68 61 72 20 2a 2a 61 72 67 76 2c 20 20 73   char **argv,  s
bd80: 74 72 75 63 74 20 66 75 73 65 5f 61 72 67 73 20  truct fuse_args 
bd90: 2a 61 72 67 73 29 20 7b 0a 09 69 6e 74 20 63 68  *args) {..int ch
bda0: 3b 0a 09 63 68 61 72 20 2a 6f 70 74 73 74 72 2c  ;..char *optstr,
bdb0: 20 2a 6f 70 74 73 74 72 5f 6e 65 78 74 2c 20 2a   *optstr_next, *
bdc0: 6f 70 74 73 74 72 5f 73 3b 0a 09 63 68 61 72 20  optstr_s;..char 
bdd0: 66 61 6b 65 5f 61 72 67 5b 33 5d 20 3d 20 7b 27  fake_arg[3] = {'
bde0: 2d 27 2c 20 30 2c 20 30 7d 3b 0a 0a 09 2f 2a 0a  -', 0, 0};.../*.
bdf0: 09 20 2a 20 44 65 66 61 75 6c 74 20 76 61 6c 75  . * Default valu
be00: 65 73 0a 09 20 2a 2f 0a 23 69 66 64 65 66 20 54  es.. */.#ifdef T
be10: 43 4c 5f 54 48 52 45 41 44 53 0a 09 61 70 70 66  CL_THREADS..appf
be20: 73 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 20 3d  s_threaded_tcl =
be30: 20 31 3b 0a 23 65 6c 73 65 0a 09 61 70 70 66 73   1;.#else..appfs
be40: 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 20 3d 20  _threaded_tcl = 
be50: 30 3b 0a 23 65 6e 64 69 66 0a 0a 09 2f 2a 2a 0a  0;.#endif.../**.
be60: 09 20 2a 2a 20 41 64 64 20 46 55 53 45 20 61 72  . ** Add FUSE ar
be70: 67 75 6d 65 6e 74 73 20 77 68 69 63 68 20 77 65  guments which we
be80: 20 61 6c 77 61 79 73 20 73 75 70 70 6c 79 0a 09   always supply..
be90: 20 2a 2a 2f 0a 09 66 75 73 65 5f 6f 70 74 5f 61   **/..fuse_opt_a
bea0: 64 64 5f 61 72 67 28 61 72 67 73 2c 20 22 2d 6f  dd_arg(args, "-o
beb0: 64 65 66 61 75 6c 74 5f 70 65 72 6d 69 73 73 69  default_permissi
bec0: 6f 6e 73 2c 66 73 6e 61 6d 65 3d 61 70 70 66 73  ons,fsname=appfs
bed0: 2c 73 75 62 74 79 70 65 3d 61 70 70 66 73 64 2c  ,subtype=appfsd,
bee0: 75 73 65 5f 69 6e 6f 2c 65 6e 74 72 79 5f 74 69  use_ino,entry_ti
bef0: 6d 65 6f 75 74 3d 30 2c 61 74 74 72 5f 74 69 6d  meout=0,attr_tim
bf00: 65 6f 75 74 3d 30 2c 62 69 67 5f 77 72 69 74 65  eout=0,big_write
bf10: 73 2c 69 6e 74 72 2c 68 61 72 64 5f 72 65 6d 6f  s,intr,hard_remo
bf20: 76 65 22 29 3b 0a 0a 09 69 66 20 28 67 65 74 75  ve");...if (getu
bf30: 69 64 28 29 20 3d 3d 20 30 29 20 7b 0a 09 09 66  id() == 0) {...f
bf40: 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72  use_opt_parse(ar
bf50: 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20  gs, NULL, NULL, 
bf60: 4e 55 4c 4c 29 3b 0a 09 09 66 75 73 65 5f 6f 70  NULL);...fuse_op
bf70: 74 5f 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20  t_add_arg(args, 
bf80: 22 2d 6f 61 6c 6c 6f 77 5f 6f 74 68 65 72 22 29  "-oallow_other")
bf90: 3b 0a 0a 09 09 2f 2a 0a 09 09 20 2a 20 54 68 69  ;..../*... * Thi
bfa0: 73 20 73 68 6f 75 6c 64 20 67 65 6e 65 72 61 6c  s should general
bfb0: 6c 79 20 62 65 20 61 76 6f 69 64 65 64 2c 20 62  ly be avoided, b
bfc0: 75 74 20 69 66 20 74 68 65 72 65 20 61 72 65 20  ut if there are 
bfd0: 73 65 63 75 72 69 74 79 0a 09 09 20 2a 20 63 6f  security... * co
bfe0: 6e 63 65 72 6e 73 20 73 75 69 64 20 63 61 6e 20  ncerns suid can 
bff0: 62 65 20 64 69 73 61 62 6c 65 64 20 63 6f 6d 70  be disabled comp
c000: 6c 65 74 65 6c 79 20 6f 6e 20 74 68 65 20 63 6f  letely on the co
c010: 6d 6d 61 6e 64 6c 69 6e 65 0a 09 09 20 2a 2f 0a  mmandline... */.
c020: 09 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65  ..fuse_opt_parse
c030: 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c  (args, NULL, NUL
c040: 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09 66 75 73 65  L, NULL);...fuse
c050: 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72 67  _opt_add_arg(arg
c060: 73 2c 20 22 2d 6f 73 75 69 64 22 29 3b 0a 09 7d  s, "-osuid");..}
c070: 0a 0a 09 77 68 69 6c 65 20 28 28 63 68 20 3d 20  ...while ((ch = 
c080: 67 65 74 6f 70 74 28 61 72 67 63 2c 20 61 72 67  getopt(argc, arg
c090: 76 2c 20 22 64 66 73 68 76 6f 3a 22 29 29 20 21  v, "dfshvo:")) !
c0a0: 3d 20 2d 31 29 20 7b 0a 09 09 73 77 69 74 63 68  = -1) {...switch
c0b0: 20 28 63 68 29 20 7b 0a 09 09 09 63 61 73 65 20   (ch) {....case 
c0c0: 27 76 27 3a 0a 09 09 09 09 2f 2a 20 49 67 6e 6f  'v':...../* Igno
c0d0: 72 65 64 20 2a 2f 0a 09 09 09 09 62 72 65 61 6b  red */.....break
c0e0: 3b 0a 09 09 09 63 61 73 65 20 27 6f 27 3a 0a 09  ;....case 'o':..
c0f0: 09 09 09 6f 70 74 73 74 72 5f 6e 65 78 74 20 3d  ...optstr_next =
c100: 20 6f 70 74 73 74 72 20 3d 20 6f 70 74 73 74 72   optstr = optstr
c110: 5f 73 20 3d 20 73 74 72 64 75 70 28 6f 70 74 61  _s = strdup(opta
c120: 72 67 29 3b 0a 0a 09 09 09 09 77 68 69 6c 65 20  rg);......while 
c130: 28 31 29 20 7b 0a 09 09 09 09 09 6f 70 74 73 74  (1) {......optst
c140: 72 20 3d 20 6f 70 74 73 74 72 5f 6e 65 78 74 3b  r = optstr_next;
c150: 0a 0a 09 09 09 09 09 69 66 20 28 21 6f 70 74 73  .......if (!opts
c160: 74 72 29 20 7b 0a 09 09 09 09 09 09 62 72 65 61  tr) {.......brea
c170: 6b 3b 0a 09 09 09 09 09 7d 0a 0a 09 09 09 09 09  k;......}.......
c180: 6f 70 74 73 74 72 5f 6e 65 78 74 20 3d 20 73 74  optstr_next = st
c190: 72 63 68 72 28 6f 70 74 73 74 72 2c 20 27 2c 27  rchr(optstr, ','
c1a0: 29 3b 0a 09 09 09 09 09 69 66 20 28 6f 70 74 73  );......if (opts
c1b0: 74 72 5f 6e 65 78 74 29 20 7b 0a 09 09 09 09 09  tr_next) {......
c1c0: 09 2a 6f 70 74 73 74 72 5f 6e 65 78 74 20 3d 20  .*optstr_next = 
c1d0: 27 5c 30 27 3b 0a 09 09 09 09 09 09 6f 70 74 73  '\0';.......opts
c1e0: 74 72 5f 6e 65 78 74 2b 2b 3b 0a 09 09 09 09 09  tr_next++;......
c1f0: 7d 0a 0a 09 09 09 09 09 69 66 20 28 73 74 72 63  }.......if (strc
c200: 6d 70 28 6f 70 74 73 74 72 2c 20 22 6e 6f 74 68  mp(optstr, "noth
c210: 72 65 61 64 73 22 29 20 3d 3d 20 30 29 20 7b 0a  reads") == 0) {.
c220: 09 09 09 09 09 09 41 50 50 46 53 5f 44 45 42 55  ......APPFS_DEBU
c230: 47 28 22 50 61 73 73 69 6e 67 20 6f 70 74 69 6f  G("Passing optio
c240: 6e 20 74 6f 20 46 55 53 45 3a 20 2d 73 22 29 3b  n to FUSE: -s");
c250: 0a 0a 09 09 09 09 09 09 66 75 73 65 5f 6f 70 74  ........fuse_opt
c260: 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c  _parse(args, NUL
c270: 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  L, NULL, NULL);.
c280: 09 09 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 61  ......fuse_opt_a
c290: 64 64 5f 61 72 67 28 61 72 67 73 2c 20 22 2d 73  dd_arg(args, "-s
c2a0: 22 29 3b 0a 0a 09 09 09 09 09 09 61 70 70 66 73  ");........appfs
c2b0: 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 20 3d 20  _threaded_tcl = 
c2c0: 30 3b 0a 09 09 09 09 09 7d 20 65 6c 73 65 20 69  0;......} else i
c2d0: 66 20 28 73 74 72 63 6d 70 28 6f 70 74 73 74 72  f (strcmp(optstr
c2e0: 2c 20 22 61 6c 6c 6f 77 5f 6f 74 68 65 72 22 29  , "allow_other")
c2f0: 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09 09 41   == 0) {.......A
c300: 50 50 46 53 5f 44 45 42 55 47 28 22 50 61 73 73  PPFS_DEBUG("Pass
c310: 69 6e 67 20 6f 70 74 69 6f 6e 20 74 6f 20 46 55  ing option to FU
c320: 53 45 3a 20 2d 6f 20 61 6c 6c 6f 77 5f 6f 74 68  SE: -o allow_oth
c330: 65 72 22 29 3b 0a 0a 09 09 09 09 09 09 66 75 73  er");........fus
c340: 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67 73  e_opt_parse(args
c350: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55  , NULL, NULL, NU
c360: 4c 4c 29 3b 0a 09 09 09 09 09 09 66 75 73 65 5f  LL);.......fuse_
c370: 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72 67 73  opt_add_arg(args
c380: 2c 20 22 2d 6f 61 6c 6c 6f 77 5f 6f 74 68 65 72  , "-oallow_other
c390: 22 29 3b 0a 09 09 09 09 09 7d 20 65 6c 73 65 20  ");......} else 
c3a0: 69 66 20 28 73 74 72 63 6d 70 28 6f 70 74 73 74  if (strcmp(optst
c3b0: 72 2c 20 22 72 77 22 29 20 3d 3d 20 30 29 20 7b  r, "rw") == 0) {
c3c0: 0a 09 09 09 09 09 09 2f 2a 20 49 67 6e 6f 72 65  ......./* Ignore
c3d0: 64 20 2a 2f 0a 09 09 09 09 09 7d 20 65 6c 73 65  d */......} else
c3e0: 20 7b 0a 09 09 09 09 09 09 66 70 72 69 6e 74 66   {.......fprintf
c3f0: 28 73 74 64 65 72 72 2c 20 22 61 70 70 66 73 64  (stderr, "appfsd
c400: 3a 20 69 6e 76 61 6c 69 64 20 6f 70 74 69 6f 6e  : invalid option
c410: 3a 20 5c 22 2d 6f 20 25 73 5c 22 5c 6e 22 2c 20  : \"-o %s\"\n", 
c420: 6f 70 74 73 74 72 29 3b 0a 0a 09 09 09 09 09 09  optstr);........
c430: 66 72 65 65 28 6f 70 74 73 74 72 5f 73 29 3b 0a  free(optstr_s);.
c440: 0a 09 09 09 09 09 09 72 65 74 75 72 6e 28 31 29  .......return(1)
c450: 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a  ;......}.....}..
c460: 09 09 09 09 66 72 65 65 28 6f 70 74 73 74 72 5f  ....free(optstr_
c470: 73 29 3b 0a 0a 09 09 09 09 62 72 65 61 6b 3b 0a  s);......break;.
c480: 09 09 09 63 61 73 65 20 27 64 27 3a 0a 09 09 09  ...case 'd':....
c490: 63 61 73 65 20 27 66 27 3a 0a 09 09 09 63 61 73  case 'f':....cas
c4a0: 65 20 27 73 27 3a 0a 09 09 09 09 69 66 20 28 63  e 's':.....if (c
c4b0: 68 20 3d 3d 20 27 73 27 29 20 7b 0a 09 09 09 09  h == 's') {.....
c4c0: 09 61 70 70 66 73 5f 74 68 72 65 61 64 65 64 5f  .appfs_threaded_
c4d0: 74 63 6c 20 3d 20 30 3b 0a 09 09 09 09 7d 0a 0a  tcl = 0;.....}..
c4e0: 09 09 09 09 66 61 6b 65 5f 61 72 67 5b 31 5d 20  ....fake_arg[1] 
c4f0: 3d 20 63 68 3b 0a 0a 09 09 09 09 41 50 50 46 53  = ch;......APPFS
c500: 5f 44 45 42 55 47 28 22 50 61 73 73 69 6e 67 20  _DEBUG("Passing 
c510: 6f 70 74 69 6f 6e 20 74 6f 20 46 55 53 45 3a 20  option to FUSE: 
c520: 25 73 22 2c 20 66 61 6b 65 5f 61 72 67 29 3b 0a  %s", fake_arg);.
c530: 0a 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 70 61  .....fuse_opt_pa
c540: 72 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20  rse(args, NULL, 
c550: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09 09  NULL, NULL);....
c560: 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72  .fuse_opt_add_ar
c570: 67 28 61 72 67 73 2c 20 66 61 6b 65 5f 61 72 67  g(args, fake_arg
c580: 29 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09  );.....break;...
c590: 09 63 61 73 65 20 27 68 27 3a 0a 09 09 09 09 61  .case 'h':.....a
c5a0: 70 70 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28  ppfs_print_help(
c5b0: 73 74 64 6f 75 74 29 3b 0a 0a 09 09 09 09 72 65  stdout);......re
c5c0: 74 75 72 6e 28 2d 31 29 3b 0a 09 09 09 63 61 73  turn(-1);....cas
c5d0: 65 20 27 3a 27 3a 0a 09 09 09 63 61 73 65 20 27  e ':':....case '
c5e0: 3f 27 3a 0a 09 09 09 64 65 66 61 75 6c 74 3a 0a  ?':....default:.
c5f0: 09 09 09 09 61 70 70 66 73 5f 70 72 69 6e 74 5f  ....appfs_print_
c600: 68 65 6c 70 28 73 74 64 65 72 72 29 3b 0a 0a 09  help(stderr);...
c610: 09 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 09  ...return(1);...
c620: 7d 0a 09 7d 0a 0a 09 69 66 20 28 28 6f 70 74 69  }..}...if ((opti
c630: 6e 64 20 2b 20 32 29 20 21 3d 20 61 72 67 63 29  nd + 2) != argc)
c640: 20 7b 0a 09 09 69 66 20 28 28 6f 70 74 69 6e 64   {...if ((optind
c650: 20 2b 20 32 29 20 3c 20 61 72 67 63 29 20 7b 0a   + 2) < argc) {.
c660: 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
c670: 72 2c 20 22 54 6f 6f 20 6d 61 6e 79 20 61 72 67  r, "Too many arg
c680: 75 6d 65 6e 74 73 5c 6e 22 29 3b 0a 09 09 7d 20  uments\n");...} 
c690: 65 6c 73 65 20 7b 0a 09 09 09 66 70 72 69 6e 74  else {....fprint
c6a0: 66 28 73 74 64 65 72 72 2c 20 22 4d 69 73 73 69  f(stderr, "Missi
c6b0: 6e 67 20 63 61 63 68 65 64 69 72 20 6f 72 20 6d  ng cachedir or m
c6c0: 6f 75 6e 74 70 6f 69 6e 74 5c 6e 22 29 3b 0a 09  ountpoint\n");..
c6d0: 09 7d 0a 0a 09 09 61 70 70 66 73 5f 70 72 69 6e  .}....appfs_prin
c6e0: 74 5f 68 65 6c 70 28 73 74 64 65 72 72 29 3b 0a  t_help(stderr);.
c6f0: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
c700: 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65 74 20 63 61  .../*.. * Set ca
c710: 63 68 65 20 64 69 72 20 61 73 20 66 69 72 73 74  che dir as first
c720: 20 61 72 67 75 6d 65 6e 74 20 28 74 68 65 20 22   argument (the "
c730: 64 65 76 69 63 65 22 2c 20 65 73 73 65 6e 74 69  device", essenti
c740: 61 6c 6c 79 29 0a 09 20 2a 2f 0a 09 61 70 70 66  ally).. */..appf
c750: 73 5f 63 61 63 68 65 64 69 72 20 3d 20 61 72 67  s_cachedir = arg
c760: 76 5b 6f 70 74 69 6e 64 5d 3b 0a 0a 09 2f 2a 0a  v[optind];.../*.
c770: 09 20 2a 20 50 61 73 73 20 74 68 65 20 72 65 6d  . * Pass the rem
c780: 61 69 6e 69 6e 67 20 61 72 67 75 6d 65 6e 74 20  aining argument 
c790: 74 6f 20 46 55 53 45 20 61 73 20 74 68 65 20 64  to FUSE as the d
c7a0: 69 72 65 63 74 6f 72 79 0a 09 20 2a 2f 0a 09 66  irectory.. */..f
c7b0: 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72  use_opt_parse(ar
c7c0: 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20  gs, NULL, NULL, 
c7d0: 4e 55 4c 4c 29 3b 0a 09 66 75 73 65 5f 6f 70 74  NULL);..fuse_opt
c7e0: 5f 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20 61  _add_arg(args, a
c7f0: 72 67 76 5b 6f 70 74 69 6e 64 20 2b 20 31 5d 29  rgv[optind + 1])
c800: 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  ;...return(0);.}
c810: 0a 0a 0a 2f 2a 0a 20 2a 20 46 55 53 45 20 6f 70  .../*. * FUSE op
c820: 65 72 61 74 69 6f 6e 73 20 73 74 72 75 63 74 75  erations structu
c830: 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 73 74  re. */.static st
c840: 72 75 63 74 20 66 75 73 65 5f 6f 70 65 72 61 74  ruct fuse_operat
c850: 69 6f 6e 73 20 61 70 70 66 73 5f 6f 70 65 72 61  ions appfs_opera
c860: 74 69 6f 6e 73 20 3d 20 7b 0a 09 2e 67 65 74 61  tions = {...geta
c870: 74 74 72 20 20 20 3d 20 61 70 70 66 73 5f 66 75  ttr   = appfs_fu
c880: 73 65 5f 67 65 74 61 74 74 72 2c 0a 09 2e 72 65  se_getattr,...re
c890: 61 64 64 69 72 20 20 20 3d 20 61 70 70 66 73 5f  addir   = appfs_
c8a0: 66 75 73 65 5f 72 65 61 64 64 69 72 2c 0a 09 2e  fuse_readdir,...
c8b0: 72 65 61 64 6c 69 6e 6b 20 20 3d 20 61 70 70 66  readlink  = appf
c8c0: 73 5f 66 75 73 65 5f 72 65 61 64 6c 69 6e 6b 2c  s_fuse_readlink,
c8d0: 0a 09 2e 6f 70 65 6e 20 20 20 20 20 20 3d 20 61  ...open      = a
c8e0: 70 70 66 73 5f 66 75 73 65 5f 6f 70 65 6e 2c 0a  ppfs_fuse_open,.
c8f0: 09 2e 72 65 6c 65 61 73 65 20 20 20 3d 20 61 70  ..release   = ap
c900: 70 66 73 5f 66 75 73 65 5f 63 6c 6f 73 65 2c 0a  pfs_fuse_close,.
c910: 09 2e 72 65 61 64 20 20 20 20 20 20 3d 20 61 70  ..read      = ap
c920: 70 66 73 5f 66 75 73 65 5f 72 65 61 64 2c 0a 09  pfs_fuse_read,..
c930: 2e 77 72 69 74 65 20 20 20 20 20 3d 20 61 70 70  .write     = app
c940: 66 73 5f 66 75 73 65 5f 77 72 69 74 65 2c 0a 09  fs_fuse_write,..
c950: 2e 6d 6b 6e 6f 64 20 20 20 20 20 3d 20 61 70 70  .mknod     = app
c960: 66 73 5f 66 75 73 65 5f 6d 6b 6e 6f 64 2c 0a 09  fs_fuse_mknod,..
c970: 2e 63 72 65 61 74 65 20 20 20 20 3d 20 61 70 70  .create    = app
c980: 66 73 5f 66 75 73 65 5f 63 72 65 61 74 65 2c 0a  fs_fuse_create,.
c990: 09 2e 74 72 75 6e 63 61 74 65 20 20 3d 20 61 70  ..truncate  = ap
c9a0: 70 66 73 5f 66 75 73 65 5f 74 72 75 6e 63 61 74  pfs_fuse_truncat
c9b0: 65 2c 0a 09 2e 75 6e 6c 69 6e 6b 20 20 20 20 3d  e,...unlink    =
c9c0: 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69   appfs_fuse_unli
c9d0: 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 72 6d 64 69  nk_rmdir,...rmdi
c9e0: 72 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  r     = appfs_fu
c9f0: 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72 2c  se_unlink_rmdir,
ca00: 0a 09 2e 6d 6b 64 69 72 20 20 20 20 20 3d 20 61  ...mkdir     = a
ca10: 70 70 66 73 5f 66 75 73 65 5f 6d 6b 64 69 72 2c  ppfs_fuse_mkdir,
ca20: 0a 09 2e 63 68 6d 6f 64 20 20 20 20 20 3d 20 61  ...chmod     = a
ca30: 70 70 66 73 5f 66 75 73 65 5f 63 68 6d 6f 64 2c  ppfs_fuse_chmod,
ca40: 0a 09 2e 73 79 6d 6c 69 6e 6b 20 20 20 3d 20 61  ...symlink   = a
ca50: 70 70 66 73 5f 66 75 73 65 5f 73 79 6d 6c 69 6e  ppfs_fuse_symlin
ca60: 6b 2c 0a 7d 3b 0a 0a 2f 2a 0a 20 2a 20 45 6e 74  k,.};../*. * Ent
ca70: 72 79 20 70 6f 69 6e 74 20 69 6e 74 6f 20 74 68  ry point into th
ca80: 69 73 20 70 72 6f 67 72 61 6d 2e 0a 20 2a 2f 0a  is program.. */.
ca90: 69 6e 74 20 6d 61 69 6e 28 69 6e 74 20 61 72 67  int main(int arg
caa0: 63 2c 20 63 68 61 72 20 2a 2a 61 72 67 76 29 20  c, char **argv) 
cab0: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 74  {..Tcl_Interp *t
cac0: 65 73 74 5f 69 6e 74 65 72 70 3b 0a 09 63 68 61  est_interp;..cha
cad0: 72 20 2a 74 65 73 74 5f 69 6e 74 65 72 70 5f 65  r *test_interp_e
cae0: 72 72 6f 72 3b 0a 09 73 74 72 75 63 74 20 66 75  rror;..struct fu
caf0: 73 65 5f 61 72 67 73 20 61 72 67 73 20 3d 20 46  se_args args = F
cb00: 55 53 45 5f 41 52 47 53 5f 49 4e 49 54 28 30 2c  USE_ARGS_INIT(0,
cb10: 20 4e 55 4c 4c 29 3b 0a 09 73 74 72 75 63 74 20   NULL);..struct 
cb20: 72 6c 69 6d 69 74 20 6e 75 6d 62 65 72 5f 6f 70  rlimit number_op
cb30: 65 6e 5f 66 69 6c 65 73 3b 0a 09 69 6e 74 20 70  en_files;..int p
cb40: 74 68 72 65 61 64 5f 72 65 74 2c 20 61 6f 70 5f  thread_ret, aop_
cb50: 72 65 74 2c 20 72 6c 69 6d 69 74 5f 72 65 74 3b  ret, rlimit_ret;
cb60: 0a 09 76 6f 69 64 20 2a 73 69 67 6e 61 6c 5f 72  ..void *signal_r
cb70: 65 74 3b 0a 09 63 68 61 72 20 2a 61 72 67 76 30  et;..char *argv0
cb80: 3b 0a 09 72 6c 69 6d 5f 74 20 6e 75 6d 62 65 72  ;..rlim_t number
cb90: 5f 6f 70 65 6e 5f 66 69 6c 65 73 5f 6d 61 78 3b  _open_files_max;
cba0: 0a 0a 09 2f 2a 0a 09 20 2a 20 53 6b 69 70 20 70  .../*.. * Skip p
cbb0: 61 73 73 65 64 20 70 72 6f 67 72 61 6d 20 6e 61  assed program na
cbc0: 6d 65 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72 67  me.. */..if (arg
cbd0: 63 20 3d 3d 20 30 20 7c 7c 20 61 72 67 76 20 3d  c == 0 || argv =
cbe0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
cbf0: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 61 72 67 76  rn(1);..}...argv
cc00: 30 20 3d 20 61 72 67 76 5b 30 5d 3b 0a 0a 09 61  0 = argv[0];...a
cc10: 72 67 63 2d 2d 3b 0a 09 61 72 67 76 2b 2b 3b 0a  rgc--;..argv++;.
cc20: 0a 09 2f 2a 0a 09 20 2a 20 53 65 74 20 61 70 70  ../*.. * Set app
cc30: 72 6f 70 72 69 61 74 65 20 75 6d 61 73 6b 0a 09  ropriate umask..
cc40: 20 2a 2f 0a 09 75 6d 61 73 6b 28 30 32 32 29 3b   */..umask(022);
cc50: 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65 74 20 67 6c  .../*.. * Set gl
cc60: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 2c 20  obal variables, 
cc70: 74 68 65 73 65 20 73 68 6f 75 6c 64 20 62 65 20  these should be 
cc80: 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 6f 70  configuration op
cc90: 74 69 6f 6e 73 2e 0a 09 20 2a 2f 0a 09 61 70 70  tions... */..app
cca0: 66 73 5f 63 61 63 68 65 64 69 72 20 3d 20 41 50  fs_cachedir = AP
ccb0: 50 46 53 5f 43 41 43 48 45 44 49 52 3b 0a 0a 09  PFS_CACHEDIR;...
ccc0: 2f 2a 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62 61  /*.. * Set globa
ccd0: 6c 20 76 61 72 69 61 62 6c 65 20 66 6f 72 20 22  l variable for "
cce0: 62 6f 6f 74 20 74 69 6d 65 22 20 74 6f 20 73 65  boot time" to se
ccf0: 74 20 61 20 74 69 6d 65 20 6f 6e 20 64 69 72 65  t a time on dire
cd00: 63 74 6f 72 69 65 73 0a 09 20 2a 20 74 68 61 74  ctories.. * that
cd10: 20 77 65 20 66 61 6b 65 2e 0a 09 20 2a 2f 0a 09   we fake... */..
cd20: 61 70 70 66 73 5f 62 6f 6f 74 74 69 6d 65 20 3d  appfs_boottime =
cd30: 20 74 69 6d 65 28 4e 55 4c 4c 29 3b 0a 0a 09 2f   time(NULL);.../
cd40: 2a 0a 09 20 2a 20 52 65 67 69 73 74 65 72 20 22  *.. * Register "
cd50: 73 68 61 31 22 20 61 6e 64 20 22 61 70 70 66 73  sha1" and "appfs
cd60: 64 22 20 70 61 63 6b 61 67 65 20 77 69 74 68 20  d" package with 
cd70: 6c 69 62 74 63 6c 20 73 6f 20 74 68 61 74 20 61  libtcl so that a
cd80: 6e 79 20 6e 65 77 0a 09 20 2a 20 69 6e 74 65 72  ny new.. * inter
cd90: 70 72 65 74 65 72 73 20 63 72 65 61 74 65 64 20  preters created 
cda0: 28 77 68 69 63 68 20 61 72 65 20 64 6f 6e 65 20  (which are done 
cdb0: 64 79 6e 61 6d 69 63 61 6c 6c 79 20 62 79 20 46  dynamically by F
cdc0: 55 53 45 29 20 63 61 6e 20 68 61 76 65 0a 09 20  USE) can have.. 
cdd0: 2a 20 74 68 65 20 61 70 70 72 6f 70 72 69 61 74  * the appropriat
cde0: 65 20 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20  e configuration 
cdf0: 64 6f 6e 65 20 61 75 74 6f 6d 61 74 69 63 61 6c  done automatical
ce00: 6c 79 2e 0a 09 20 2a 2f 0a 09 54 63 6c 5f 53 74  ly... */..Tcl_St
ce10: 61 74 69 63 50 61 63 6b 61 67 65 28 4e 55 4c 4c  aticPackage(NULL
ce20: 2c 20 22 73 68 61 31 22 2c 20 53 68 61 31 5f 49  , "sha1", Sha1_I
ce30: 6e 69 74 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c  nit, NULL);..Tcl
ce40: 5f 53 74 61 74 69 63 50 61 63 6b 61 67 65 28 4e  _StaticPackage(N
ce50: 55 4c 4c 2c 20 22 61 70 70 66 73 64 22 2c 20 41  ULL, "appfsd", A
ce60: 70 70 66 73 64 5f 49 6e 69 74 2c 20 4e 55 4c 4c  ppfsd_Init, NULL
ce70: 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72 65 61  );.../*.. * Crea
ce80: 74 65 20 61 20 74 68 72 65 61 64 2d 73 70 65 63  te a thread-spec
ce90: 69 66 69 63 2d 64 61 74 61 20 28 54 53 44 29 20  ific-data (TSD) 
cea0: 6b 65 79 20 66 6f 72 20 65 61 63 68 20 74 68 72  key for each thr
ceb0: 65 61 64 20 74 6f 20 72 65 66 65 72 0a 09 20 2a  ead to refer.. *
cec0: 20 74 6f 20 69 74 73 20 6f 77 6e 20 54 63 6c 20   to its own Tcl 
ced0: 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20 54 63  interpreter.  Tc
cee0: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 73 20 6d  l interpreters m
cef0: 75 73 74 20 62 65 20 75 6e 69 71 75 65 20 70 65  ust be unique pe
cf00: 72 0a 09 20 2a 20 74 68 72 65 61 64 20 61 6e 64  r.. * thread and
cf10: 20 6e 65 77 20 74 68 72 65 61 64 73 20 61 72 65   new threads are
cf20: 20 64 79 6e 61 6d 69 63 61 6c 6c 79 20 63 72 65   dynamically cre
cf30: 61 74 65 64 20 62 79 20 46 55 53 45 2e 0a 09 20  ated by FUSE... 
cf40: 2a 2f 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20  */..pthread_ret 
cf50: 3d 20 70 74 68 72 65 61 64 5f 6b 65 79 5f 63 72  = pthread_key_cr
cf60: 65 61 74 65 28 26 69 6e 74 65 72 70 4b 65 79 2c  eate(&interpKey,
cf70: 20 61 70 70 66 73 5f 74 65 72 6d 69 6e 61 74 65   appfs_terminate
cf80: 5f 69 6e 74 65 72 70 5f 61 6e 64 5f 74 68 72 65  _interp_and_thre
cf90: 61 64 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61  ad);..if (pthrea
cfa0: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
cfb0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
cfc0: 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74  "Unable to creat
cfd0: 65 20 54 53 44 20 6b 65 79 20 66 6f 72 20 54 63  e TSD key for Tc
cfe0: 6c 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22  l.  Aborting.\n"
cff0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b  );....return(1);
d000: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4d 61 6e  ..}.../*.. * Man
d010: 75 61 6c 6c 79 20 73 70 65 63 69 66 79 20 63 61  ually specify ca
d020: 63 68 65 20 64 69 72 65 63 74 6f 72 79 2c 20 77  che directory, w
d030: 69 74 68 6f 75 74 20 46 55 53 45 20 63 61 6c 6c  ithout FUSE call
d040: 62 61 63 6b 0a 09 20 2a 20 54 68 69 73 20 6f 70  back.. * This op
d050: 74 69 6f 6e 20 6f 6e 6c 79 20 77 6f 72 6b 73 20  tion only works 
d060: 77 68 65 6e 20 6e 6f 74 20 75 73 69 6e 67 20 46  when not using F
d070: 55 53 45 2c 20 73 69 6e 63 65 20 77 65 0a 09 20  USE, since we.. 
d080: 2a 20 64 6f 20 6e 6f 74 20 70 72 6f 63 65 73 73  * do not process
d090: 20 69 74 20 77 69 74 68 20 46 55 53 45 73 20 6f   it with FUSEs o
d0a0: 70 74 69 6f 6e 20 70 72 6f 63 65 73 73 69 6e 67  ption processing
d0b0: 2e 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63  ... */..if (argc
d0c0: 20 3e 3d 20 32 29 20 7b 0a 09 09 69 66 20 28 73   >= 2) {...if (s
d0d0: 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20 22  trcmp(argv[0], "
d0e0: 2d 2d 63 61 63 68 65 64 69 72 22 29 20 3d 3d 20  --cachedir") == 
d0f0: 30 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61  0) {....appfs_ca
d100: 63 68 65 64 69 72 20 3d 20 73 74 72 64 75 70 28  chedir = strdup(
d110: 61 72 67 76 5b 31 5d 29 3b 0a 0a 09 09 09 61 72  argv[1]);.....ar
d120: 67 63 20 2d 3d 20 32 3b 0a 09 09 09 61 72 67 76  gc -= 2;....argv
d130: 20 2b 3d 20 32 3b 0a 09 09 7d 0a 09 7d 0a 0a 09   += 2;...}..}...
d140: 2f 2a 0a 09 20 2a 20 53 51 4c 69 74 65 33 20 6d  /*.. * SQLite3 m
d150: 6f 64 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67  ode, for running
d160: 20 72 61 77 20 53 51 4c 20 61 67 61 69 6e 73 74   raw SQL against
d170: 20 74 68 65 20 63 61 63 68 65 20 64 61 74 61 62   the cache datab
d180: 61 73 65 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72  ase.. */..if (ar
d190: 67 63 20 3d 3d 20 32 20 26 26 20 73 74 72 63 6d  gc == 2 && strcm
d1a0: 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 73 71  p(argv[0], "--sq
d1b0: 6c 69 74 65 33 22 29 20 3d 3d 20 30 29 20 7b 0a  lite3") == 0) {.
d1c0: 09 09 72 65 74 75 72 6e 28 61 70 70 66 73 5f 73  ..return(appfs_s
d1d0: 71 6c 69 74 65 33 28 61 72 67 76 5b 31 5d 29 29  qlite3(argv[1]))
d1e0: 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 54 63  ;..}.../*.. * Tc
d1f0: 6c 20 6d 6f 64 65 2c 20 66 6f 72 20 72 75 6e 6e  l mode, for runn
d200: 69 6e 67 20 72 61 77 20 54 63 6c 20 69 6e 20 74  ing raw Tcl in t
d210: 68 65 20 73 61 6d 65 20 65 6e 76 69 72 6f 6e 6d  he same environm
d220: 65 6e 74 20 41 70 70 46 53 64 20 77 6f 75 6c 64  ent AppFSd would
d230: 0a 09 20 2a 20 72 75 6e 20 63 6f 64 65 2e 0a 09  .. * run code...
d240: 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d   */..if (argc ==
d250: 20 32 20 26 26 20 73 74 72 63 6d 70 28 61 72 67   2 && strcmp(arg
d260: 76 5b 30 5d 2c 20 22 2d 2d 74 63 6c 22 29 20 3d  v[0], "--tcl") =
d270: 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  = 0) {...return(
d280: 61 70 70 66 73 5f 74 63 6c 28 61 72 67 76 5b 31  appfs_tcl(argv[1
d290: 5d 29 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  ]));..}.../*.. *
d2a0: 20 52 65 67 69 73 74 65 72 20 61 20 73 69 67 6e   Register a sign
d2b0: 61 6c 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 68  al handler for h
d2c0: 6f 74 2d 72 65 73 74 61 72 74 20 72 65 71 75 65  ot-restart reque
d2d0: 73 74 73 0a 09 20 2a 2f 0a 09 73 69 67 6e 61 6c  sts.. */..signal
d2e0: 5f 72 65 74 20 3d 20 73 69 67 6e 61 6c 28 53 49  _ret = signal(SI
d2f0: 47 48 55 50 2c 20 61 70 70 66 73 5f 73 69 67 6e  GHUP, appfs_sign
d300: 61 6c 5f 68 61 6e 64 6c 65 72 29 3b 0a 09 69 66  al_handler);..if
d310: 20 28 73 69 67 6e 61 6c 5f 72 65 74 20 3d 3d 20   (signal_ret == 
d320: 53 49 47 5f 45 52 52 29 20 7b 0a 09 09 66 70 72  SIG_ERR) {...fpr
d330: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e  intf(stderr, "Un
d340: 61 62 6c 65 20 74 6f 20 69 6e 73 74 61 6c 6c 20  able to install 
d350: 73 69 67 6e 61 6c 20 68 61 6e 64 6c 65 72 20 66  signal handler f
d360: 6f 72 20 68 6f 74 2d 72 65 73 74 61 72 74 5c 6e  or hot-restart\n
d370: 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ");...fprintf(st
d380: 64 65 72 72 2c 20 22 48 6f 74 2d 72 65 73 74 61  derr, "Hot-resta
d390: 72 74 20 77 69 6c 6c 20 6e 6f 74 20 62 65 20 61  rt will not be a
d3a0: 76 61 69 6c 61 62 6c 65 2e 5c 6e 22 29 3b 0a 09  vailable.\n");..
d3b0: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 50 61 72 73 65  }.../*.. * Parse
d3c0: 20 63 6f 6d 6d 61 6e 64 20 6c 69 6e 65 20 61 72   command line ar
d3d0: 67 75 6d 65 6e 74 73 0a 09 20 2a 2f 0a 09 2f 2a  guments.. */../*
d3e0: 2a 0a 09 20 2a 2a 20 52 65 73 74 6f 72 65 20 61  *.. ** Restore a
d3f0: 72 67 63 2f 61 72 67 76 20 74 6f 20 6f 72 69 67  rgc/argv to orig
d400: 69 6e 61 6c 20 76 61 6c 75 65 73 2c 20 72 65 70  inal values, rep
d410: 6c 61 63 69 6e 67 20 61 72 67 76 5b 30 5d 20 69  lacing argv[0] i
d420: 6e 20 63 61 73 65 0a 09 20 2a 2a 20 69 74 20 77  n case.. ** it w
d430: 61 73 20 6d 6f 69 66 69 65 64 20 62 79 20 2d 2d  as moified by --
d440: 63 61 63 68 65 64 69 72 20 6f 70 74 69 6f 6e 2e  cachedir option.
d450: 0a 09 20 2a 2a 2f 0a 09 61 72 67 63 2b 2b 3b 0a  .. **/..argc++;.
d460: 09 61 72 67 76 2d 2d 3b 0a 09 61 72 67 76 5b 30  .argv--;..argv[0
d470: 5d 20 3d 20 61 72 67 76 30 3b 0a 0a 09 2f 2a 2a  ] = argv0;.../**
d480: 0a 09 20 2a 2a 20 50 65 72 66 6f 72 6d 20 74 68  .. ** Perform th
d490: 65 20 61 72 67 75 6d 65 6e 74 20 70 61 72 73 69  e argument parsi
d4a0: 6e 67 0a 09 20 2a 2a 2f 0a 09 61 6f 70 5f 72 65  ng.. **/..aop_re
d4b0: 74 20 3d 20 61 70 70 66 73 5f 6f 70 74 5f 70 61  t = appfs_opt_pa
d4c0: 72 73 65 28 61 72 67 63 2c 20 61 72 67 76 2c 20  rse(argc, argv, 
d4d0: 26 61 72 67 73 29 3b 0a 09 69 66 20 28 61 6f 70  &args);..if (aop
d4e0: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 69  _ret != 0) {...i
d4f0: 66 20 28 61 6f 70 5f 72 65 74 20 3c 20 30 29 20  f (aop_ret < 0) 
d500: 7b 0a 09 09 09 72 65 74 75 72 6e 28 30 29 3b 0a  {....return(0);.
d510: 09 09 7d 0a 0a 09 09 72 65 74 75 72 6e 28 61 6f  ..}....return(ao
d520: 70 5f 72 65 74 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a  p_ret);..}.../*.
d530: 09 20 2a 20 43 72 65 61 74 65 20 61 20 54 63 6c  . * Create a Tcl
d540: 20 69 6e 74 65 72 70 72 65 74 65 72 20 6a 75 73   interpreter jus
d550: 74 20 74 6f 20 76 65 72 69 66 79 20 74 68 61 74  t to verify that
d560: 20 74 68 69 6e 67 73 20 61 72 65 20 69 6e 20 77   things are in w
d570: 6f 72 6b 69 6e 67 20 0a 09 20 2a 20 6f 72 64 65  orking .. * orde
d580: 72 20 62 65 66 6f 72 65 20 77 65 20 62 65 63 6f  r before we beco
d590: 6d 65 20 61 20 64 61 65 6d 6f 6e 2e 0a 09 20 2a  me a daemon... *
d5a0: 2f 0a 09 74 65 73 74 5f 69 6e 74 65 72 70 20 3d  /..test_interp =
d5b0: 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63   appfs_create_Tc
d5c0: 6c 49 6e 74 65 72 70 28 26 74 65 73 74 5f 69 6e  lInterp(&test_in
d5d0: 74 65 72 70 5f 65 72 72 6f 72 29 3b 0a 09 69 66  terp_error);..if
d5e0: 20 28 74 65 73 74 5f 69 6e 74 65 72 70 20 3d 3d   (test_interp ==
d5f0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 66 20 28 74   NULL) {...if (t
d600: 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72  est_interp_error
d610: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 74   == NULL) {....t
d620: 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72  est_interp_error
d630: 20 3d 20 22 55 6e 6b 6e 6f 77 6e 20 65 72 72 6f   = "Unknown erro
d640: 72 22 3b 0a 09 09 7d 0a 0a 09 09 66 70 72 69 6e  r";...}....fprin
d650: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
d660: 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65  le to initialize
d670: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
d680: 20 66 6f 72 20 41 70 70 46 53 64 3a 5c 6e 22 29   for AppFSd:\n")
d690: 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ;...fprintf(stde
d6a0: 72 72 2c 20 22 25 73 5c 6e 22 2c 20 74 65 73 74  rr, "%s\n", test
d6b0: 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 29 3b 0a  _interp_error);.
d6c0: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
d6d0: 0a 0a 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74  ...Tcl_DeleteInt
d6e0: 65 72 70 28 74 65 73 74 5f 69 6e 74 65 72 70 29  erp(test_interp)
d6f0: 3b 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 74 68  ;...if (appfs_th
d700: 72 65 61 64 65 64 5f 74 63 6c 29 20 7b 0a 09 09  readed_tcl) {...
d710: 54 63 6c 5f 46 69 6e 61 6c 69 7a 65 4e 6f 74 69  Tcl_FinalizeNoti
d720: 66 69 65 72 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  fier(NULL);..}..
d730: 09 2f 2a 0a 09 20 2a 20 49 6e 63 72 65 61 73 65  ./*.. * Increase
d740: 20 72 65 73 6f 75 72 63 65 20 6c 69 6d 69 74 73   resource limits
d750: 20 66 6f 72 20 6e 75 6d 62 65 72 20 6f 66 20 6f   for number of o
d760: 70 65 6e 20 66 69 6c 65 73 0a 09 20 2a 20 74 6f  pen files.. * to
d770: 20 74 68 65 20 6d 61 78 69 6d 75 6d 20 76 61 6c   the maximum val
d780: 75 65 73 2c 20 73 69 6e 63 65 20 77 65 20 6d 61  ues, since we ma
d790: 79 20 62 65 20 61 73 6b 65 64 20 74 6f 0a 09 20  y be asked to.. 
d7a0: 2a 20 68 6f 6c 64 20 6f 70 65 6e 20 6d 61 6e 79  * hold open many
d7b0: 20 66 69 6c 65 73 20 6f 6e 20 62 65 68 61 6c 66   files on behalf
d7c0: 20 6f 66 20 6d 61 6e 79 20 6f 74 68 65 72 20 70   of many other p
d7d0: 72 6f 63 65 73 73 65 73 0a 09 20 2a 2f 0a 09 6e  rocesses.. */..n
d7e0: 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73  umber_open_files
d7f0: 2e 72 6c 69 6d 5f 63 75 72 20 3d 20 6e 75 6d 62  .rlim_cur = numb
d800: 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 2e 72 6c  er_open_files.rl
d810: 69 6d 5f 6d 61 78 20 3d 20 52 4c 49 4d 5f 49 4e  im_max = RLIM_IN
d820: 46 49 4e 49 54 59 3b 0a 0a 09 72 6c 69 6d 69 74  FINITY;...rlimit
d830: 5f 72 65 74 20 3d 20 73 65 74 72 6c 69 6d 69 74  _ret = setrlimit
d840: 28 52 4c 49 4d 49 54 5f 4e 4f 46 49 4c 45 2c 20  (RLIMIT_NOFILE, 
d850: 26 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c  &number_open_fil
d860: 65 73 29 3b 0a 0a 09 69 66 20 28 72 6c 69 6d 69  es);...if (rlimi
d870: 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  t_ret != 0) {...
d880: 72 6c 69 6d 69 74 5f 72 65 74 20 3d 20 67 65 74  rlimit_ret = get
d890: 72 6c 69 6d 69 74 28 52 4c 49 4d 49 54 5f 4e 4f  rlimit(RLIMIT_NO
d8a0: 46 49 4c 45 2c 20 26 6e 75 6d 62 65 72 5f 6f 70  FILE, &number_op
d8b0: 65 6e 5f 66 69 6c 65 73 29 3b 0a 09 09 69 66 20  en_files);...if 
d8c0: 28 72 6c 69 6d 69 74 5f 72 65 74 20 3d 3d 20 30  (rlimit_ret == 0
d8d0: 29 20 7b 0a 09 09 09 6e 75 6d 62 65 72 5f 6f 70  ) {....number_op
d8e0: 65 6e 5f 66 69 6c 65 73 5f 6d 61 78 20 3d 20 6e  en_files_max = n
d8f0: 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73  umber_open_files
d900: 2e 72 6c 69 6d 5f 6d 61 78 3b 0a 0a 09 09 09 69  .rlim_max;.....i
d910: 66 20 28 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66  f (number_open_f
d920: 69 6c 65 73 5f 6d 61 78 20 3c 20 28 31 30 32 34  iles_max < (1024
d930: 20 2a 20 31 30 32 34 29 29 20 7b 0a 09 09 09 09   * 1024)) {.....
d940: 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65  number_open_file
d950: 73 2e 72 6c 69 6d 5f 63 75 72 20 3d 20 6e 75 6d  s.rlim_cur = num
d960: 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 2e 72  ber_open_files.r
d970: 6c 69 6d 5f 6d 61 78 20 3d 20 31 30 32 34 20 2a  lim_max = 1024 *
d980: 20 31 30 32 34 3b 0a 0a 09 09 09 09 72 6c 69 6d   1024;......rlim
d990: 69 74 5f 72 65 74 20 3d 20 73 65 74 72 6c 69 6d  it_ret = setrlim
d9a0: 69 74 28 52 4c 49 4d 49 54 5f 4e 4f 46 49 4c 45  it(RLIMIT_NOFILE
d9b0: 2c 20 26 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66  , &number_open_f
d9c0: 69 6c 65 73 29 3b 0a 09 09 09 7d 20 65 6c 73 65  iles);....} else
d9d0: 20 7b 0a 09 09 09 09 6e 75 6d 62 65 72 5f 6f 70   {.....number_op
d9e0: 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f 63 75  en_files.rlim_cu
d9f0: 72 20 3d 20 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f  r = number_open_
da00: 66 69 6c 65 73 2e 72 6c 69 6d 5f 6d 61 78 3b 0a  files.rlim_max;.
da10: 09 09 09 7d 0a 0a 09 09 09 72 6c 69 6d 69 74 5f  ...}.....rlimit_
da20: 72 65 74 20 3d 20 73 65 74 72 6c 69 6d 69 74 28  ret = setrlimit(
da30: 52 4c 49 4d 49 54 5f 4e 4f 46 49 4c 45 2c 20 26  RLIMIT_NOFILE, &
da40: 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65  number_open_file
da50: 73 29 3b 0a 0a 09 09 09 69 66 20 28 72 6c 69 6d  s);.....if (rlim
da60: 69 74 5f 72 65 74 20 21 3d 20 30 20 26 26 20 6e  it_ret != 0 && n
da70: 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73  umber_open_files
da80: 2e 72 6c 69 6d 5f 63 75 72 20 21 3d 20 6e 75 6d  .rlim_cur != num
da90: 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 5f 6d  ber_open_files_m
daa0: 61 78 29 20 7b 0a 09 09 09 09 6e 75 6d 62 65 72  ax) {.....number
dab0: 5f 6f 70 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d  _open_files.rlim
dac0: 5f 63 75 72 20 3d 20 6e 75 6d 62 65 72 5f 6f 70  _cur = number_op
dad0: 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f 6d 61  en_files.rlim_ma
dae0: 78 20 3d 20 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f  x = number_open_
daf0: 66 69 6c 65 73 5f 6d 61 78 3b 0a 0a 09 09 09 09  files_max;......
db00: 73 65 74 72 6c 69 6d 69 74 28 52 4c 49 4d 49 54  setrlimit(RLIMIT
db10: 5f 4e 4f 46 49 4c 45 2c 20 26 6e 75 6d 62 65 72  _NOFILE, &number
db20: 5f 6f 70 65 6e 5f 66 69 6c 65 73 29 3b 0a 09 09  _open_files);...
db30: 09 7d 0a 09 09 7d 0a 09 7d 0a 0a 0a 09 2f 2a 0a  .}...}..}..../*.
db40: 09 20 2a 20 45 6e 74 65 72 20 74 68 65 20 46 55  . * Enter the FU
db50: 53 45 20 6d 61 69 6e 20 6c 6f 6f 70 20 2d 2d 20  SE main loop -- 
db60: 74 68 69 73 20 77 69 6c 6c 20 70 72 6f 63 65 73  this will proces
db70: 73 20 61 6e 79 20 61 72 67 75 6d 65 6e 74 73 0a  s any arguments.
db80: 09 20 2a 20 61 6e 64 20 73 74 61 72 74 20 73 65  . * and start se
db90: 72 76 69 63 69 6e 67 20 72 65 71 75 65 73 74 73  rvicing requests
dba0: 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 66 75  ... */..appfs_fu
dbb0: 73 65 5f 73 74 61 72 74 65 64 20 3d 20 31 3b 0a  se_started = 1;.
dbc0: 09 72 65 74 75 72 6e 28 66 75 73 65 5f 6d 61 69  .return(fuse_mai
dbd0: 6e 28 61 72 67 73 2e 61 72 67 63 2c 20 61 72 67  n(args.argc, arg
dbe0: 73 2e 61 72 67 76 2c 20 26 61 70 70 66 73 5f 6f  s.argv, &appfs_o
dbf0: 70 65 72 61 74 69 6f 6e 73 2c 20 4e 55 4c 4c 29  perations, NULL)
dc00: 29 3b 0a 7d 0a                                   );.}.