Hex Artifact Content

Artifact 6b6df68529ff73d92f9c3af5d8a5ecf2650717f4:


0000: 2f 2a 0a 20 2a 20 43 6f 70 79 72 69 67 68 74 20  /*. * Copyright 
0010: 28 63 29 20 32 30 31 34 2c 20 32 30 31 35 20 20  (c) 2014, 2015  
0020: 52 6f 79 20 4b 65 65 6e 65 0a 20 2a 0a 20 2a 20  Roy Keene. *. * 
0030: 50 65 72 6d 69 73 73 69 6f 6e 20 69 73 20 68 65  Permission is he
0040: 72 65 62 79 20 67 72 61 6e 74 65 64 2c 20 66 72  reby granted, fr
0050: 65 65 20 6f 66 20 63 68 61 72 67 65 2c 20 74 6f  ee of charge, to
0060: 20 61 6e 79 20 70 65 72 73 6f 6e 20 6f 62 74 61   any person obta
0070: 69 6e 69 6e 67 20 61 20 63 6f 70 79 0a 20 2a 20  ining a copy. * 
0080: 6f 66 20 74 68 69 73 20 73 6f 66 74 77 61 72 65  of this software
0090: 20 61 6e 64 20 61 73 73 6f 63 69 61 74 65 64 20   and associated 
00a0: 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e 20 66 69  documentation fi
00b0: 6c 65 73 20 28 74 68 65 20 22 53 6f 66 74 77 61  les (the "Softwa
00c0: 72 65 22 29 2c 20 74 6f 20 64 65 61 6c 0a 20 2a  re"), to deal. *
00d0: 20 69 6e 20 74 68 65 20 53 6f 66 74 77 61 72 65   in the Software
00e0: 20 77 69 74 68 6f 75 74 20 72 65 73 74 72 69 63   without restric
00f0: 74 69 6f 6e 2c 20 69 6e 63 6c 75 64 69 6e 67 20  tion, including 
0100: 77 69 74 68 6f 75 74 20 6c 69 6d 69 74 61 74 69  without limitati
0110: 6f 6e 20 74 68 65 20 72 69 67 68 74 73 0a 20 2a  on the rights. *
0120: 20 74 6f 20 75 73 65 2c 20 63 6f 70 79 2c 20 6d   to use, copy, m
0130: 6f 64 69 66 79 2c 20 6d 65 72 67 65 2c 20 70 75  odify, merge, pu
0140: 62 6c 69 73 68 2c 20 64 69 73 74 72 69 62 75 74  blish, distribut
0150: 65 2c 20 73 75 62 6c 69 63 65 6e 73 65 2c 20 61  e, sublicense, a
0160: 6e 64 2f 6f 72 20 73 65 6c 6c 0a 20 2a 20 63 6f  nd/or sell. * co
0170: 70 69 65 73 20 6f 66 20 74 68 65 20 53 6f 66 74  pies of the Soft
0180: 77 61 72 65 2c 20 61 6e 64 20 74 6f 20 70 65 72  ware, and to per
0190: 6d 69 74 20 70 65 72 73 6f 6e 73 20 74 6f 20 77  mit persons to w
01a0: 68 6f 6d 20 74 68 65 20 53 6f 66 74 77 61 72 65  hom the Software
01b0: 20 69 73 0a 20 2a 20 66 75 72 6e 69 73 68 65 64   is. * furnished
01c0: 20 74 6f 20 64 6f 20 73 6f 2c 20 73 75 62 6a 65   to do so, subje
01d0: 63 74 20 74 6f 20 74 68 65 20 66 6f 6c 6c 6f 77  ct to the follow
01e0: 69 6e 67 20 63 6f 6e 64 69 74 69 6f 6e 73 3a 0a  ing conditions:.
01f0: 20 2a 0a 20 2a 20 54 68 65 20 61 62 6f 76 65 20   *. * The above 
0200: 63 6f 70 79 72 69 67 68 74 20 6e 6f 74 69 63 65  copyright notice
0210: 20 61 6e 64 20 74 68 69 73 20 70 65 72 6d 69 73   and this permis
0220: 73 69 6f 6e 20 6e 6f 74 69 63 65 20 73 68 61 6c  sion notice shal
0230: 6c 20 62 65 20 69 6e 63 6c 75 64 65 64 20 69 6e  l be included in
0240: 0a 20 2a 20 61 6c 6c 20 63 6f 70 69 65 73 20 6f  . * all copies o
0250: 72 20 73 75 62 73 74 61 6e 74 69 61 6c 20 70 6f  r substantial po
0260: 72 74 69 6f 6e 73 20 6f 66 20 74 68 65 20 53 6f  rtions of the So
0270: 66 74 77 61 72 65 2e 0a 20 2a 0a 20 2a 20 54 48  ftware.. *. * TH
0280: 45 20 53 4f 46 54 57 41 52 45 20 49 53 20 50 52  E SOFTWARE IS PR
0290: 4f 56 49 44 45 44 20 22 41 53 20 49 53 22 2c 20  OVIDED "AS IS", 
02a0: 57 49 54 48 4f 55 54 20 57 41 52 52 41 4e 54 59  WITHOUT WARRANTY
02b0: 20 4f 46 20 41 4e 59 20 4b 49 4e 44 2c 20 45 58   OF ANY KIND, EX
02c0: 50 52 45 53 53 20 4f 52 0a 20 2a 20 49 4d 50 4c  PRESS OR. * IMPL
02d0: 49 45 44 2c 20 49 4e 43 4c 55 44 49 4e 47 20 42  IED, INCLUDING B
02e0: 55 54 20 4e 4f 54 20 4c 49 4d 49 54 45 44 20 54  UT NOT LIMITED T
02f0: 4f 20 54 48 45 20 57 41 52 52 41 4e 54 49 45 53  O THE WARRANTIES
0300: 20 4f 46 20 4d 45 52 43 48 41 4e 54 41 42 49 4c   OF MERCHANTABIL
0310: 49 54 59 2c 0a 20 2a 20 46 49 54 4e 45 53 53 20  ITY,. * FITNESS 
0320: 46 4f 52 20 41 20 50 41 52 54 49 43 55 4c 41 52  FOR A PARTICULAR
0330: 20 50 55 52 50 4f 53 45 20 41 4e 44 20 4e 4f 4e   PURPOSE AND NON
0340: 49 4e 46 52 49 4e 47 45 4d 45 4e 54 2e 20 49 4e  INFRINGEMENT. IN
0350: 20 4e 4f 20 45 56 45 4e 54 20 53 48 41 4c 4c 20   NO EVENT SHALL 
0360: 54 48 45 0a 20 2a 20 41 55 54 48 4f 52 53 20 4f  THE. * AUTHORS O
0370: 52 20 43 4f 50 59 52 49 47 48 54 20 48 4f 4c 44  R COPYRIGHT HOLD
0380: 45 52 53 20 42 45 20 4c 49 41 42 4c 45 20 46 4f  ERS BE LIABLE FO
0390: 52 20 41 4e 59 20 43 4c 41 49 4d 2c 20 44 41 4d  R ANY CLAIM, DAM
03a0: 41 47 45 53 20 4f 52 20 4f 54 48 45 52 0a 20 2a  AGES OR OTHER. *
03b0: 20 4c 49 41 42 49 4c 49 54 59 2c 20 57 48 45 54   LIABILITY, WHET
03c0: 48 45 52 20 49 4e 20 41 4e 20 41 43 54 49 4f 4e  HER IN AN ACTION
03d0: 20 4f 46 20 43 4f 4e 54 52 41 43 54 2c 20 54 4f   OF CONTRACT, TO
03e0: 52 54 20 4f 52 20 4f 54 48 45 52 57 49 53 45 2c  RT OR OTHERWISE,
03f0: 20 41 52 49 53 49 4e 47 20 46 52 4f 4d 2c 0a 20   ARISING FROM,. 
0400: 2a 20 4f 55 54 20 4f 46 20 4f 52 20 49 4e 20 43  * OUT OF OR IN C
0410: 4f 4e 4e 45 43 54 49 4f 4e 20 57 49 54 48 20 54  ONNECTION WITH T
0420: 48 45 20 53 4f 46 54 57 41 52 45 20 4f 52 20 54  HE SOFTWARE OR T
0430: 48 45 20 55 53 45 20 4f 52 20 4f 54 48 45 52 20  HE USE OR OTHER 
0440: 44 45 41 4c 49 4e 47 53 20 49 4e 0a 20 2a 20 54  DEALINGS IN. * T
0450: 48 45 20 53 4f 46 54 57 41 52 45 2e 0a 20 2a 2f  HE SOFTWARE.. */
0460: 0a 23 64 65 66 69 6e 65 20 46 55 53 45 5f 55 53  .#define FUSE_US
0470: 45 5f 56 45 52 53 49 4f 4e 20 32 36 0a 0a 23 69  E_VERSION 26..#i
0480: 6e 63 6c 75 64 65 20 3c 73 79 73 2f 66 73 75 69  nclude <sys/fsui
0490: 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73  d.h>.#include <s
04a0: 79 73 2f 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63  ys/types.h>.#inc
04b0: 6c 75 64 65 20 3c 70 74 68 72 65 61 64 2e 68 3e  lude <pthread.h>
04c0: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 69 67 6e 61  .#include <signa
04d0: 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 6c  l.h>.#include <l
04e0: 69 6d 69 74 73 2e 68 3e 0a 23 69 6e 63 6c 75 64  imits.h>.#includ
04f0: 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e  e <string.h>.#in
0500: 63 6c 75 64 65 20 3c 73 74 64 61 72 67 2e 68 3e  clude <stdarg.h>
0510: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69  .#include <stdli
0520: 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 75  b.h>.#include <u
0530: 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c 75 64  nistd.h>.#includ
0540: 65 20 3c 65 72 72 6e 6f 2e 68 3e 0a 23 69 6e 63  e <errno.h>.#inc
0550: 6c 75 64 65 20 3c 66 63 6e 74 6c 2e 68 3e 0a 23  lude <fcntl.h>.#
0560: 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68  include <stdio.h
0570: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 66 75 73 65  >.#include <fuse
0580: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 70 77  .h>.#include <pw
0590: 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 74  d.h>.#include <t
05a0: 63 6c 2e 68 3e 0a 0a 2f 2a 0a 20 2a 20 44 65 66  cl.h>../*. * Def
05b0: 61 75 6c 74 20 63 61 63 68 65 20 64 69 72 65 63  ault cache direc
05c0: 74 6f 72 79 0a 20 2a 2f 0a 23 69 66 6e 64 65 66  tory. */.#ifndef
05d0: 20 41 50 50 46 53 5f 43 41 43 48 45 44 49 52 0a   APPFS_CACHEDIR.
05e0: 23 64 65 66 69 6e 65 20 41 50 50 46 53 5f 43 41  #define APPFS_CA
05f0: 43 48 45 44 49 52 20 22 2f 76 61 72 2f 63 61 63  CHEDIR "/var/cac
0600: 68 65 2f 61 70 70 66 73 22 0a 23 65 6e 64 69 66  he/appfs".#endif
0610: 0a 0a 2f 2a 20 44 65 62 75 67 67 69 6e 67 20 6d  ../* Debugging m
0620: 61 63 72 6f 73 20 2a 2f 0a 23 69 66 64 65 66 20  acros */.#ifdef 
0630: 44 45 42 55 47 0a 69 6e 74 20 61 70 70 66 73 5f  DEBUG.int appfs_
0640: 64 65 62 75 67 5f 66 64 20 3d 20 53 54 44 45 52  debug_fd = STDER
0650: 52 5f 46 49 4c 45 4e 4f 3b 0a 23 64 65 66 69 6e  R_FILENO;.#defin
0660: 65 20 41 50 50 46 53 5f 44 45 42 55 47 28 78 2e  e APPFS_DEBUG(x.
0670: 2e 2e 29 20 7b 20 5c 0a 09 63 68 61 72 20 62 75  ..) { \..char bu
0680: 66 5b 38 31 39 32 5d 3b 20 5c 0a 09 69 6e 74 20  f[8192]; \..int 
0690: 62 75 66 6f 66 66 20 3d 20 30 3b 20 5c 0a 09 69  bufoff = 0; \..i
06a0: 66 20 28 61 70 70 66 73 5f 64 65 62 75 67 5f 66  f (appfs_debug_f
06b0: 64 20 3d 3d 20 2d 31 29 20 7b 20 5c 0a 09 09 61  d == -1) { \...a
06c0: 70 70 66 73 5f 64 65 62 75 67 5f 66 64 20 3d 20  ppfs_debug_fd = 
06d0: 6f 70 65 6e 28 22 2f 74 6d 70 2f 61 70 70 66 73  open("/tmp/appfs
06e0: 64 2e 6c 6f 67 22 2c 20 4f 5f 57 52 4f 4e 4c 59  d.log", O_WRONLY
06f0: 20 7c 20 4f 5f 41 50 50 45 4e 44 20 7c 20 4f 5f   | O_APPEND | O_
0700: 43 52 45 41 54 2c 20 30 36 30 30 29 3b 20 5c 0a  CREAT, 0600); \.
0710: 09 7d 3b 20 5c 0a 09 62 75 66 6f 66 66 20 3d 20  .}; \..bufoff = 
0720: 73 6e 70 72 69 6e 74 66 28 62 75 66 2c 20 73 69  snprintf(buf, si
0730: 7a 65 6f 66 28 62 75 66 29 2c 20 22 5b 64 65 62  zeof(buf), "[deb
0740: 75 67 5d 20 5b 74 3d 25 6c 6c 78 5d 20 25 73 3a  ug] [t=%llx] %s:
0750: 25 69 3a 25 73 3a 20 22 2c 20 28 75 6e 73 69 67  %i:%s: ", (unsig
0760: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 70  ned long long) p
0770: 74 68 72 65 61 64 5f 73 65 6c 66 28 29 2c 20 5f  thread_self(), _
0780: 5f 46 49 4c 45 5f 5f 2c 20 5f 5f 4c 49 4e 45 5f  _FILE__, __LINE_
0790: 5f 2c 20 5f 5f 66 75 6e 63 5f 5f 29 3b 20 5c 0a  _, __func__); \.
07a0: 09 69 66 20 28 62 75 66 6f 66 66 20 3c 20 73 69  .if (bufoff < si
07b0: 7a 65 6f 66 28 62 75 66 29 29 20 7b 20 5c 0a 09  zeof(buf)) { \..
07c0: 09 62 75 66 6f 66 66 20 2b 3d 20 73 6e 70 72 69  .bufoff += snpri
07d0: 6e 74 66 28 62 75 66 20 2b 20 62 75 66 6f 66 66  ntf(buf + bufoff
07e0: 2c 20 73 69 7a 65 6f 66 28 62 75 66 29 20 2d 20  , sizeof(buf) - 
07f0: 62 75 66 6f 66 66 2c 20 78 29 3b 20 5c 0a 09 7d  bufoff, x); \..}
0800: 3b 20 5c 0a 09 69 66 20 28 62 75 66 6f 66 66 20  ; \..if (bufoff 
0810: 3c 20 73 69 7a 65 6f 66 28 62 75 66 29 29 20 7b  < sizeof(buf)) {
0820: 20 5c 0a 09 09 62 75 66 6f 66 66 20 2b 3d 20 73   \...bufoff += s
0830: 6e 70 72 69 6e 74 66 28 62 75 66 20 2b 20 62 75  nprintf(buf + bu
0840: 66 6f 66 66 2c 20 73 69 7a 65 6f 66 28 62 75 66  foff, sizeof(buf
0850: 29 20 2d 20 62 75 66 6f 66 66 2c 20 22 5c 6e 22  ) - bufoff, "\n"
0860: 29 3b 5c 0a 09 7d 20 5c 0a 09 69 66 20 28 62 75  );\..} \..if (bu
0870: 66 6f 66 66 20 3e 20 73 69 7a 65 6f 66 28 62 75  foff > sizeof(bu
0880: 66 29 29 20 7b 20 5c 0a 09 09 62 75 66 6f 66 66  f)) { \...bufoff
0890: 20 3d 20 73 69 7a 65 6f 66 28 62 75 66 29 3b 20   = sizeof(buf); 
08a0: 5c 0a 09 7d 3b 20 5c 0a 09 77 72 69 74 65 28 61  \..}; \..write(a
08b0: 70 70 66 73 5f 64 65 62 75 67 5f 66 64 2c 20 62  ppfs_debug_fd, b
08c0: 75 66 2c 20 62 75 66 6f 66 66 29 3b 20 5c 0a 7d  uf, bufoff); \.}
08d0: 0a 23 65 6c 73 65 0a 23 64 65 66 69 6e 65 20 41  .#else.#define A
08e0: 50 50 46 53 5f 44 45 42 55 47 28 78 2e 2e 2e 29  PPFS_DEBUG(x...)
08f0: 20 2f 2a 2a 2f 0a 23 65 6e 64 69 66 0a 0a 2f 2a   /**/.#endif../*
0900: 0a 20 2a 20 53 48 41 31 20 54 63 6c 20 50 61 63  . * SHA1 Tcl Pac
0910: 6b 61 67 65 20 69 6e 69 74 69 61 6c 69 7a 65 72  kage initializer
0920: 2c 20 66 72 6f 6d 20 73 68 61 31 2e 6f 0a 20 2a  , from sha1.o. *
0930: 2f 0a 69 6e 74 20 53 68 61 31 5f 49 6e 69 74 28  /.int Sha1_Init(
0940: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
0950: 72 70 29 3b 0a 0a 2f 2a 0a 20 2a 20 54 68 72 65  rp);../*. * Thre
0960: 61 64 20 53 70 65 63 69 66 69 63 20 44 61 74 61  ad Specific Data
0970: 20 28 54 53 44 29 20 66 6f 72 20 54 63 6c 20 49   (TSD) for Tcl I
0980: 6e 74 65 72 70 72 65 74 65 72 20 66 6f 72 20 74  nterpreter for t
0990: 68 65 20 63 75 72 72 65 6e 74 20 74 68 72 65 61  he current threa
09a0: 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 70 74 68  d. */.static pth
09b0: 72 65 61 64 5f 6b 65 79 5f 74 20 69 6e 74 65 72  read_key_t inter
09c0: 70 4b 65 79 3b 0a 0a 2f 2a 0a 20 2a 20 47 6c 6f  pKey;../*. * Glo
09d0: 62 61 6c 20 76 61 72 69 61 62 6c 65 73 2c 20 6e  bal variables, n
09e0: 65 65 64 65 64 20 66 6f 72 20 61 6c 6c 20 74 68  eeded for all th
09f0: 72 65 61 64 73 20 62 75 74 20 6f 6e 6c 79 20 69  reads but only i
0a00: 6e 69 74 69 61 6c 69 7a 65 64 20 62 65 66 6f 72  nitialized befor
0a10: 65 20 61 6e 79 0a 20 2a 20 46 55 53 45 20 74 68  e any. * FUSE th
0a20: 72 65 61 64 73 20 61 72 65 20 63 72 65 61 74 65  reads are create
0a30: 64 0a 20 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 72  d. */.const char
0a40: 20 2a 61 70 70 66 73 5f 63 61 63 68 65 64 69 72   *appfs_cachedir
0a50: 3b 0a 74 69 6d 65 5f 74 20 61 70 70 66 73 5f 62  ;.time_t appfs_b
0a60: 6f 6f 74 74 69 6d 65 3b 0a 69 6e 74 20 61 70 70  oottime;.int app
0a70: 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 20  fs_fuse_started 
0a80: 3d 20 30 3b 0a 69 6e 74 20 61 70 70 66 73 5f 74  = 0;.int appfs_t
0a90: 68 72 65 61 64 65 64 5f 74 63 6c 3b 0a 0a 2f 2a  hreaded_tcl;../*
0aa0: 0a 20 2a 20 47 6c 6f 62 61 6c 20 76 61 72 69 61  . * Global varia
0ab0: 62 6c 65 73 20 66 6f 72 20 41 70 70 46 53 20 63  bles for AppFS c
0ac0: 61 63 68 69 6e 67 0a 20 2a 2f 0a 70 74 68 72 65  aching. */.pthre
0ad0: 61 64 5f 6d 75 74 65 78 5f 74 20 61 70 70 66 73  ad_mutex_t appfs
0ae0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
0af0: 5f 6d 75 74 65 78 20 3d 20 50 54 48 52 45 41 44  _mutex = PTHREAD
0b00: 5f 4d 55 54 45 58 5f 49 4e 49 54 49 41 4c 49 5a  _MUTEX_INITIALIZ
0b10: 45 52 3b 0a 69 6e 74 20 61 70 70 66 73 5f 70 61  ER;.int appfs_pa
0b20: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69  th_info_cache_si
0b30: 7a 65 20 3d 20 38 32 30 39 3b 0a 73 74 72 75 63  ze = 8209;.struc
0b40: 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f  t appfs_pathinfo
0b50: 20 2a 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66   *appfs_path_inf
0b60: 6f 5f 63 61 63 68 65 20 3d 20 4e 55 4c 4c 3b 0a  o_cache = NULL;.
0b70: 0a 23 69 66 6e 64 65 66 20 54 43 4c 5f 54 48 52  .#ifndef TCL_THR
0b80: 45 41 44 53 0a 2f 2a 0a 20 2a 20 48 61 6e 64 6c  EADS./*. * Handl
0b90: 65 20 75 6e 74 68 72 65 61 64 65 64 20 54 63 6c  e unthreaded Tcl
0ba0: 0a 20 2a 2f 0a 70 74 68 72 65 61 64 5f 6d 75 74  . */.pthread_mut
0bb0: 65 78 5f 74 20 61 70 70 66 73 5f 74 63 6c 5f 62  ex_t appfs_tcl_b
0bc0: 69 67 5f 67 6c 6f 62 61 6c 5f 6c 6f 63 6b 20 3d  ig_global_lock =
0bd0: 20 50 54 48 52 45 41 44 5f 4d 55 54 45 58 5f 49   PTHREAD_MUTEX_I
0be0: 4e 49 54 49 41 4c 49 5a 45 52 3b 0a 23 64 65 66  NITIALIZER;.#def
0bf0: 69 6e 65 20 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ine appfs_call_l
0c00: 69 62 74 63 6c 5f 65 6e 74 65 72 20 70 74 68 72  ibtcl_enter pthr
0c10: 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26  ead_mutex_lock(&
0c20: 61 70 70 66 73 5f 74 63 6c 5f 62 69 67 5f 67 6c  appfs_tcl_big_gl
0c30: 6f 62 61 6c 5f 6c 6f 63 6b 29 3b 0a 23 64 65 66  obal_lock);.#def
0c40: 69 6e 65 20 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ine appfs_call_l
0c50: 69 62 74 63 6c 5f 65 78 69 74 20 70 74 68 72 65  ibtcl_exit pthre
0c60: 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28  ad_mutex_unlock(
0c70: 26 61 70 70 66 73 5f 74 63 6c 5f 62 69 67 5f 67  &appfs_tcl_big_g
0c80: 6c 6f 62 61 6c 5f 6c 6f 63 6b 29 3b 0a 23 65 6c  lobal_lock);.#el
0c90: 73 65 0a 23 64 65 66 69 6e 65 20 61 70 70 66 73  se.#define appfs
0ca0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 6e 74  _call_libtcl_ent
0cb0: 65 72 20 2f 2a 2a 2f 0a 23 64 65 66 69 6e 65 20  er /**/.#define 
0cc0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
0cd0: 6c 5f 65 78 69 74 20 2f 2a 2a 2f 0a 23 65 6e 64  l_exit /**/.#end
0ce0: 69 66 0a 23 64 65 66 69 6e 65 20 61 70 70 66 73  if.#define appfs
0cf0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 78 2e 2e  _call_libtcl(x..
0d00: 2e 29 20 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  .) appfs_call_li
0d10: 62 74 63 6c 5f 65 6e 74 65 72 20 78 20 61 70 70  btcl_enter x app
0d20: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65  fs_call_libtcl_e
0d30: 78 69 74 0a 0a 2f 2a 0a 20 2a 20 47 6c 6f 62 61  xit../*. * Globa
0d40: 6c 20 76 61 72 69 61 62 6c 65 73 20 66 6f 72 20  l variables for 
0d50: 41 70 70 46 53 20 54 63 6c 20 49 6e 74 65 72 70  AppFS Tcl Interp
0d60: 72 65 74 65 72 20 72 65 73 74 61 72 74 69 6e 67  reter restarting
0d70: 0a 20 2a 2f 0a 69 6e 74 20 69 6e 74 65 72 70 5f  . */.int interp_
0d80: 72 65 73 65 74 5f 6b 65 79 20 3d 20 30 3b 0a 0a  reset_key = 0;..
0d90: 2f 2a 0a 20 2a 20 41 70 70 46 53 20 50 61 74 68  /*. * AppFS Path
0da0: 20 54 79 70 65 3a 20 20 44 65 73 63 72 69 62 65   Type:  Describe
0db0: 73 20 74 68 65 20 74 79 70 65 20 6f 66 20 70 61  s the type of pa
0dc0: 74 68 20 61 20 67 69 76 65 6e 20 66 69 6c 65 20  th a given file 
0dd0: 69 73 0a 20 2a 2f 0a 74 79 70 65 64 65 66 20 65  is. */.typedef e
0de0: 6e 75 6d 20 7b 0a 09 41 50 50 46 53 5f 50 41 54  num {..APPFS_PAT
0df0: 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 2c 0a 09  HTYPE_INVALID,..
0e00: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44  APPFS_PATHTYPE_D
0e10: 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 2c 0a 09  OES_NOT_EXIST,..
0e20: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46  APPFS_PATHTYPE_F
0e30: 49 4c 45 2c 0a 09 41 50 50 46 53 5f 50 41 54 48  ILE,..APPFS_PATH
0e40: 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 2c 0a  TYPE_DIRECTORY,.
0e50: 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f  .APPFS_PATHTYPE_
0e60: 53 59 4d 4c 49 4e 4b 2c 0a 09 41 50 50 46 53 5f  SYMLINK,..APPFS_
0e70: 50 41 54 48 54 59 50 45 5f 53 4f 43 4b 45 54 2c  PATHTYPE_SOCKET,
0e80: 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  ..APPFS_PATHTYPE
0e90: 5f 46 49 46 4f 2c 0a 7d 20 61 70 70 66 73 5f 70  _FIFO,.} appfs_p
0ea0: 61 74 68 74 79 70 65 5f 74 3b 0a 0a 2f 2a 0a 20  athtype_t;../*. 
0eb0: 2a 20 41 70 70 46 53 20 50 61 74 68 20 49 6e 66  * AppFS Path Inf
0ec0: 6f 72 6d 61 74 69 6f 6e 3a 0a 20 2a 20 20 20 20  ormation:. *    
0ed0: 20 20 20 20 20 43 6f 6d 70 6c 65 74 65 6c 79 20       Completely 
0ee0: 64 65 73 63 72 69 62 65 73 20 61 20 73 70 65 63  describes a spec
0ef0: 69 66 69 63 20 70 61 74 68 2c 20 68 6f 77 20 69  ific path, how i
0f00: 74 20 73 68 6f 75 6c 64 20 62 65 20 72 65 74 75  t should be retu
0f10: 72 6e 65 64 20 74 6f 0a 20 2a 20 20 20 20 20 20  rned to. *      
0f20: 20 20 20 74 6f 20 74 68 65 20 6b 65 72 6e 65 6c     to the kernel
0f30: 0a 20 2a 2f 0a 73 74 72 75 63 74 20 61 70 70 66  . */.struct appf
0f40: 73 5f 70 61 74 68 69 6e 66 6f 20 7b 0a 09 61 70  s_pathinfo {..ap
0f50: 70 66 73 5f 70 61 74 68 74 79 70 65 5f 74 20 74  pfs_pathtype_t t
0f60: 79 70 65 3b 0a 09 74 69 6d 65 5f 74 20 74 69 6d  ype;..time_t tim
0f70: 65 3b 0a 09 63 68 61 72 20 68 6f 73 74 6e 61 6d  e;..char hostnam
0f80: 65 5b 32 35 36 5d 3b 0a 09 69 6e 74 20 70 61 63  e[256];..int pac
0f90: 6b 61 67 65 64 3b 0a 09 75 6e 73 69 67 6e 65 64  kaged;..unsigned
0fa0: 20 6c 6f 6e 67 20 6c 6f 6e 67 20 69 6e 6f 64 65   long long inode
0fb0: 3b 0a 09 75 6e 69 6f 6e 20 7b 0a 09 09 73 74 72  ;..union {...str
0fc0: 75 63 74 20 7b 0a 09 09 09 69 6e 74 20 63 68 69  uct {....int chi
0fd0: 6c 64 63 6f 75 6e 74 3b 0a 09 09 7d 20 64 69 72  ldcount;...} dir
0fe0: 3b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09 09  ;...struct {....
0ff0: 69 6e 74 20 65 78 65 63 75 74 61 62 6c 65 3b 0a  int executable;.
1000: 09 09 09 69 6e 74 20 73 75 69 64 52 6f 6f 74 3b  ...int suidRoot;
1010: 0a 09 09 09 69 6e 74 20 77 6f 72 6c 64 61 63 63  ....int worldacc
1020: 65 73 73 69 62 6c 65 3b 0a 09 09 09 6f 66 66 5f  essible;....off_
1030: 74 20 73 69 7a 65 3b 0a 09 09 7d 20 66 69 6c 65  t size;...} file
1040: 3b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09 09  ;...struct {....
1050: 6f 66 66 5f 74 20 73 69 7a 65 3b 0a 09 09 09 63  off_t size;....c
1060: 68 61 72 20 73 6f 75 72 63 65 5b 32 35 36 5d 3b  har source[256];
1070: 0a 09 09 7d 20 73 79 6d 6c 69 6e 6b 3b 0a 09 7d  ...} symlink;..}
1080: 20 74 79 70 65 69 6e 66 6f 3b 0a 0a 09 2f 2a 20   typeinfo;.../* 
1090: 41 74 74 72 69 62 75 74 65 73 20 75 73 65 64 20  Attributes used 
10a0: 6f 6e 6c 79 20 66 6f 72 20 63 61 63 68 69 6e 67  only for caching
10b0: 20 65 6e 74 72 69 65 73 20 2a 2f 0a 09 63 68 61   entries */..cha
10c0: 72 20 2a 5f 63 61 63 68 65 5f 70 61 74 68 3b 0a  r *_cache_path;.
10d0: 09 75 69 64 5f 74 20 5f 63 61 63 68 65 5f 75 69  .uid_t _cache_ui
10e0: 64 3b 0a 7d 3b 0a 0a 2f 2a 0a 20 2a 20 43 72 65  d;.};../*. * Cre
10f0: 61 74 65 20 61 20 6e 65 77 20 54 63 6c 20 69 6e  ate a new Tcl in
1100: 74 65 72 70 72 65 74 65 72 20 61 6e 64 20 63 6f  terpreter and co
1110: 6d 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61 6c  mpletely initial
1120: 69 7a 65 20 69 74 0a 20 2a 2f 0a 73 74 61 74 69  ize it. */.stati
1130: 63 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 61 70  c Tcl_Interp *ap
1140: 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e  pfs_create_TclIn
1150: 74 65 72 70 28 63 68 61 72 20 2a 2a 65 72 72 6f  terp(char **erro
1160: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 54 63 6c  r_string) {..Tcl
1170: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
1180: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 09  ..int tcl_ret;..
1190: 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c 5f  const char *tcl_
11a0: 73 65 74 76 61 72 5f 72 65 74 3b 0a 0a 09 41 50  setvar_ret;...AP
11b0: 50 46 53 5f 44 45 42 55 47 28 22 43 72 65 61 74  PFS_DEBUG("Creat
11c0: 69 6e 67 20 6e 65 77 20 54 63 6c 20 69 6e 74 65  ing new Tcl inte
11d0: 72 70 72 65 74 65 72 20 66 6f 72 20 54 49 44 20  rpreter for TID 
11e0: 3d 20 30 78 25 6c 6c 78 22 2c 20 28 75 6e 73 69  = 0x%llx", (unsi
11f0: 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20  gned long long) 
1200: 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29 29 3b  pthread_self());
1210: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
1220: 62 74 63 6c 28 0a 09 09 69 6e 74 65 72 70 20 3d  btcl(...interp =
1230: 20 54 63 6c 5f 43 72 65 61 74 65 49 6e 74 65 72   Tcl_CreateInter
1240: 70 28 29 3b 0a 09 29 0a 09 69 66 20 28 69 6e 74  p();..)..if (int
1250: 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  erp == NULL) {..
1260: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
1270: 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61   "Unable to crea
1280: 74 65 20 54 63 6c 20 49 6e 74 65 72 70 72 65 74  te Tcl Interpret
1290: 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e  er.  Aborting.\n
12a0: 22 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f 72  ");....if (error
12b0: 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65  _string) {....*e
12c0: 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74  rror_string = st
12d0: 72 64 75 70 28 22 55 6e 61 62 6c 65 20 74 6f 20  rdup("Unable to 
12e0: 63 72 65 61 74 65 20 54 63 6c 20 69 6e 74 65 72  create Tcl inter
12f0: 70 72 65 74 65 72 2e 22 29 3b 0a 09 09 7d 0a 0a  preter.");...}..
1300: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
1310: 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .}...appfs_call_
1320: 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65  libtcl(Tcl_Prese
1330: 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  rve(interp);)...
1340: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
1350: 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54  l(...tcl_ret = T
1360: 63 6c 5f 49 6e 69 74 28 69 6e 74 65 72 70 29 3b  cl_Init(interp);
1370: 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ..)..if (tcl_ret
1380: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
1390: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
13a0: 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69  "Unable to initi
13b0: 61 6c 69 7a 65 20 54 63 6c 2e 20 20 41 62 6f 72  alize Tcl.  Abor
13c0: 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 70  ting.\n");...app
13d0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
13e0: 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
13f0: 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73  r, "Tcl Error is
1400: 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74  : %s\n", Tcl_Get
1410: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
1420: 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69 66  erp));...)....if
1430: 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20   (error_string) 
1440: 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  {....appfs_call_
1450: 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72 72  libtcl(.....*err
1460: 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64  or_string = strd
1470: 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  up(Tcl_GetString
1480: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
1490: 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70  ....)...}....app
14a0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
14b0: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
14c0: 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44 45  p);)....APPFS_DE
14d0: 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67  BUG("Terminating
14e0: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72   Tcl interpreter
14f0: 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61  .");....appfs_ca
1500: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65  ll_libtcl(Tcl_De
1510: 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72  leteInterp(inter
1520: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e  p);)....return(N
1530: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  ULL);..}...appfs
1540: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
1550: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76  tcl_ret = Tcl_Ev
1560: 61 6c 28 69 6e 74 65 72 70 2c 20 22 70 61 63 6b  al(interp, "pack
1570: 61 67 65 20 69 66 6e 65 65 64 65 64 20 73 68 61  age ifneeded sha
1580: 31 20 31 2e 30 20 5b 6c 69 73 74 20 6c 6f 61 64  1 1.0 [list load
1590: 20 7b 7d 20 73 68 61 31 5d 22 29 3b 0a 09 29 0a   {} sha1]");..).
15a0: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
15b0: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69  TCL_OK) {...fpri
15c0: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61  ntf(stderr, "Una
15d0: 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a  ble to initializ
15e0: 65 20 54 63 6c 20 53 48 41 31 2e 20 20 41 62 6f  e Tcl SHA1.  Abo
15f0: 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70  rting.\n");...ap
1600: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
1610: 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ....fprintf(stde
1620: 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69  rr, "Tcl Error i
1630: 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65  s: %s\n", Tcl_Ge
1640: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
1650: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69  terp));...)....i
1660: 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29  f (error_string)
1670: 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c   {....appfs_call
1680: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72  _libtcl(.....*er
1690: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
16a0: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
16b0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
16c0: 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70  ;....)...}....ap
16d0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
16e0: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
16f0: 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44  rp);)....APPFS_D
1700: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
1710: 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  g Tcl interprete
1720: 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63  r.");....appfs_c
1730: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44  all_libtcl(Tcl_D
1740: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65  eleteInterp(inte
1750: 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28  rp);)....return(
1760: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  NULL);..}...appf
1770: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
1780: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45  .tcl_ret = Tcl_E
1790: 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 70 61 63  val(interp, "pac
17a0: 6b 61 67 65 20 69 66 6e 65 65 64 65 64 20 61 70  kage ifneeded ap
17b0: 70 66 73 64 20 31 2e 30 20 5b 6c 69 73 74 20 6c  pfsd 1.0 [list l
17c0: 6f 61 64 20 7b 7d 20 61 70 70 66 73 64 5d 22 29  oad {} appfsd]")
17d0: 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65  ;..)..if (tcl_re
17e0: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
17f0: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
1800: 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74   "Unable to init
1810: 69 61 6c 69 7a 65 20 54 63 6c 20 41 70 70 46 53  ialize Tcl AppFS
1820: 20 50 61 63 6b 61 67 65 2e 20 20 41 62 6f 72 74   Package.  Abort
1830: 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 70 66  ing.\n");...appf
1840: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
1850: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
1860: 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  , "Tcl Error is:
1870: 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53   %s\n", Tcl_GetS
1880: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
1890: 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69 66 20  rp));...)....if 
18a0: 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b  (error_string) {
18b0: 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
18c0: 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72 72 6f  ibtcl(.....*erro
18d0: 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75  r_string = strdu
18e0: 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  p(Tcl_GetStringR
18f0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
1900: 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70 66  ...)...}....appf
1910: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
1920: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
1930: 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44 45 42  );)....APPFS_DEB
1940: 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20  UG("Terminating 
1950: 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e  Tcl interpreter.
1960: 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c  ");....appfs_cal
1970: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c  l_libtcl(Tcl_Del
1980: 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70  eteInterp(interp
1990: 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  );)....return(NU
19a0: 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  LL);..}.../*.. *
19b0: 20 4c 6f 61 64 20 22 70 6b 69 2e 74 63 6c 22 20   Load "pki.tcl" 
19c0: 69 6e 20 74 68 65 20 73 61 6d 65 20 77 61 79 20  in the same way 
19d0: 61 73 20 61 70 70 66 73 64 2e 74 63 6c 20 28 73  as appfsd.tcl (s
19e0: 65 65 20 62 65 6c 6f 77 29 0a 09 20 2a 2f 0a 09  ee below).. */..
19f0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
1a00: 6c 5f 65 6e 74 65 72 0a 09 09 74 63 6c 5f 72 65  l_enter...tcl_re
1a10: 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74  t = Tcl_Eval(int
1a20: 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64 65  erp, "".#include
1a30: 20 22 70 6b 69 2e 74 63 6c 2e 68 22 0a 09 09 22   "pki.tcl.h"..."
1a40: 22 29 3b 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  ");..appfs_call_
1a50: 6c 69 62 74 63 6c 5f 65 78 69 74 0a 09 69 66 20  libtcl_exit..if 
1a60: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
1a70: 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28  OK) {...fprintf(
1a80: 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20  stderr, "Unable 
1a90: 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63  to initialize Tc
1aa0: 6c 20 50 4b 49 2e 20 20 41 62 6f 72 74 69 6e 67  l PKI.  Aborting
1ab0: 2e 5c 6e 22 29 3b 0a 09 09 61 70 70 66 73 5f 63  .\n");...appfs_c
1ac0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 66  all_libtcl(....f
1ad0: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
1ae0: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
1af0: 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  \n", Tcl_GetStri
1b00: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
1b10: 29 3b 0a 09 09 29 0a 0a 09 09 69 66 20 28 65 72  );...)....if (er
1b20: 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09  ror_string) {...
1b30: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
1b40: 63 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73  cl(.....*error_s
1b50: 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54  tring = strdup(T
1b60: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
1b70: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09  lt(interp));....
1b80: 29 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63  )...}....appfs_c
1b90: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
1ba0: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
1bb0: 0a 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
1bc0: 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c  "Terminating Tcl
1bd0: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b   interpreter.");
1be0: 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
1bf0: 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65  ibtcl(Tcl_Delete
1c00: 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29  Interp(interp);)
1c10: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
1c20: 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4c 6f  ;..}.../*.. * Lo
1c30: 61 64 20 74 68 65 20 22 61 70 70 66 73 64 2e 74  ad the "appfsd.t
1c40: 63 6c 22 20 73 63 72 69 70 74 2c 20 77 68 69 63  cl" script, whic
1c50: 68 20 69 73 20 22 63 6f 6d 70 69 6c 65 64 22 20  h is "compiled" 
1c60: 69 6e 74 6f 20 61 20 43 20 68 65 61 64 65 72 0a  into a C header.
1c70: 09 20 2a 20 73 6f 20 74 68 61 74 20 69 74 20 64  . * so that it d
1c80: 6f 65 73 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20  oes not need to 
1c90: 65 78 69 73 74 20 6f 6e 20 74 68 65 20 66 69 6c  exist on the fil
1ca0: 65 73 79 73 74 65 6d 20 61 6e 64 20 63 61 6e 20  esystem and can 
1cb0: 62 65 0a 09 20 2a 20 64 69 72 65 63 74 6c 79 20  be.. * directly 
1cc0: 65 76 61 6c 75 61 74 65 64 2e 0a 09 20 2a 2f 0a  evaluated... */.
1cd0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
1ce0: 63 6c 5f 65 6e 74 65 72 0a 09 09 74 63 6c 5f 72  cl_enter...tcl_r
1cf0: 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e  et = Tcl_Eval(in
1d00: 74 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64  terp, "".#includ
1d10: 65 20 22 61 70 70 66 73 64 2e 74 63 6c 2e 68 22  e "appfsd.tcl.h"
1d20: 0a 09 09 22 22 29 3b 0a 09 61 70 70 66 73 5f 63  ..."");..appfs_c
1d30: 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74 0a  all_libtcl_exit.
1d40: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
1d50: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69  TCL_OK) {...fpri
1d60: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61  ntf(stderr, "Una
1d70: 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a  ble to initializ
1d80: 65 20 54 63 6c 20 41 70 70 46 53 20 73 63 72 69  e Tcl AppFS scri
1d90: 70 74 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e  pt.  Aborting.\n
1da0: 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  ");...appfs_call
1db0: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 66 70 72 69  _libtcl(....fpri
1dc0: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c  ntf(stderr, "Tcl
1dd0: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22   Error is: %s\n"
1de0: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
1df0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
1e00: 09 09 29 0a 0a 09 09 69 66 20 28 65 72 72 6f 72  ..)....if (error
1e10: 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 61 70  _string) {....ap
1e20: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
1e30: 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69  .....*error_stri
1e40: 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f  ng = strdup(Tcl_
1e50: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
1e60: 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29 0a 09  interp));....)..
1e70: 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  .}....appfs_call
1e80: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
1e90: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
1ea0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 65  .APPFS_DEBUG("Te
1eb0: 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e  rminating Tcl in
1ec0: 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09  terpreter.");...
1ed0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
1ee0: 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74  cl(Tcl_DeleteInt
1ef0: 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  erp(interp);)...
1f00: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
1f10: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65 74 20 67  }.../*.. * Set g
1f20: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20  lobal variables 
1f30: 66 72 6f 6d 20 43 20 74 6f 20 54 63 6c 0a 09 20  from C to Tcl.. 
1f40: 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  */..appfs_call_l
1f50: 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 73 65 74  ibtcl(...tcl_set
1f60: 76 61 72 5f 72 65 74 20 3d 20 54 63 6c 5f 53 65  var_ret = Tcl_Se
1f70: 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 3a 3a  tVar(interp, "::
1f80: 61 70 70 66 73 3a 3a 63 61 63 68 65 64 69 72 22  appfs::cachedir"
1f90: 2c 20 61 70 70 66 73 5f 63 61 63 68 65 64 69 72  , appfs_cachedir
1fa0: 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c  , TCL_GLOBAL_ONL
1fb0: 59 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f  Y);..)..if (tcl_
1fc0: 73 65 74 76 61 72 5f 72 65 74 20 3d 3d 20 4e 55  setvar_ret == NU
1fd0: 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28  LL) {...fprintf(
1fe0: 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20  stderr, "Unable 
1ff0: 74 6f 20 73 65 74 20 63 61 63 68 65 20 64 69 72  to set cache dir
2000: 65 63 74 6f 72 79 2e 20 20 54 68 69 73 20 73 68  ectory.  This sh
2010: 6f 75 6c 64 20 6e 65 76 65 72 20 66 61 69 6c 2e  ould never fail.
2020: 5c 6e 22 29 3b 0a 0a 09 09 69 66 20 28 65 72 72  \n");....if (err
2030: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09  or_string) {....
2040: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
2050: 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74  l(.....*error_st
2060: 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63  ring = strdup(Tc
2070: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
2080: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29  t(interp));....)
2090: 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61  ...}....appfs_ca
20a0: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
20b0: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
20c0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
20d0: 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20  Terminating Tcl 
20e0: 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a  interpreter.");.
20f0: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
2100: 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49  btcl(Tcl_DeleteI
2110: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a  nterp(interp);).
2120: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
2130: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 49 6e 69  ..}.../*.. * Ini
2140: 74 69 61 6c 69 7a 65 20 74 68 65 20 22 61 70 70  tialize the "app
2150: 66 73 64 2e 74 63 6c 22 20 65 6e 76 69 72 6f 6e  fsd.tcl" environ
2160: 6d 65 6e 74 2c 20 77 68 69 63 68 20 6d 75 73 74  ment, which must
2170: 20 62 65 20 64 6f 6e 65 20 61 66 74 65 72 0a 09   be done after..
2180: 20 2a 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62   * global variab
2190: 6c 65 73 20 61 72 65 20 73 65 74 2e 0a 09 20 2a  les are set... *
21a0: 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  /..appfs_call_li
21b0: 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20  btcl(...tcl_ret 
21c0: 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  = Tcl_Eval(inter
21d0: 70 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 69 6e 69  p, "::appfs::ini
21e0: 74 22 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c  t");..)..if (tcl
21f0: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  _ret != TCL_OK) 
2200: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  {...fprintf(stde
2210: 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69  rr, "Unable to i
2220: 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 41 70  nitialize Tcl Ap
2230: 70 46 53 20 73 63 72 69 70 74 20 28 3a 3a 61 70  pFS script (::ap
2240: 70 66 73 3a 3a 69 6e 69 74 29 2e 20 20 41 62 6f  pfs::init).  Abo
2250: 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70  rting.\n");...ap
2260: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
2270: 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ....fprintf(stde
2280: 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69  rr, "Tcl Error i
2290: 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65  s: %s\n", Tcl_Ge
22a0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
22b0: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69  terp));...)....i
22c0: 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29  f (error_string)
22d0: 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c   {....appfs_call
22e0: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72  _libtcl(.....*er
22f0: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
2300: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
2310: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
2320: 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70  ;....)...}....ap
2330: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
2340: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
2350: 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44  rp);)....APPFS_D
2360: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
2370: 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  g Tcl interprete
2380: 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63  r.");....appfs_c
2390: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44  all_libtcl(Tcl_D
23a0: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65  eleteInterp(inte
23b0: 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28  rp);)....return(
23c0: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  NULL);..}.../*..
23d0: 20 2a 20 48 69 64 65 20 73 6f 6d 65 20 54 63 6c   * Hide some Tcl
23e0: 20 63 6f 6d 6d 61 6e 64 73 20 74 68 61 74 20 77   commands that w
23f0: 65 20 64 6f 20 6e 6f 74 20 63 61 72 65 20 74 6f  e do not care to
2400: 20 75 73 65 20 61 6e 64 20 77 68 69 63 68 20 6d   use and which m
2410: 61 79 0a 09 20 2a 20 73 6c 6f 77 20 64 6f 77 6e  ay.. * slow down
2420: 20 72 75 6e 2d 74 69 6d 65 20 6f 70 65 72 61 74   run-time operat
2430: 69 6f 6e 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 66  ions... */..appf
2440: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
2450: 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61 6e 64  .Tcl_HideCommand
2460: 28 69 6e 74 65 72 70 2c 20 22 61 75 74 6f 5f 6c  (interp, "auto_l
2470: 6f 61 64 5f 69 6e 64 65 78 22 2c 20 22 61 75 74  oad_index", "aut
2480: 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22 29 3b 0a  o_load_index");.
2490: 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61 6e  ..Tcl_HideComman
24a0: 64 28 69 6e 74 65 72 70 2c 20 22 75 6e 6b 6e 6f  d(interp, "unkno
24b0: 77 6e 22 2c 20 22 75 6e 6b 6e 6f 77 6e 22 29 3b  wn", "unknown");
24c0: 0a 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61  ...Tcl_HideComma
24d0: 6e 64 28 69 6e 74 65 72 70 2c 20 22 65 78 69 74  nd(interp, "exit
24e0: 22 2c 20 22 65 78 69 74 22 29 3b 0a 09 29 0a 0a  ", "exit");..)..
24f0: 09 2f 2a 0a 09 20 2a 20 52 65 6c 65 61 73 65 20  ./*.. * Release 
2500: 74 68 65 20 68 6f 6c 64 20 77 65 20 68 61 76 65  the hold we have
2510: 20 6f 6e 20 74 68 65 20 69 6e 74 65 72 70 72 65   on the interpre
2520: 74 65 72 20 73 6f 20 74 68 61 74 20 69 74 20 6d  ter so that it m
2530: 61 79 20 62 65 0a 09 20 2a 20 64 65 6c 65 74 65  ay be.. * delete
2540: 64 20 69 66 20 6e 65 65 64 65 64 0a 09 20 2a 2f  d if needed.. */
2550: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
2560: 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28  tcl(Tcl_Release(
2570: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 2f 2a 0a 09  interp);).../*..
2580: 20 2a 20 52 65 74 75 72 6e 20 74 68 65 20 63 6f   * Return the co
2590: 6d 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61 6c  mpletely initial
25a0: 69 7a 65 64 20 69 6e 74 65 72 70 72 65 74 65 72  ized interpreter
25b0: 0a 09 20 2a 2f 0a 09 72 65 74 75 72 6e 28 69 6e  .. */..return(in
25c0: 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  terp);.}../*. * 
25d0: 52 65 74 75 72 6e 20 74 68 65 20 74 68 72 65 61  Return the threa
25e0: 64 2d 73 70 65 63 69 66 69 63 20 54 63 6c 20 69  d-specific Tcl i
25f0: 6e 74 65 72 70 72 65 74 65 72 2c 20 63 72 65 61  nterpreter, crea
2600: 74 69 6e 67 20 69 74 20 69 66 20 6e 65 65 64 65  ting it if neede
2610: 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 54 63 6c  d. */.static Tcl
2620: 5f 49 6e 74 65 72 70 20 2a 61 70 70 66 73 5f 54  _Interp *appfs_T
2630: 63 6c 49 6e 74 65 72 70 28 76 6f 69 64 29 20 7b  clInterp(void) {
2640: 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  ..Tcl_Interp *in
2650: 74 65 72 70 3b 0a 09 69 6e 74 20 70 74 68 72 65  terp;..int pthre
2660: 61 64 5f 72 65 74 3b 0a 09 73 74 61 74 69 63 20  ad_ret;..static 
2670: 5f 5f 74 68 72 65 61 64 20 69 6e 74 20 74 68 72  __thread int thr
2680: 65 61 64 5f 69 6e 74 65 72 70 5f 72 65 73 65 74  ead_interp_reset
2690: 5f 6b 65 79 20 3d 20 30 3b 0a 09 69 6e 74 20 67  _key = 0;..int g
26a0: 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73  lobal_interp_res
26b0: 65 74 5f 6b 65 79 3b 0a 0a 09 67 6c 6f 62 61 6c  et_key;...global
26c0: 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65  _interp_reset_ke
26d0: 79 20 3d 20 5f 5f 73 79 6e 63 5f 66 65 74 63 68  y = __sync_fetch
26e0: 5f 61 6e 64 5f 61 64 64 28 26 69 6e 74 65 72 70  _and_add(&interp
26f0: 5f 72 65 73 65 74 5f 6b 65 79 2c 20 30 29 3b 0a  _reset_key, 0);.
2700: 0a 09 69 6e 74 65 72 70 20 3d 20 70 74 68 72 65  ..interp = pthre
2710: 61 64 5f 67 65 74 73 70 65 63 69 66 69 63 28 69  ad_getspecific(i
2720: 6e 74 65 72 70 4b 65 79 29 3b 0a 09 69 66 20 28  nterpKey);..if (
2730: 69 6e 74 65 72 70 20 21 3d 20 4e 55 4c 4c 20 26  interp != NULL &
2740: 26 20 74 68 72 65 61 64 5f 69 6e 74 65 72 70 5f  & thread_interp_
2750: 72 65 73 65 74 5f 6b 65 79 20 21 3d 20 67 6c 6f  reset_key != glo
2760: 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74  bal_interp_reset
2770: 5f 6b 65 79 29 20 7b 0a 09 09 41 50 50 46 53 5f  _key) {...APPFS_
2780: 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69  DEBUG("Terminati
2790: 6e 67 20 6f 6c 64 20 69 6e 74 65 72 70 72 65 74  ng old interpret
27a0: 65 72 20 61 6e 64 20 72 65 73 74 61 72 74 69 6e  er and restartin
27b0: 67 20 64 75 65 20 74 6f 20 72 65 73 65 74 20 72  g due to reset r
27c0: 65 71 75 65 73 74 2e 22 29 3b 0a 0a 09 09 61 70  equest.");....ap
27d0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
27e0: 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70  Tcl_DeleteInterp
27f0: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 69 6e  (interp);)....in
2800: 74 65 72 70 20 3d 20 4e 55 4c 4c 3b 0a 0a 09 09  terp = NULL;....
2810: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
2820: 68 72 65 61 64 5f 73 65 74 73 70 65 63 69 66 69  hread_setspecifi
2830: 63 28 69 6e 74 65 72 70 4b 65 79 2c 20 69 6e 74  c(interpKey, int
2840: 65 72 70 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 67  erp);..}...if (g
2850: 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73  lobal_interp_res
2860: 65 74 5f 6b 65 79 20 3d 3d 20 2d 31 29 20 7b 0a  et_key == -1) {.
2870: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 52  ..APPFS_DEBUG("R
2880: 65 74 75 72 6e 69 6e 67 20 4e 55 4c 4c 20 73 69  eturning NULL si
2890: 6e 63 65 20 77 65 20 61 72 65 20 69 6e 20 74 68  nce we are in th
28a0: 65 20 70 72 6f 63 65 73 73 20 6f 66 20 74 65 72  e process of ter
28b0: 6d 69 6e 61 74 69 6e 67 20 61 6c 6c 20 74 68 72  minating all thr
28c0: 65 61 64 73 2e 22 29 3b 0a 0a 09 09 72 65 74 75  eads.");....retu
28d0: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74  rn(NULL);..}...t
28e0: 68 72 65 61 64 5f 69 6e 74 65 72 70 5f 72 65 73  hread_interp_res
28f0: 65 74 5f 6b 65 79 20 3d 20 67 6c 6f 62 61 6c 5f  et_key = global_
2900: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
2910: 3b 0a 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  ;...if (interp =
2920: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 6e 74 65  = NULL) {...inte
2930: 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61 74  rp = appfs_creat
2940: 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c  e_TclInterp(NULL
2950: 29 3b 0a 0a 09 09 69 66 20 28 69 6e 74 65 72 70  );....if (interp
2960: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 41   == NULL) {....A
2970: 50 50 46 53 5f 44 45 42 55 47 28 22 43 72 65 61  PPFS_DEBUG("Crea
2980: 74 65 20 69 6e 74 65 72 70 20 66 61 69 6c 65 64  te interp failed
2990: 2c 20 72 65 74 75 72 6e 69 6e 67 69 6e 20 66 61  , returningin fa
29a0: 69 6c 75 72 65 2e 22 29 3b 0a 0a 09 09 09 72 65  ilure.");.....re
29b0: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a  turn(NULL);...}.
29c0: 0a 09 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d  ...pthread_ret =
29d0: 20 70 74 68 72 65 61 64 5f 73 65 74 73 70 65 63   pthread_setspec
29e0: 69 66 69 63 28 69 6e 74 65 72 70 4b 65 79 2c 20  ific(interpKey, 
29f0: 69 6e 74 65 72 70 29 3b 0a 09 09 69 66 20 28 70  interp);...if (p
2a00: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
2a10: 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55   {....APPFS_DEBU
2a20: 47 28 22 70 74 68 72 65 61 64 5f 73 65 74 73 70  G("pthread_setsp
2a30: 65 63 69 66 69 63 28 29 20 66 61 69 6c 65 64 2e  ecific() failed.
2a40: 20 20 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63    Terminating Tc
2a50: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29  l interpreter.")
2a60: 3b 0a 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c  ;.....appfs_call
2a70: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65  _libtcl(Tcl_Dele
2a80: 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29  teInterp(interp)
2a90: 3b 29 0a 0a 09 09 09 72 65 74 75 72 6e 28 4e 55  ;).....return(NU
2aa0: 4c 4c 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65  LL);...}..}...re
2ab0: 74 75 72 6e 28 69 6e 74 65 72 70 29 3b 0a 7d 0a  turn(interp);.}.
2ac0: 0a 2f 2a 0a 20 2a 20 45 76 61 6c 75 61 74 65 20  ./*. * Evaluate 
2ad0: 61 20 54 63 6c 20 73 63 72 69 70 74 20 63 6f 6e  a Tcl script con
2ae0: 73 74 72 75 63 74 65 64 20 62 79 20 63 6f 6e 63  structed by conc
2af0: 61 74 65 6e 61 74 69 6e 67 20 61 20 62 75 6e 63  atenating a bunc
2b00: 68 20 6f 66 20 43 20 73 74 72 69 6e 67 73 0a 20  h of C strings. 
2b10: 2a 20 74 6f 67 65 74 68 65 72 2e 0a 20 2a 2f 0a  * together.. */.
2b20: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
2b30: 5f 54 63 6c 5f 45 76 61 6c 28 54 63 6c 5f 49 6e  _Tcl_Eval(Tcl_In
2b40: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e  terp *interp, in
2b50: 74 20 6f 62 6a 63 2c 20 63 6f 6e 73 74 20 63 68  t objc, const ch
2b60: 61 72 20 2a 63 6d 64 2c 20 2e 2e 2e 29 20 7b 0a  ar *cmd, ...) {.
2b70: 09 54 63 6c 5f 4f 62 6a 20 2a 2a 6f 62 6a 76 3b  .Tcl_Obj **objv;
2b80: 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 72  ..const char *ar
2b90: 67 3b 0a 09 76 61 5f 6c 69 73 74 20 61 72 67 70  g;..va_list argp
2ba0: 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 09  ;..int retval;..
2bb0: 69 6e 74 20 69 3b 0a 0a 09 69 66 20 28 69 6e 74  int i;...if (int
2bc0: 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  erp == NULL) {..
2bd0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 49 6e  .APPFS_DEBUG("In
2be0: 76 61 6c 69 64 20 69 6e 74 65 72 70 72 65 74 65  valid interprete
2bf0: 72 20 70 61 73 73 65 64 20 69 6e 2c 20 72 65 74  r passed in, ret
2c00: 75 72 6e 69 6e 67 20 69 6e 20 66 61 69 6c 75 72  urning in failur
2c10: 65 2e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  e.");....return(
2c20: 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a  TCL_ERROR);..}..
2c30: 09 6f 62 6a 76 20 3d 20 28 76 6f 69 64 20 2a 29  .objv = (void *)
2c40: 20 63 6b 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28   ckalloc(sizeof(
2c50: 2a 6f 62 6a 76 29 20 2a 20 6f 62 6a 63 29 3b 0a  *objv) * objc);.
2c60: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
2c70: 74 63 6c 28 0a 09 09 6f 62 6a 76 5b 30 5d 20 3d  tcl(...objv[0] =
2c80: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
2c90: 6a 28 63 6d 64 2c 20 2d 31 29 3b 0a 0a 09 09 54  j(cmd, -1);....T
2ca0: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
2cb0: 6f 62 6a 76 5b 30 5d 29 3b 0a 0a 09 09 76 61 5f  objv[0]);....va_
2cc0: 73 74 61 72 74 28 61 72 67 70 2c 20 63 6d 64 29  start(argp, cmd)
2cd0: 3b 0a 09 09 66 6f 72 20 28 69 20 3d 20 31 3b 20  ;...for (i = 1; 
2ce0: 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29 20 7b  i < objc; i++) {
2cf0: 0a 09 09 09 61 72 67 20 3d 20 76 61 5f 61 72 67  ....arg = va_arg
2d00: 28 61 72 67 70 2c 20 63 6f 6e 73 74 20 63 68 61  (argp, const cha
2d10: 72 20 2a 29 3b 0a 0a 09 09 09 6f 62 6a 76 5b 69  r *);.....objv[i
2d20: 5d 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  ] = Tcl_NewStrin
2d30: 67 4f 62 6a 28 61 72 67 2c 20 2d 31 29 3b 0a 0a  gObj(arg, -1);..
2d40: 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f  ...Tcl_IncrRefCo
2d50: 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09 09  unt(objv[i]);...
2d60: 7d 0a 09 09 76 61 5f 65 6e 64 28 61 72 67 70 29  }...va_end(argp)
2d70: 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..)...appfs_cal
2d80: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 74 76  l_libtcl(...retv
2d90: 61 6c 20 3d 20 54 63 6c 5f 45 76 61 6c 4f 62 6a  al = Tcl_EvalObj
2da0: 76 28 69 6e 74 65 72 70 2c 20 6f 62 6a 63 2c 20  v(interp, objc, 
2db0: 6f 62 6a 76 2c 20 30 29 3b 0a 09 29 0a 0a 09 61  objv, 0);..)...a
2dc0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
2dd0: 28 0a 09 09 66 6f 72 20 28 69 20 3d 20 30 3b 20  (...for (i = 0; 
2de0: 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29 20 7b  i < objc; i++) {
2df0: 0a 09 09 09 54 63 6c 5f 44 65 63 72 52 65 66 43  ....Tcl_DecrRefC
2e00: 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09  ount(objv[i]);..
2e10: 09 7d 0a 09 29 0a 0a 09 63 6b 66 72 65 65 28 28  .}..)...ckfree((
2e20: 76 6f 69 64 20 2a 29 20 6f 62 6a 76 29 3b 0a 0a  void *) objv);..
2e30: 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20 54  .if (retval != T
2e40: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 61 70 70 66 73  CL_OK) {...appfs
2e50: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
2e60: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63  .APPFS_DEBUG("Tc
2e70: 6c 20 63 6f 6d 6d 61 6e 64 20 66 61 69 6c 65 64  l command failed
2e80: 2c 20 3a 3a 65 72 72 6f 72 49 6e 66 6f 20 63 6f  , ::errorInfo co
2e90: 6e 74 61 69 6e 73 3a 20 25 73 5c 6e 22 2c 20 54  ntains: %s\n", T
2ea0: 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72 70  cl_GetVar(interp
2eb0: 2c 20 22 3a 3a 65 72 72 6f 72 49 6e 66 6f 22 2c  , "::errorInfo",
2ec0: 20 30 29 29 3b 0a 09 09 29 0a 09 7d 0a 0a 09 72   0));...)..}...r
2ed0: 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d  eturn(retval);.}
2ee0: 0a 0a 2f 2a 0a 20 2a 20 52 65 71 75 65 73 74 20  ../*. * Request 
2ef0: 61 6c 6c 20 54 63 6c 20 69 6e 74 65 72 70 72 65  all Tcl interpre
2f00: 74 65 72 73 20 72 65 73 74 61 72 74 0a 20 2a 2f  ters restart. */
2f10: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
2f20: 66 73 5f 74 63 6c 5f 52 65 73 65 74 49 6e 74 65  fs_tcl_ResetInte
2f30: 72 70 73 28 76 6f 69 64 29 20 7b 0a 09 41 50 50  rps(void) {..APP
2f40: 46 53 5f 44 45 42 55 47 28 22 52 65 71 75 65 73  FS_DEBUG("Reques
2f50: 74 69 6e 67 20 72 65 73 65 74 20 6f 66 20 61 6c  ting reset of al
2f60: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 73 2e 22  l interpreters."
2f70: 29 3b 0a 0a 09 5f 5f 73 79 6e 63 5f 61 64 64 5f  );...__sync_add_
2f80: 61 6e 64 5f 66 65 74 63 68 28 26 69 6e 74 65 72  and_fetch(&inter
2f90: 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 31 29 3b  p_reset_key, 1);
2fa0: 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a  ...return;.}../*
2fb0: 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65 20 74 68  . * Determine th
2fc0: 65 20 55 49 44 20 66 6f 72 20 74 68 65 20 75 73  e UID for the us
2fd0: 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 63 75  er making the cu
2fe0: 72 72 65 6e 74 20 46 55 53 45 20 66 69 6c 65 73  rrent FUSE files
2ff0: 79 73 74 65 6d 20 72 65 71 75 65 73 74 2e 0a 20  ystem request.. 
3000: 2a 20 54 68 69 73 20 77 69 6c 6c 20 62 65 20 75  * This will be u
3010: 73 65 64 20 74 6f 20 6c 6f 6f 6b 75 70 20 74 68  sed to lookup th
3020: 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64 69  e user's home di
3030: 72 65 63 74 6f 72 79 20 73 6f 20 77 65 20 63 61  rectory so we ca
3040: 6e 20 73 65 61 72 63 68 20 66 6f 72 0a 20 2a 20  n search for. * 
3050: 6c 6f 63 61 6c 6c 79 20 6d 6f 64 69 66 69 65 64  locally modified
3060: 20 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73 74 61 74   files.. */.stat
3070: 69 63 20 75 69 64 5f 74 20 61 70 70 66 73 5f 67  ic uid_t appfs_g
3080: 65 74 5f 66 73 75 69 64 28 76 6f 69 64 29 20 7b  et_fsuid(void) {
3090: 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f 63 6f  ..struct fuse_co
30a0: 6e 74 65 78 74 20 2a 63 74 78 3b 0a 0a 09 69 66  ntext *ctx;...if
30b0: 20 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73 74   (!appfs_fuse_st
30c0: 61 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75 72  arted) {...retur
30d0: 6e 28 67 65 74 75 69 64 28 29 29 3b 0a 09 7d 0a  n(getuid());..}.
30e0: 0a 09 63 74 78 20 3d 20 66 75 73 65 5f 67 65 74  ..ctx = fuse_get
30f0: 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09 69 66 20  _context();..if 
3100: 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  (ctx == NULL) {.
3110: 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74 6f 20 6c  ../* Unable to l
3120: 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20 73  ookup user for s
3130: 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f 0a 09 09  ome reason */...
3140: 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20 75 6e 70  /* Return an unp
3150: 72 69 76 69 6c 65 67 65 64 20 75 73 65 72 20 49  rivileged user I
3160: 44 20 2a 2f 0a 09 09 41 50 50 46 53 5f 44 45 42  D */...APPFS_DEB
3170: 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f  UG("Unable to lo
3180: 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20 73 6f  okup user for so
3190: 6d 65 20 72 65 61 73 6f 6e 2c 20 72 65 74 75 72  me reason, retur
31a0: 6e 69 6e 6e 67 20 75 73 65 72 20 49 44 20 6f 66  ninng user ID of
31b0: 20 31 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28   1");....return(
31c0: 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  1);..}...return(
31d0: 63 74 78 2d 3e 75 69 64 29 3b 0a 7d 0a 0a 2f 2a  ctx->uid);.}../*
31e0: 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65 20 74 68  . * Determine th
31f0: 65 20 47 49 44 20 66 6f 72 20 74 68 65 20 75 73  e GID for the us
3200: 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 63 75  er making the cu
3210: 72 72 65 6e 74 20 46 55 53 45 20 66 69 6c 65 73  rrent FUSE files
3220: 79 73 74 65 6d 20 72 65 71 75 65 73 74 2e 0a 20  ystem request.. 
3230: 2a 2f 0a 73 74 61 74 69 63 20 67 69 64 5f 74 20  */.static gid_t 
3240: 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28  appfs_get_fsgid(
3250: 76 6f 69 64 29 20 7b 0a 09 73 74 72 75 63 74 20  void) {..struct 
3260: 66 75 73 65 5f 63 6f 6e 74 65 78 74 20 2a 63 74  fuse_context *ct
3270: 78 3b 0a 0a 09 69 66 20 28 21 61 70 70 66 73 5f  x;...if (!appfs_
3280: 66 75 73 65 5f 73 74 61 72 74 65 64 29 20 7b 0a  fuse_started) {.
3290: 09 09 72 65 74 75 72 6e 28 67 65 74 67 69 64 28  ..return(getgid(
32a0: 29 29 3b 0a 09 7d 0a 0a 09 63 74 78 20 3d 20 66  ));..}...ctx = f
32b0: 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65 78 74 28  use_get_context(
32c0: 29 3b 0a 09 69 66 20 28 63 74 78 20 3d 3d 20 4e  );..if (ctx == N
32d0: 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20 55 6e 61 62  ULL) {.../* Unab
32e0: 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 75 73 65  le to lookup use
32f0: 72 20 66 6f 72 20 73 6f 6d 65 20 72 65 61 73 6f  r for some reaso
3300: 6e 20 2a 2f 0a 09 09 2f 2a 20 52 65 74 75 72 6e  n */.../* Return
3310: 20 61 6e 20 75 6e 70 72 69 76 69 6c 65 67 65 64   an unprivileged
3320: 20 75 73 65 72 20 49 44 20 2a 2f 0a 09 09 41 50   user ID */...AP
3330: 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c  PFS_DEBUG("Unabl
3340: 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 67 72 6f 75  e to lookup grou
3350: 70 20 66 6f 72 20 73 6f 6d 65 20 72 65 61 73 6f  p for some reaso
3360: 6e 2c 20 72 65 74 75 72 6e 69 6e 6e 67 20 67 72  n, returninng gr
3370: 6f 75 70 20 49 44 20 6f 66 20 31 22 29 3b 0a 0a  oup ID of 1");..
3380: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
3390: 0a 09 72 65 74 75 72 6e 28 63 74 78 2d 3e 67 69  ..return(ctx->gi
33a0: 64 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  d);.}..static vo
33b0: 69 64 20 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  id appfs_simulat
33c0: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
33d0: 76 6f 69 64 29 20 7b 0a 09 73 65 74 66 73 75 69  void) {..setfsui
33e0: 64 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  d(appfs_get_fsui
33f0: 64 28 29 29 3b 0a 09 73 65 74 66 73 67 69 64 28  d());..setfsgid(
3400: 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28  appfs_get_fsgid(
3410: 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  ));.}..static vo
3420: 69 64 20 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  id appfs_simulat
3430: 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28  e_user_fs_leave(
3440: 76 6f 69 64 29 20 7b 0a 09 73 65 74 66 73 75 69  void) {..setfsui
3450: 64 28 30 29 3b 0a 09 73 65 74 66 73 67 69 64 28  d(0);..setfsgid(
3460: 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 4c 6f 6f  0);.}../*. * Loo
3470: 6b 20 75 70 20 74 68 65 20 68 6f 6d 65 20 64 69  k up the home di
3480: 72 65 63 74 6f 72 79 20 66 6f 72 20 61 20 67 69  rectory for a gi
3490: 76 65 6e 20 55 49 44 0a 20 2a 20 20 20 20 20 20  ven UID. *      
34a0: 20 20 52 65 74 75 72 6e 73 20 61 20 43 20 73 74    Returns a C st
34b0: 72 69 6e 67 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ring containing 
34c0: 74 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20  the user's home 
34d0: 64 69 72 65 63 74 6f 72 79 20 6f 72 20 4e 55 4c  directory or NUL
34e0: 4c 20 69 66 0a 20 2a 20 20 20 20 20 20 20 20 74  L if. *        t
34f0: 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64  he user's home d
3500: 69 72 65 63 74 6f 72 79 20 64 6f 65 73 20 6e 6f  irectory does no
3510: 74 20 65 78 69 73 74 20 6f 72 20 69 73 20 6e 6f  t exist or is no
3520: 74 20 63 6f 72 72 65 63 74 6c 79 0a 20 2a 20 20  t correctly. *  
3530: 20 20 20 20 20 20 63 6f 6e 66 69 67 75 72 65 64        configured
3540: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72  . */.static char
3550: 20 2a 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65   *appfs_get_home
3560: 64 69 72 28 75 69 64 5f 74 20 66 73 75 69 64 29  dir(uid_t fsuid)
3570: 20 7b 0a 09 73 74 72 75 63 74 20 70 61 73 73 77   {..struct passw
3580: 64 20 65 6e 74 72 79 2c 20 2a 72 65 73 75 6c 74  d entry, *result
3590: 3b 0a 09 73 74 72 75 63 74 20 73 74 61 74 20 73  ;..struct stat s
35a0: 74 62 75 66 3b 0a 09 63 68 61 72 20 62 75 66 5b  tbuf;..char buf[
35b0: 31 30 32 34 5d 2c 20 2a 72 65 74 76 61 6c 3b 0a  1024], *retval;.
35c0: 09 69 6e 74 20 67 70 75 5f 72 65 74 2c 20 73 74  .int gpu_ret, st
35d0: 61 74 5f 72 65 74 3b 0a 0a 09 67 70 75 5f 72 65  at_ret;...gpu_re
35e0: 74 20 3d 20 67 65 74 70 77 75 69 64 5f 72 28 66  t = getpwuid_r(f
35f0: 73 75 69 64 2c 20 26 65 6e 74 72 79 2c 20 62 75  suid, &entry, bu
3600: 66 2c 20 73 69 7a 65 6f 66 28 62 75 66 29 2c 20  f, sizeof(buf), 
3610: 26 72 65 73 75 6c 74 29 3b 0a 09 69 66 20 28 67  &result);..if (g
3620: 70 75 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  pu_ret != 0) {..
3630: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67 65  .APPFS_DEBUG("ge
3640: 74 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e  tpwuid_r(%llu, .
3650: 2e 2e 29 20 72 65 74 75 72 6e 65 64 20 69 6e 20  ..) returned in 
3660: 66 61 69 6c 75 72 65 22 2c 20 28 75 6e 73 69 67  failure", (unsig
3670: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66  ned long long) f
3680: 73 75 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e  suid);....return
3690: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20  (NULL);..}...if 
36a0: 28 72 65 73 75 6c 74 20 3d 3d 20 4e 55 4c 4c 29  (result == NULL)
36b0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
36c0: 28 22 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c  ("getpwuid_r(%ll
36d0: 75 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64  u, ...) returned
36e0: 20 4e 55 4c 4c 20 72 65 73 75 6c 74 22 2c 20 28   NULL result", (
36f0: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
3700: 6e 67 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72  ng) fsuid);....r
3710: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
3720: 0a 09 69 66 20 28 72 65 73 75 6c 74 2d 3e 70 77  ..if (result->pw
3730: 5f 64 69 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  _dir == NULL) {.
3740: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67  ..APPFS_DEBUG("g
3750: 65 74 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20  etpwuid_r(%llu, 
3760: 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64 20 4e 55  ...) returned NU
3770: 4c 4c 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  LL home director
3780: 79 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f  y", (unsigned lo
3790: 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b  ng long) fsuid);
37a0: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
37b0: 3b 0a 09 7d 0a 0a 09 73 74 61 74 5f 72 65 74 20  ;..}...stat_ret 
37c0: 3d 20 73 74 61 74 28 72 65 73 75 6c 74 2d 3e 70  = stat(result->p
37d0: 77 5f 64 69 72 2c 20 26 73 74 62 75 66 29 3b 0a  w_dir, &stbuf);.
37e0: 09 69 66 20 28 73 74 61 74 5f 72 65 74 20 21 3d  .if (stat_ret !=
37f0: 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45   0) {...APPFS_DE
3800: 42 55 47 28 22 73 74 61 74 28 25 73 29 20 72 65  BUG("stat(%s) re
3810: 74 75 72 6e 65 64 20 69 6e 20 66 61 69 6c 75 72  turned in failur
3820: 65 22 2c 20 72 65 73 75 6c 74 2d 3e 70 77 5f 64  e", result->pw_d
3830: 69 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e  ir);....return(N
3840: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 73  ULL);..}...if (s
3850: 74 62 75 66 2e 73 74 5f 75 69 64 20 21 3d 20 66  tbuf.st_uid != f
3860: 73 75 69 64 29 20 7b 0a 09 09 41 50 50 46 53 5f  suid) {...APPFS_
3870: 44 45 42 55 47 28 22 55 49 44 20 6d 69 73 2d 6d  DEBUG("UID mis-m
3880: 61 74 63 68 20 6f 6e 20 75 73 65 72 20 25 6c 6c  atch on user %ll
3890: 75 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  u's home directo
38a0: 72 79 20 28 25 73 29 2e 20 20 49 74 27 73 20 6f  ry (%s).  It's o
38b0: 77 6e 65 64 20 62 79 20 25 6c 6c 75 2e 22 2c 0a  wned by %llu.",.
38c0: 09 09 20 20 20 20 28 75 6e 73 69 67 6e 65 64 20  ..    (unsigned 
38d0: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64  long long) fsuid
38e0: 2c 0a 09 09 20 20 20 20 72 65 73 75 6c 74 2d 3e  ,...    result->
38f0: 70 77 5f 64 69 72 2c 0a 09 09 20 20 20 20 28 75  pw_dir,...    (u
3900: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e  nsigned long lon
3910: 67 29 20 73 74 62 75 66 2e 73 74 5f 75 69 64 0a  g) stbuf.st_uid.
3920: 09 09 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e  ..);....return(N
3930: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 76 61  ULL);..}...retva
3940: 6c 20 3d 20 73 74 72 64 75 70 28 72 65 73 75 6c  l = strdup(resul
3950: 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09 72 65  t->pw_dir);...re
3960: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a  turn(retval);.}.
3970: 0a 2f 2a 0a 20 2a 20 47 65 6e 65 72 61 74 65 20  ./*. * Generate 
3980: 61 6e 20 69 6e 6f 64 65 20 66 6f 72 20 61 20 67  an inode for a g
3990: 69 76 65 6e 20 70 61 74 68 2e 20 20 54 68 65 20  iven path.  The 
39a0: 69 6e 6f 64 65 20 73 68 6f 75 6c 64 20 62 65 20  inode should be 
39b0: 63 6f 6d 70 75 74 65 64 20 69 6e 20 73 75 63 68  computed in such
39c0: 0a 20 2a 20 61 20 77 61 79 20 74 68 61 74 20 69  . * a way that i
39d0: 74 20 69 73 20 75 6e 6c 69 6b 65 6c 79 20 74 6f  t is unlikely to
39e0: 20 62 65 20 64 75 70 6c 69 63 61 74 65 64 20 61   be duplicated a
39f0: 6e 64 20 72 65 6d 61 69 6e 73 20 74 68 65 20 73  nd remains the s
3a00: 61 6d 65 20 66 6f 72 20 61 20 67 69 76 65 6e 0a  ame for a given.
3a10: 20 2a 20 66 69 6c 65 0a 20 2a 0a 20 2a 20 43 75   * file. *. * Cu
3a20: 72 72 65 6e 74 20 69 6d 70 6c 65 6d 65 6e 74 61  rrent implementa
3a30: 74 69 6f 6e 20 69 73 20 61 6e 20 46 4e 56 2d 31  tion is an FNV-1
3a40: 61 20 33 32 2d 62 69 74 0a 20 2a 2f 0a 23 69 66  a 32-bit. */.#if
3a50: 20 55 49 4e 54 5f 4d 41 58 20 3c 20 34 32 39 34   UINT_MAX < 4294
3a60: 39 36 37 32 39 35 0a 23 65 72 72 6f 72 20 49 6e  967295.#error In
3a70: 74 65 67 65 72 20 73 69 7a 65 20 69 73 20 74 6f  teger size is to
3a80: 6f 20 73 6d 61 6c 6c 20 0a 23 65 6e 64 69 66 0a  o small .#endif.
3a90: 73 74 61 74 69 63 20 75 6e 73 69 67 6e 65 64 20  static unsigned 
3aa0: 6c 6f 6e 67 20 6c 6f 6e 67 20 61 70 70 66 73 5f  long long appfs_
3ab0: 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 63  get_path_inode(c
3ac0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
3ad0: 20 69 6e 74 20 75 69 64 29 20 7b 0a 09 75 6e 73   int uid) {..uns
3ae0: 69 67 6e 65 64 20 69 6e 74 20 72 65 74 76 61 6c  igned int retval
3af0: 3b 0a 09 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65  ;..const unsigne
3b00: 64 20 63 68 61 72 20 2a 70 3b 0a 0a 09 72 65 74  d char *p;...ret
3b10: 76 61 6c 20 3d 20 32 31 36 36 31 33 36 32 36 31  val = 2166136261
3b20: 3b 20 2f 2a 20 46 4e 56 2d 31 61 20 33 32 2d 62  ; /* FNV-1a 32-b
3b30: 69 74 20 6f 66 66 73 65 74 5f 62 61 73 69 73 20  it offset_basis 
3b40: 2a 2f 0a 0a 09 66 6f 72 20 28 70 20 3d 20 28 75  */...for (p = (u
3b50: 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 29 20  nsigned char *) 
3b60: 70 61 74 68 3b 20 2a 70 3b 20 70 2b 2b 29 20 7b  path; *p; p++) {
3b70: 0a 09 09 72 65 74 76 61 6c 20 5e 3d 20 28 69 6e  ...retval ^= (in
3b80: 74 29 20 2a 70 3b 0a 23 69 66 20 30 0a 09 09 72  t) *p;.#if 0...r
3b90: 65 74 76 61 6c 20 2a 3d 20 31 36 37 37 37 36 31  etval *= 1677761
3ba0: 39 3b 20 2f 2a 20 46 4e 56 2d 31 61 20 33 32 2d  9; /* FNV-1a 32-
3bb0: 62 69 74 20 70 72 69 6d 65 20 2a 2f 0a 23 65 6c  bit prime */.#el
3bc0: 73 65 0a 09 09 2f 2a 20 47 43 43 20 4f 70 74 69  se.../* GCC Opti
3bd0: 6d 69 7a 65 64 20 72 65 70 6c 61 63 65 6d 65 6e  mized replacemen
3be0: 74 20 2a 2f 0a 09 09 72 65 74 76 61 6c 20 2b 3d  t */...retval +=
3bf0: 20 28 72 65 74 76 61 6c 20 3c 3c 20 31 29 20 2b   (retval << 1) +
3c00: 20 28 72 65 74 76 61 6c 20 3c 3c 20 34 29 20 2b   (retval << 4) +
3c10: 20 28 72 65 74 76 61 6c 20 3c 3c 20 37 29 20 2b   (retval << 7) +
3c20: 20 28 72 65 74 76 61 6c 20 3c 3c 20 38 29 20 2b   (retval << 8) +
3c30: 20 28 72 65 74 76 61 6c 20 3c 3c 20 32 34 29 3b   (retval << 24);
3c40: 0a 23 65 6e 64 69 66 0a 09 7d 0a 0a 09 69 66 20  .#endif..}...if 
3c50: 28 75 69 64 20 3e 3d 20 30 29 20 7b 0a 09 09 72  (uid >= 0) {...r
3c60: 65 74 76 61 6c 20 2b 3d 20 75 69 64 3b 0a 09 09  etval += uid;...
3c70: 72 65 74 76 61 6c 2b 2b 3b 0a 09 7d 0a 0a 09 41  retval++;..}...A
3c80: 50 50 46 53 5f 44 45 42 55 47 28 22 4c 6f 6f 6b  PPFS_DEBUG("Look
3c90: 65 64 20 75 70 20 69 6e 6f 64 65 20 6e 75 6d 62  ed up inode numb
3ca0: 65 72 20 66 6f 72 20 70 61 74 68 3d 25 73 2c 75  er for path=%s,u
3cb0: 69 64 3d 25 69 3a 20 25 75 22 2c 20 70 61 74 68  id=%i: %u", path
3cc0: 2c 20 75 69 64 2c 20 72 65 74 76 61 6c 29 3b 0a  , uid, retval);.
3cd0: 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
3ce0: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 61 63 68 65  ;.}../*. * Cache
3cf0: 20 47 65 74 20 50 61 74 68 20 49 6e 66 6f 20 6c   Get Path Info l
3d00: 6f 6f 6b 75 70 73 20 66 6f 72 20 73 70 65 65 64  ookups for speed
3d10: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  . */.static int 
3d20: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
3d30: 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28 63 6f  nfo_cache_get(co
3d40: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
3d50: 75 69 64 5f 74 20 75 69 64 2c 20 73 74 72 75 63  uid_t uid, struc
3d60: 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f  t appfs_pathinfo
3d70: 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 75   *pathinfo) {..u
3d80: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68  nsigned int hash
3d90: 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65  _idx;..int pthre
3da0: 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65 74  ad_ret;..int ret
3db0: 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  val;...retval = 
3dc0: 31 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74  1;...pthread_ret
3dd0: 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78   = pthread_mutex
3de0: 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74  _lock(&appfs_pat
3df0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74  h_info_cache_mut
3e00: 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61  ex);..if (pthrea
3e10: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
3e20: 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61  APPFS_DEBUG("Una
3e30: 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68  ble to lock path
3e40: 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65  _info cache mute
3e50: 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  x !");....return
3e60: 28 2d 31 29 3b 0a 09 7d 0a 0a 09 41 50 50 46 53  (-1);..}...APPFS
3e70: 5f 44 45 42 55 47 28 22 4c 6f 6f 6b 69 6e 67 20  _DEBUG("Looking 
3e80: 75 70 20 63 61 63 68 65 20 65 6e 74 72 79 20 66  up cache entry f
3e90: 6f 72 20 70 61 74 68 3d 25 73 2c 75 69 64 3d 25  or path=%s,uid=%
3ea0: 6c 6c 69 2e 2e 2e 22 2c 20 70 61 74 68 2c 20 28  lli...", path, (
3eb0: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69 64 29 3b  long long) uid);
3ec0: 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70 61 74  ...if (appfs_pat
3ed0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 21 3d 20  h_info_cache != 
3ee0: 4e 55 4c 4c 29 20 7b 0a 09 09 68 61 73 68 5f 69  NULL) {...hash_i
3ef0: 64 78 20 3d 20 28 61 70 70 66 73 5f 67 65 74 5f  dx = (appfs_get_
3f00: 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74 68 2c  path_inode(path,
3f10: 20 75 69 64 29 29 20 25 20 61 70 70 66 73 5f 70   uid)) % appfs_p
3f20: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73  ath_info_cache_s
3f30: 69 7a 65 3b 0a 0a 09 09 69 66 20 28 61 70 70 66  ize;....if (appf
3f40: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
3f50: 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63  e[hash_idx]._cac
3f60: 68 65 5f 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29  he_path != NULL)
3f70: 20 7b 0a 09 09 09 69 66 20 28 73 74 72 63 6d 70   {....if (strcmp
3f80: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  (appfs_path_info
3f90: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d  _cache[hash_idx]
3fa0: 2e 5f 63 61 63 68 65 5f 70 61 74 68 2c 20 70 61  ._cache_path, pa
3fb0: 74 68 29 20 3d 3d 20 30 20 26 26 20 61 70 70 66  th) == 0 && appf
3fc0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
3fd0: 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63  e[hash_idx]._cac
3fe0: 68 65 5f 75 69 64 20 3d 3d 20 75 69 64 29 20 7b  he_uid == uid) {
3ff0: 0a 09 09 09 09 72 65 74 76 61 6c 20 3d 20 30 3b  .....retval = 0;
4000: 0a 0a 09 09 09 09 6d 65 6d 63 70 79 28 70 61 74  ......memcpy(pat
4010: 68 69 6e 66 6f 2c 20 26 61 70 70 66 73 5f 70 61  hinfo, &appfs_pa
4020: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61  th_info_cache[ha
4030: 73 68 5f 69 64 78 5d 2c 20 73 69 7a 65 6f 66 28  sh_idx], sizeof(
4040: 2a 70 61 74 68 69 6e 66 6f 29 29 3b 0a 09 09 09  *pathinfo));....
4050: 09 70 61 74 68 69 6e 66 6f 2d 3e 5f 63 61 63 68  .pathinfo->_cach
4060: 65 5f 70 61 74 68 20 3d 20 4e 55 4c 4c 3b 0a 09  e_path = NULL;..
4070: 09 09 7d 0a 09 09 7d 0a 09 7d 0a 0a 09 70 74 68  ..}...}..}...pth
4080: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
4090: 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28  ad_mutex_unlock(
40a0: 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  &appfs_path_info
40b0: 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09  _cache_mutex);..
40c0: 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20  if (pthread_ret 
40d0: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
40e0: 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f  DEBUG("Unable to
40f0: 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66   unlock path_inf
4100: 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22  o cache mutex !"
4110: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 31 29  );....return(-1)
4120: 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65 74 76 61  ;..}...if (retva
4130: 6c 20 3d 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  l == 0) {...APPF
4140: 53 5f 44 45 42 55 47 28 22 43 61 63 68 65 20 68  S_DEBUG("Cache h
4150: 69 74 20 6f 6e 20 70 61 74 68 3d 25 73 2c 75 69  it on path=%s,ui
4160: 64 3d 25 6c 6c 69 22 2c 20 70 61 74 68 2c 20 28  d=%lli", path, (
4170: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69 64 29 3b  long long) uid);
4180: 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 41 50 50  ..} else {...APP
4190: 46 53 5f 44 45 42 55 47 28 22 43 61 63 68 65 20  FS_DEBUG("Cache 
41a0: 6d 69 73 73 20 6f 6e 20 70 61 74 68 3d 25 73 2c  miss on path=%s,
41b0: 75 69 64 3d 25 6c 6c 69 22 2c 20 70 61 74 68 2c  uid=%lli", path,
41c0: 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69 64   (long long) uid
41d0: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72  );..}...return(r
41e0: 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69  etval);.}..stati
41f0: 63 20 76 6f 69 64 20 61 70 70 66 73 5f 67 65 74  c void appfs_get
4200: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4210: 5f 61 64 64 28 63 6f 6e 73 74 20 63 68 61 72 20  _add(const char 
4220: 2a 70 61 74 68 2c 20 75 69 64 5f 74 20 75 69 64  *path, uid_t uid
4230: 2c 20 73 74 72 75 63 74 20 61 70 70 66 73 5f 70  , struct appfs_p
4240: 61 74 68 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66  athinfo *pathinf
4250: 6f 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69  o) {..unsigned i
4260: 6e 74 20 68 61 73 68 5f 69 64 78 3b 0a 09 69 6e  nt hash_idx;..in
4270: 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a  t pthread_ret;..
4280: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
4290: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63  thread_mutex_loc
42a0: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  k(&appfs_path_in
42b0: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b  fo_cache_mutex);
42c0: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
42d0: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  t != 0) {...APPF
42e0: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20  S_DEBUG("Unable 
42f0: 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66  to lock path_inf
4300: 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22  o cache mutex !"
4310: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d  );....return;..}
4320: 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70 61 74  ...if (appfs_pat
4330: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d 3d 20  h_info_cache == 
4340: 4e 55 4c 4c 29 20 7b 0a 09 09 61 70 70 66 73 5f  NULL) {...appfs_
4350: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20  path_info_cache 
4360: 3d 20 63 61 6c 6c 6f 63 28 61 70 70 66 73 5f 70  = calloc(appfs_p
4370: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73  ath_info_cache_s
4380: 69 7a 65 2c 20 73 69 7a 65 6f 66 28 2a 61 70 70  ize, sizeof(*app
4390: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
43a0: 68 65 29 29 3b 0a 09 7d 0a 0a 09 68 61 73 68 5f  he));..}...hash_
43b0: 69 64 78 20 3d 20 28 61 70 70 66 73 5f 67 65 74  idx = (appfs_get
43c0: 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74 68  _path_inode(path
43d0: 2c 20 75 69 64 29 29 20 25 20 61 70 70 66 73 5f  , uid)) % appfs_
43e0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
43f0: 73 69 7a 65 3b 0a 0a 09 69 66 20 28 61 70 70 66  size;...if (appf
4400: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4410: 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63  e[hash_idx]._cac
4420: 68 65 5f 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29  he_path != NULL)
4430: 20 7b 0a 09 09 66 72 65 65 28 61 70 70 66 73 5f   {...free(appfs_
4440: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
4450: 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65  hash_idx]._cache
4460: 5f 70 61 74 68 29 3b 0a 09 7d 0a 0a 09 6d 65 6d  _path);..}...mem
4470: 63 70 79 28 26 61 70 70 66 73 5f 70 61 74 68 5f  cpy(&appfs_path_
4480: 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f  info_cache[hash_
4490: 69 64 78 5d 2c 20 70 61 74 68 69 6e 66 6f 2c 20  idx], pathinfo, 
44a0: 73 69 7a 65 6f 66 28 2a 70 61 74 68 69 6e 66 6f  sizeof(*pathinfo
44b0: 29 29 3b 0a 0a 09 61 70 70 66 73 5f 70 61 74 68  ));...appfs_path
44c0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
44d0: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  _idx]._cache_pat
44e0: 68 20 3d 20 73 74 72 64 75 70 28 70 61 74 68 29  h = strdup(path)
44f0: 3b 0a 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  ;..appfs_path_in
4500: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
4510: 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64 20 20 3d  x]._cache_uid  =
4520: 20 75 69 64 3b 0a 0a 09 70 74 68 72 65 61 64 5f   uid;...pthread_
4530: 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75  ret = pthread_mu
4540: 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66  tex_unlock(&appf
4550: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4560: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70  e_mutex);..if (p
4570: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
4580: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
4590: 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f  ("Unable to unlo
45a0: 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63  ck path_info cac
45b0: 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09  he mutex !");...
45c0: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65  .return;..}...re
45d0: 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  turn;.}..static 
45e0: 76 6f 69 64 20 61 70 70 66 73 5f 67 65 74 5f 70  void appfs_get_p
45f0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72  ath_info_cache_r
4600: 6d 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  m(const char *pa
4610: 74 68 2c 20 75 69 64 5f 74 20 75 69 64 29 20 7b  th, uid_t uid) {
4620: 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68  ..unsigned int h
4630: 61 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74  ash_idx;..int pt
4640: 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 70 74 68  hread_ret;...pth
4650: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
4660: 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61  ad_mutex_lock(&a
4670: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4680: 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66  ache_mutex);..if
4690: 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d   (pthread_ret !=
46a0: 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45   0) {...APPFS_DE
46b0: 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c  BUG("Unable to l
46c0: 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61  ock path_info ca
46d0: 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a  che mutex !");..
46e0: 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69  ..return;..}...i
46f0: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
4700: 66 6f 5f 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c  fo_cache != NULL
4710: 29 20 7b 0a 09 09 68 61 73 68 5f 69 64 78 20 3d  ) {...hash_idx =
4720: 20 28 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68   (appfs_get_path
4730: 5f 69 6e 6f 64 65 28 70 61 74 68 2c 20 75 69 64  _inode(path, uid
4740: 29 29 20 25 20 61 70 70 66 73 5f 70 61 74 68 5f  )) % appfs_path_
4750: 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b  info_cache_size;
4760: 0a 0a 09 09 69 66 20 28 61 70 70 66 73 5f 70 61  ....if (appfs_pa
4770: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61  th_info_cache[ha
4780: 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70  sh_idx]._cache_p
4790: 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ath != NULL) {..
47a0: 09 09 66 72 65 65 28 61 70 70 66 73 5f 70 61 74  ..free(appfs_pat
47b0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73  h_info_cache[has
47c0: 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61  h_idx]._cache_pa
47d0: 74 68 29 3b 0a 0a 09 09 09 61 70 70 66 73 5f 70  th);.....appfs_p
47e0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68  ath_info_cache[h
47f0: 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f  ash_idx]._cache_
4800: 70 61 74 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 7d  path = NULL;...}
4810: 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72 65  ..}...pthread_re
4820: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65  t = pthread_mute
4830: 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f  x_unlock(&appfs_
4840: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
4850: 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68  mutex);..if (pth
4860: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  read_ret != 0) {
4870: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
4880: 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b  Unable to unlock
4890: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65   path_info cache
48a0: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72   mutex !");....r
48b0: 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65 74 75  eturn;..}...retu
48c0: 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f  rn;.}..static vo
48d0: 69 64 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74  id appfs_get_pat
48e0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75  h_info_cache_flu
48f0: 73 68 28 75 69 64 5f 74 20 75 69 64 2c 20 69 6e  sh(uid_t uid, in
4900: 74 20 6e 65 77 5f 73 69 7a 65 29 20 7b 0a 09 75  t new_size) {..u
4910: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 64 78 3b  nsigned int idx;
4920: 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65  ..int pthread_re
4930: 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  t;...APPFS_DEBUG
4940: 28 22 46 6c 75 73 68 69 6e 67 20 41 70 70 46 53  ("Flushing AppFS
4950: 20 63 61 63 68 65 20 28 75 69 64 20 3d 20 25 6c   cache (uid = %l
4960: 6c 69 2c 20 6e 65 77 5f 73 69 7a 65 20 3d 20 25  li, new_size = %
4970: 69 29 22 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29  i)", (long long)
4980: 20 75 69 64 2c 20 6e 65 77 5f 73 69 7a 65 29 3b   uid, new_size);
4990: 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d  ...pthread_ret =
49a0: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c   pthread_mutex_l
49b0: 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f  ock(&appfs_path_
49c0: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
49d0: 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f  );..if (pthread_
49e0: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ret != 0) {...AP
49f0: 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c  PFS_DEBUG("Unabl
4a00: 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69  e to lock path_i
4a10: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20  nfo cache mutex 
4a20: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a  !");....return;.
4a30: 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70  .}...if (appfs_p
4a40: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 21  ath_info_cache !
4a50: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 6f 72 20  = NULL) {...for 
4a60: 28 69 64 78 20 3d 20 30 3b 20 69 64 78 20 3c 20  (idx = 0; idx < 
4a70: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4a80: 63 61 63 68 65 5f 73 69 7a 65 3b 20 69 64 78 2b  cache_size; idx+
4a90: 2b 29 20 7b 0a 09 09 09 69 66 20 28 61 70 70 66  +) {....if (appf
4aa0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4ab0: 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61  e[idx]._cache_pa
4ac0: 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th != NULL) {...
4ad0: 09 09 69 66 20 28 75 69 64 20 21 3d 20 28 28 75  ..if (uid != ((u
4ae0: 69 64 5f 74 29 20 2d 31 29 29 20 7b 0a 09 09 09  id_t) -1)) {....
4af0: 09 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68  ..if (appfs_path
4b00: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d  _info_cache[idx]
4b10: 2e 5f 63 61 63 68 65 5f 75 69 64 20 21 3d 20 75  ._cache_uid != u
4b20: 69 64 29 20 7b 0a 09 09 09 09 09 09 63 6f 6e 74  id) {.......cont
4b30: 69 6e 75 65 3b 0a 09 09 09 09 09 7d 0a 09 09 09  inue;......}....
4b40: 09 7d 0a 0a 09 09 09 09 66 72 65 65 28 61 70 70  .}......free(app
4b50: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4b60: 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70  he[idx]._cache_p
4b70: 61 74 68 29 3b 0a 0a 09 09 09 09 61 70 70 66 73  ath);......appfs
4b80: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4b90: 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  [idx]._cache_pat
4ba0: 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09  h = NULL;....}..
4bb0: 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 75 69 64 20  .}..}...if (uid 
4bc0: 3d 3d 20 28 28 75 69 64 5f 74 29 20 2d 31 29 29  == ((uid_t) -1))
4bd0: 20 7b 0a 09 09 66 72 65 65 28 61 70 70 66 73 5f   {...free(appfs_
4be0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 29  path_info_cache)
4bf0: 3b 0a 0a 09 09 61 70 70 66 73 5f 70 61 74 68 5f  ;....appfs_path_
4c00: 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20 4e 55 4c  info_cache = NUL
4c10: 4c 3b 0a 0a 09 09 69 66 20 28 6e 65 77 5f 73 69  L;....if (new_si
4c20: 7a 65 20 21 3d 20 2d 31 29 20 7b 0a 09 09 09 61  ze != -1) {....a
4c30: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4c40: 61 63 68 65 5f 73 69 7a 65 20 3d 20 6e 65 77 5f  ache_size = new_
4c50: 73 69 7a 65 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 70  size;...}..}...p
4c60: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68  thread_ret = pth
4c70: 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63  read_mutex_unloc
4c80: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  k(&appfs_path_in
4c90: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b  fo_cache_mutex);
4ca0: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
4cb0: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  t != 0) {...APPF
4cc0: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20  S_DEBUG("Unable 
4cd0: 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69  to unlock path_i
4ce0: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20  nfo cache mutex 
4cf0: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a  !");....return;.
4d00: 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a  .}...return;.}..
4d10: 2f 2a 20 47 65 74 20 69 6e 66 6f 72 6d 61 74 69  /* Get informati
4d20: 6f 6e 20 61 62 6f 75 74 20 61 20 70 61 74 68 2c  on about a path,
4d30: 20 61 6e 64 20 6f 70 74 69 6f 6e 61 6c 6c 79 20   and optionally 
4d40: 6c 69 73 74 20 63 68 69 6c 64 72 65 6e 20 2a 2f  list children */
4d50: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
4d60: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28  s_get_path_info(
4d70: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
4d80: 2c 20 73 74 72 75 63 74 20 61 70 70 66 73 5f 70  , struct appfs_p
4d90: 61 74 68 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66  athinfo *pathinf
4da0: 6f 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  o) {..Tcl_Interp
4db0: 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c 5f 4f   *interp;..Tcl_O
4dc0: 62 6a 20 2a 61 74 74 72 73 5f 64 69 63 74 2c 20  bj *attrs_dict, 
4dd0: 2a 61 74 74 72 5f 76 61 6c 75 65 3b 0a 09 63 6f  *attr_value;..co
4de0: 6e 73 74 20 63 68 61 72 20 2a 61 74 74 72 5f 76  nst char *attr_v
4df0: 61 6c 75 65 5f 73 74 72 2c 20 2a 61 74 74 72 5f  alue_str, *attr_
4e00: 76 61 6c 75 65 5f 73 74 72 5f 69 3b 0a 09 54 63  value_str_i;..Tc
4e10: 6c 5f 57 69 64 65 49 6e 74 20 61 74 74 72 5f 76  l_WideInt attr_v
4e20: 61 6c 75 65 5f 77 69 64 65 3b 0a 09 69 6e 74 20  alue_wide;..int 
4e30: 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a  attr_value_int;.
4e40: 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64  .static __thread
4e50: 20 54 63 6c 5f 4f 62 6a 20 2a 61 74 74 72 5f 6b   Tcl_Obj *attr_k
4e60: 65 79 5f 74 79 70 65 20 3d 20 4e 55 4c 4c 2c 20  ey_type = NULL, 
4e70: 2a 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20  *attr_key_perms 
4e80: 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65  = NULL, *attr_ke
4e90: 79 5f 73 69 7a 65 20 3d 20 4e 55 4c 4c 2c 20 2a  y_size = NULL, *
4ea0: 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 20 3d 20  attr_key_time = 
4eb0: 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f  NULL, *attr_key_
4ec0: 73 6f 75 72 63 65 20 3d 20 4e 55 4c 4c 2c 20 2a  source = NULL, *
4ed0: 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f  attr_key_childco
4ee0: 75 6e 74 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74  unt = NULL, *att
4ef0: 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 20 3d  r_key_packaged =
4f00: 20 4e 55 4c 4c 3b 0a 09 69 6e 74 20 63 61 63 68   NULL;..int cach
4f10: 65 5f 72 65 74 3b 0a 09 69 6e 74 20 74 63 6c 5f  e_ret;..int tcl_
4f20: 72 65 74 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c  ret;..int retval
4f30: 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a  ;..uid_t fsuid;.
4f40: 0a 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09  ..retval = 0;...
4f50: 66 73 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65  fsuid = appfs_ge
4f60: 74 5f 66 73 75 69 64 28 29 3b 0a 0a 09 63 61 63  t_fsuid();...cac
4f70: 68 65 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 67  he_ret = appfs_g
4f80: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
4f90: 68 65 5f 67 65 74 28 70 61 74 68 2c 20 66 73 75  he_get(path, fsu
4fa0: 69 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a 09  id, pathinfo);..
4fb0: 69 66 20 28 63 61 63 68 65 5f 72 65 74 20 3d 3d  if (cache_ret ==
4fc0: 20 30 29 20 7b 0a 09 09 69 66 20 28 70 61 74 68   0) {...if (path
4fd0: 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d 20 41 50  info->type == AP
4fe0: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 4f 45  PFS_PATHTYPE_DOE
4ff0: 53 5f 4e 4f 54 5f 45 58 49 53 54 29 20 7b 0a 09  S_NOT_EXIST) {..
5000: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 52  ..APPFS_DEBUG("R
5010: 65 74 75 72 6e 69 6e 67 20 66 72 6f 6d 20 63 61  eturning from ca
5020: 63 68 65 3a 20 64 6f 65 73 20 6e 6f 74 20 65 78  che: does not ex
5030: 69 73 74 20 5c 22 25 73 5c 22 22 2c 20 70 61 74  ist \"%s\"", pat
5040: 68 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 2d  h);.....return(-
5050: 45 4e 4f 45 4e 54 29 3b 0a 09 09 7d 0a 0a 09 09  ENOENT);...}....
5060: 69 66 20 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79  if (pathinfo->ty
5070: 70 65 20 3d 3d 20 41 50 50 46 53 5f 50 41 54 48  pe == APPFS_PATH
5080: 54 59 50 45 5f 49 4e 56 41 4c 49 44 29 20 7b 0a  TYPE_INVALID) {.
5090: 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
50a0: 52 65 74 75 72 6e 69 6e 67 20 66 72 6f 6d 20 63  Returning from c
50b0: 61 63 68 65 3a 20 69 6e 76 61 6c 69 64 20 6f 62  ache: invalid ob
50c0: 6a 65 63 74 20 5c 22 25 73 5c 22 22 2c 20 70 61  ject \"%s\"", pa
50d0: 74 68 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28  th);.....return(
50e0: 2d 45 49 4f 29 3b 0a 09 09 7d 0a 0a 09 09 72 65  -EIO);...}....re
50f0: 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 69 6e  turn(0);..}...in
5100: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c  terp = appfs_Tcl
5110: 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69  Interp();..if (i
5120: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b  nterp == NULL) {
5130: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
5140: 65 72 72 6f 72 3a 20 55 6e 61 62 6c 65 20 74 6f  error: Unable to
5150: 20 67 65 74 20 61 6e 20 69 6e 74 65 72 70 72 65   get an interpre
5160: 74 65 72 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  ter");....return
5170: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70  (-EIO);..}...app
5180: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
5190: 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65  cl_Preserve(inte
51a0: 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72 65 74 20  rp);)...tcl_ret 
51b0: 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c  = appfs_Tcl_Eval
51c0: 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61  (interp, 2, "::a
51d0: 70 70 66 73 3a 3a 67 65 74 61 74 74 72 22 2c 20  ppfs::getattr", 
51e0: 70 61 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f  path);..if (tcl_
51f0: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
5200: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
5210: 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61 74 74 72  ::appfs::getattr
5220: 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70  (%s) failed.", p
5230: 61 74 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61  ath);...appfs_ca
5240: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50  ll_libtcl(....AP
5250: 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45  PFS_DEBUG("Tcl E
5260: 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63  rror is: %s", Tc
5270: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
5280: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a  t(interp));...).
5290: 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
52a0: 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59  e = APPFS_PATHTY
52b0: 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53  PE_DOES_NOT_EXIS
52c0: 54 3b 0a 0a 09 09 61 70 70 66 73 5f 67 65 74 5f  T;....appfs_get_
52d0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
52e0: 61 64 64 28 70 61 74 68 2c 20 66 73 75 69 64 2c  add(path, fsuid,
52f0: 20 70 61 74 68 69 6e 66 6f 29 3b 0a 0a 09 09 61   pathinfo);....a
5300: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
5310: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
5320: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e  erp);)....return
5330: 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09 7d 0a 0a 09  (-ENOENT);..}...
5340: 69 66 20 28 61 74 74 72 5f 6b 65 79 5f 74 79 70  if (attr_key_typ
5350: 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 61  e == NULL) {...a
5360: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
5370: 28 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 74 79  (....attr_key_ty
5380: 70 65 20 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e  pe       = Tcl_N
5390: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 74 79 70  ewStringObj("typ
53a0: 65 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72  e", -1);....attr
53b0: 5f 6b 65 79 5f 70 65 72 6d 73 20 20 20 20 20 20  _key_perms      
53c0: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
53d0: 62 6a 28 22 70 65 72 6d 73 22 2c 20 2d 31 29 3b  bj("perms", -1);
53e0: 0a 09 09 09 61 74 74 72 5f 6b 65 79 5f 73 69 7a  ....attr_key_siz
53f0: 65 20 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65  e       = Tcl_Ne
5400: 77 53 74 72 69 6e 67 4f 62 6a 28 22 73 69 7a 65  wStringObj("size
5410: 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f  ", -1);....attr_
5420: 6b 65 79 5f 74 69 6d 65 20 20 20 20 20 20 20 3d  key_time       =
5430: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
5440: 6a 28 22 74 69 6d 65 22 2c 20 2d 31 29 3b 0a 09  j("time", -1);..
5450: 09 09 61 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63  ..attr_key_sourc
5460: 65 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53  e     = Tcl_NewS
5470: 74 72 69 6e 67 4f 62 6a 28 22 73 6f 75 72 63 65  tringObj("source
5480: 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f  ", -1);....attr_
5490: 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 20 3d  key_childcount =
54a0: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
54b0: 6a 28 22 63 68 69 6c 64 63 6f 75 6e 74 22 2c 20  j("childcount", 
54c0: 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79  -1);....attr_key
54d0: 5f 70 61 63 6b 61 67 65 64 20 20 20 3d 20 54 63  _packaged   = Tc
54e0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
54f0: 70 61 63 6b 61 67 65 64 22 2c 20 2d 31 29 3b 0a  packaged", -1);.
5500: 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43  ....Tcl_IncrRefC
5510: 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 74 79  ount(attr_key_ty
5520: 70 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72  pe);....Tcl_Incr
5530: 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65  RefCount(attr_ke
5540: 79 5f 70 65 72 6d 73 29 3b 0a 09 09 09 54 63 6c  y_perms);....Tcl
5550: 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74  _IncrRefCount(at
5560: 74 72 5f 6b 65 79 5f 73 69 7a 65 29 3b 0a 09 09  tr_key_size);...
5570: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
5580: 74 28 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 29  t(attr_key_time)
5590: 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66  ;....Tcl_IncrRef
55a0: 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 73  Count(attr_key_s
55b0: 6f 75 72 63 65 29 3b 0a 09 09 09 54 63 6c 5f 49  ource);....Tcl_I
55c0: 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72  ncrRefCount(attr
55d0: 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 29  _key_childcount)
55e0: 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66  ;....Tcl_IncrRef
55f0: 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 70  Count(attr_key_p
5600: 61 63 6b 61 67 65 64 29 3b 0a 09 09 29 0a 09 7d  ackaged);...)..}
5610: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
5620: 62 74 63 6c 28 0a 09 09 61 74 74 72 73 5f 64 69  btcl(...attrs_di
5630: 63 74 20 3d 20 54 63 6c 5f 47 65 74 4f 62 6a 52  ct = Tcl_GetObjR
5640: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09  esult(interp);..
5650: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 44  .tcl_ret = Tcl_D
5660: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
5670: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
5680: 74 72 5f 6b 65 79 5f 74 79 70 65 2c 20 26 61 74  tr_key_type, &at
5690: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 29 0a 09 69  tr_value);..)..i
56a0: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
56b0: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
56c0: 44 45 42 55 47 28 22 5b 64 69 63 74 20 67 65 74  DEBUG("[dict get
56d0: 20 5c 22 74 79 70 65 5c 22 5d 20 66 61 69 6c 65   \"type\"] faile
56e0: 64 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c  d");...appfs_cal
56f0: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50  l_libtcl(....APP
5700: 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72  FS_DEBUG("Tcl Er
5710: 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c  ror is: %s", Tcl
5720: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
5730: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a  (interp));...)..
5740: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
5750: 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28  tcl(Tcl_Release(
5760: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74  interp);)....ret
5770: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
5780: 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 3d  if (attr_value =
5790: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46  = NULL) {...APPF
57a0: 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20  S_DEBUG("error: 
57b0: 55 6e 61 62 6c 65 20 74 6f 20 67 65 74 20 74 79  Unable to get ty
57c0: 70 65 20 66 6f 72 20 5c 22 25 73 5c 22 20 66 72  pe for \"%s\" fr
57d0: 6f 6d 20 54 63 6c 22 2c 20 70 61 74 68 29 3b 0a  om Tcl", path);.
57e0: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
57f0: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
5800: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65  (interp);)....re
5810: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
5820: 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61  .pathinfo->packa
5830: 67 65 64 20 3d 20 30 3b 0a 0a 09 61 70 70 66 73  ged = 0;...appfs
5840: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
5850: 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 20 3d  attr_value_str =
5860: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 61   Tcl_GetString(a
5870: 74 74 72 5f 76 61 6c 75 65 29 3b 0a 0a 09 09 73  ttr_value);....s
5880: 77 69 74 63 68 20 28 61 74 74 72 5f 76 61 6c 75  witch (attr_valu
5890: 65 5f 73 74 72 5b 30 5d 29 20 7b 0a 09 09 09 63  e_str[0]) {....c
58a0: 61 73 65 20 27 64 27 3a 20 2f 2a 20 64 69 72 65  ase 'd': /* dire
58b0: 63 74 6f 72 79 20 2a 2f 0a 09 09 09 09 70 61 74  ctory */.....pat
58c0: 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50  hinfo->type = AP
58d0: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52  PFS_PATHTYPE_DIR
58e0: 45 43 54 4f 52 59 3b 0a 09 09 09 09 70 61 74 68  ECTORY;.....path
58f0: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64  info->typeinfo.d
5900: 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20  ir.childcount = 
5910: 30 3b 0a 0a 09 09 09 09 54 63 6c 5f 44 69 63 74  0;......Tcl_Dict
5920: 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61  ObjGet(interp, a
5930: 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f  ttrs_dict, attr_
5940: 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 2c 20  key_childcount, 
5950: 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09  &attr_value);...
5960: 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65  ..if (attr_value
5970: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09   != NULL) {.....
5980: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47  .tcl_ret = Tcl_G
5990: 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a  etWideIntFromObj
59a0: 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75  (NULL, attr_valu
59b0: 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77  e, &attr_value_w
59c0: 69 64 65 29 3b 0a 09 09 09 09 09 69 66 20 28 74  ide);......if (t
59d0: 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b  cl_ret == TCL_OK
59e0: 29 20 7b 0a 09 09 09 09 09 09 70 61 74 68 69 6e  ) {.......pathin
59f0: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64 69 72  fo->typeinfo.dir
5a00: 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 61 74  .childcount = at
5a10: 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09  tr_value_wide;..
5a20: 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09  ....}.....}.....
5a30: 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20  .break;....case 
5a40: 27 66 27 3a 20 2f 2a 20 66 69 6c 65 20 2a 2f 0a  'f': /* file */.
5a50: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
5a60: 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54  pe = APPFS_PATHT
5a70: 59 50 45 5f 46 49 4c 45 3b 0a 09 09 09 09 70 61  YPE_FILE;.....pa
5a80: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f  thinfo->typeinfo
5a90: 2e 66 69 6c 65 2e 73 69 7a 65 20 3d 20 30 3b 0a  .file.size = 0;.
5aa0: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
5ab0: 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63  peinfo.file.exec
5ac0: 75 74 61 62 6c 65 20 3d 20 30 3b 0a 09 09 09 09  utable = 0;.....
5ad0: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
5ae0: 66 6f 2e 66 69 6c 65 2e 73 75 69 64 52 6f 6f 74  fo.file.suidRoot
5af0: 20 3d 20 30 3b 0a 09 09 09 09 70 61 74 68 69 6e   = 0;.....pathin
5b00: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c  fo->typeinfo.fil
5b10: 65 2e 77 6f 72 6c 64 61 63 63 65 73 73 69 62 6c  e.worldaccessibl
5b20: 65 20 3d 20 30 3b 0a 0a 09 09 09 09 54 63 6c 5f  e = 0;......Tcl_
5b30: 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72  DictObjGet(inter
5b40: 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61  p, attrs_dict, a
5b50: 74 74 72 5f 6b 65 79 5f 73 69 7a 65 2c 20 26 61  ttr_key_size, &a
5b60: 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09  ttr_value);.....
5b70: 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21  if (attr_value !
5b80: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 09 74  = NULL) {......t
5b90: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74  cl_ret = Tcl_Get
5ba0: 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e  WideIntFromObj(N
5bb0: 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c  ULL, attr_value,
5bc0: 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64   &attr_value_wid
5bd0: 65 29 3b 0a 09 09 09 09 09 69 66 20 28 74 63 6c  e);......if (tcl
5be0: 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20  _ret == TCL_OK) 
5bf0: 7b 0a 09 09 09 09 09 09 70 61 74 68 69 6e 66 6f  {.......pathinfo
5c00: 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e  ->typeinfo.file.
5c10: 73 69 7a 65 20 3d 20 61 74 74 72 5f 76 61 6c 75  size = attr_valu
5c20: 65 5f 77 69 64 65 3b 0a 09 09 09 09 09 7d 0a 09  e_wide;......}..
5c30: 09 09 09 7d 0a 0a 09 09 09 09 54 63 6c 5f 44 69  ...}......Tcl_Di
5c40: 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c  ctObjGet(interp,
5c50: 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74   attrs_dict, att
5c60: 72 5f 6b 65 79 5f 70 65 72 6d 73 2c 20 26 61 74  r_key_perms, &at
5c70: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09 69  tr_value);.....i
5c80: 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d  f (attr_value !=
5c90: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 09 61 74   NULL) {......at
5ca0: 74 72 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20 54  tr_value_str = T
5cb0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 61 74 74  cl_GetString(att
5cc0: 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09 09 66  r_value);......f
5cd0: 6f 72 20 28 61 74 74 72 5f 76 61 6c 75 65 5f 73  or (attr_value_s
5ce0: 74 72 5f 69 20 3d 20 26 61 74 74 72 5f 76 61 6c  tr_i = &attr_val
5cf0: 75 65 5f 73 74 72 5b 30 5d 3b 20 2a 61 74 74 72  ue_str[0]; *attr
5d00: 5f 76 61 6c 75 65 5f 73 74 72 5f 69 20 21 3d 20  _value_str_i != 
5d10: 27 5c 30 27 3b 20 61 74 74 72 5f 76 61 6c 75 65  '\0'; attr_value
5d20: 5f 73 74 72 5f 69 2b 2b 29 20 7b 0a 09 09 09 09  _str_i++) {.....
5d30: 09 09 73 77 69 74 63 68 20 28 2a 61 74 74 72 5f  ..switch (*attr_
5d40: 76 61 6c 75 65 5f 73 74 72 5f 69 29 20 7b 0a 09  value_str_i) {..
5d50: 09 09 09 09 09 09 63 61 73 65 20 27 78 27 3a 0a  ......case 'x':.
5d60: 09 09 09 09 09 09 09 09 70 61 74 68 69 6e 66 6f  ........pathinfo
5d70: 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e  ->typeinfo.file.
5d80: 65 78 65 63 75 74 61 62 6c 65 20 3d 20 31 3b 0a  executable = 1;.
5d90: 0a 09 09 09 09 09 09 09 09 62 72 65 61 6b 3b 0a  .........break;.
5da0: 09 09 09 09 09 09 09 63 61 73 65 20 27 55 27 3a  .......case 'U':
5db0: 0a 09 09 09 09 09 09 09 09 70 61 74 68 69 6e 66  .........pathinf
5dc0: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  o->typeinfo.file
5dd0: 2e 73 75 69 64 52 6f 6f 74 20 3d 20 31 3b 0a 0a  .suidRoot = 1;..
5de0: 09 09 09 09 09 09 09 09 62 72 65 61 6b 3b 0a 09  ........break;..
5df0: 09 09 09 09 09 09 63 61 73 65 20 27 2d 27 3a 0a  ......case '-':.
5e00: 09 09 09 09 09 09 09 09 70 61 74 68 69 6e 66 6f  ........pathinfo
5e10: 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e  ->typeinfo.file.
5e20: 77 6f 72 6c 64 61 63 63 65 73 73 69 62 6c 65 20  worldaccessible 
5e30: 3d 20 31 3b 0a 0a 09 09 09 09 09 09 09 09 62 72  = 1;..........br
5e40: 65 61 6b 3b 0a 09 09 09 09 09 09 7d 0a 09 09 09  eak;.......}....
5e50: 09 09 7d 0a 09 09 09 09 7d 0a 09 09 09 09 62 72  ..}.....}.....br
5e60: 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 73 27  eak;....case 's'
5e70: 3a 20 2f 2a 20 73 79 6d 6c 69 6e 6b 20 2a 2f 0a  : /* symlink */.
5e80: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
5e90: 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54  pe = APPFS_PATHT
5ea0: 59 50 45 5f 53 59 4d 4c 49 4e 4b 3b 0a 09 09 09  YPE_SYMLINK;....
5eb0: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  .pathinfo->typei
5ec0: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65  nfo.symlink.size
5ed0: 20 3d 20 30 3b 0a 09 09 09 09 70 61 74 68 69 6e   = 0;.....pathin
5ee0: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  fo->typeinfo.sym
5ef0: 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b 30 5d 20 3d  link.source[0] =
5f00: 20 27 5c 30 27 3b 0a 0a 09 09 09 09 54 63 6c 5f   '\0';......Tcl_
5f10: 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72  DictObjGet(inter
5f20: 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61  p, attrs_dict, a
5f30: 74 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65 2c 20  ttr_key_source, 
5f40: 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09  &attr_value);...
5f50: 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65  ..if (attr_value
5f60: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09   != NULL) {.....
5f70: 09 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 20  .attr_value_str 
5f80: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 46  = Tcl_GetStringF
5f90: 72 6f 6d 4f 62 6a 28 61 74 74 72 5f 76 61 6c 75  romObj(attr_valu
5fa0: 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 69  e, &attr_value_i
5fb0: 6e 74 29 3b 20 0a 0a 09 09 09 09 09 69 66 20 28  nt); .......if (
5fc0: 28 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 20  (attr_value_int 
5fd0: 2b 20 31 29 20 3c 3d 20 73 69 7a 65 6f 66 28 70  + 1) <= sizeof(p
5fe0: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
5ff0: 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65  o.symlink.source
6000: 29 29 20 7b 0a 09 09 09 09 09 09 70 61 74 68 69  )) {.......pathi
6010: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79  nfo->typeinfo.sy
6020: 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20 61 74 74  mlink.size = att
6030: 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a 09 09 09  r_value_int;....
6040: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
6050: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f  einfo.symlink.so
6060: 75 72 63 65 5b 61 74 74 72 5f 76 61 6c 75 65 5f  urce[attr_value_
6070: 69 6e 74 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09 09  int] = '\0';....
6080: 09 09 09 09 6d 65 6d 63 70 79 28 70 61 74 68 69  ....memcpy(pathi
6090: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79  nfo->typeinfo.sy
60a0: 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c 20 61 74  mlink.source, at
60b0: 74 72 5f 76 61 6c 75 65 5f 73 74 72 2c 20 61 74  tr_value_str, at
60c0: 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 0a 09  tr_value_int);..
60d0: 09 09 09 09 7d 0a 09 09 09 09 7d 0a 09 09 09 09  ....}.....}.....
60e0: 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27  break;....case '
60f0: 46 27 3a 20 2f 2a 20 70 69 70 65 2f 66 69 66 6f  F': /* pipe/fifo
6100: 20 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 6f   */.....pathinfo
6110: 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50  ->type = APPFS_P
6120: 41 54 48 54 59 50 45 5f 46 49 46 4f 3b 0a 09 09  ATHTYPE_FIFO;...
6130: 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65  ..break;....case
6140: 20 27 53 27 3a 20 2f 2a 20 55 4e 49 58 20 64 6f   'S': /* UNIX do
6150: 6d 61 69 6e 20 73 6f 63 6b 65 74 20 2a 2f 0a 09  main socket */..
6160: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
6170: 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59  e = APPFS_PATHTY
6180: 50 45 5f 53 4f 43 4b 45 54 3b 0a 09 09 09 09 62  PE_SOCKET;.....b
6190: 72 65 61 6b 3b 0a 09 09 09 64 65 66 61 75 6c 74  reak;....default
61a0: 3a 0a 09 09 09 09 72 65 74 76 61 6c 20 3d 20 2d  :.....retval = -
61b0: 45 49 4f 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f  EIO;...}....Tcl_
61c0: 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72  DictObjGet(inter
61d0: 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61  p, attrs_dict, a
61e0: 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64  ttr_key_packaged
61f0: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a  , &attr_value);.
6200: 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65  ..if (attr_value
6210: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 70   != NULL) {....p
6220: 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67 65  athinfo->package
6230: 64 20 3d 20 31 3b 0a 09 09 7d 0a 0a 09 09 54 63  d = 1;...}....Tc
6240: 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74  l_DictObjGet(int
6250: 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c  erp, attrs_dict,
6260: 20 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 2c 20   attr_key_time, 
6270: 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09  &attr_value);...
6280: 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21  if (attr_value !
6290: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 74 63 6c  = NULL) {....tcl
62a0: 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 57 69  _ret = Tcl_GetWi
62b0: 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e 55 4c  deIntFromObj(NUL
62c0: 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c 20 26  L, attr_value, &
62d0: 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 29  attr_value_wide)
62e0: 3b 0a 09 09 09 69 66 20 28 74 63 6c 5f 72 65 74  ;....if (tcl_ret
62f0: 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   == TCL_OK) {...
6300: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 69 6d 65  ..pathinfo->time
6310: 20 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69   = attr_value_wi
6320: 64 65 3b 0a 09 09 09 7d 0a 09 09 7d 20 65 6c 73  de;....}...} els
6330: 65 20 7b 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d  e {....pathinfo-
6340: 3e 74 69 6d 65 20 3d 20 61 70 70 66 73 5f 62 6f  >time = appfs_bo
6350: 6f 74 74 69 6d 65 3b 0a 09 09 7d 0a 0a 09 09 54  ottime;...}....T
6360: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72  cl_Release(inter
6370: 70 29 3b 0a 09 29 0a 0a 09 69 66 20 28 70 61 74  p);..)...if (pat
6380: 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67 65 64 29  hinfo->packaged)
6390: 20 7b 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e 69   {...pathinfo->i
63a0: 6e 6f 64 65 20 3d 20 61 70 70 66 73 5f 67 65 74  node = appfs_get
63b0: 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74 68  _path_inode(path
63c0: 2c 20 2d 31 29 3b 0a 09 7d 20 65 6c 73 65 20 7b  , -1);..} else {
63d0: 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e 69 6e 6f  ...pathinfo->ino
63e0: 64 65 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 70  de = appfs_get_p
63f0: 61 74 68 5f 69 6e 6f 64 65 28 70 61 74 68 2c 20  ath_inode(path, 
6400: 66 73 75 69 64 29 3b 0a 09 7d 0a 0a 09 41 50 50  fsuid);..}...APP
6410: 46 53 5f 44 45 42 55 47 28 22 43 61 63 68 69 6e  FS_DEBUG("Cachin
6420: 67 20 69 6e 6f 64 65 20 66 6f 72 20 70 61 74 68  g inode for path
6430: 3d 25 73 2c 75 69 64 3d 25 6c 6c 69 20 61 73 20  =%s,uid=%lli as 
6440: 25 6c 6c 75 20 28 70 61 63 6b 61 67 65 64 20 3d  %llu (packaged =
6450: 20 25 69 29 22 2c 20 70 61 74 68 2c 20 28 6c 6f   %i)", path, (lo
6460: 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 2c 20  ng long) fsuid, 
6470: 70 61 74 68 69 6e 66 6f 2d 3e 69 6e 6f 64 65 2c  pathinfo->inode,
6480: 20 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 6b 61   pathinfo->packa
6490: 67 65 64 29 3b 0a 0a 09 69 66 20 28 72 65 74 76  ged);...if (retv
64a0: 61 6c 20 3d 3d 20 30 29 20 7b 0a 09 09 61 70 70  al == 0) {...app
64b0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
64c0: 5f 63 61 63 68 65 5f 61 64 64 28 70 61 74 68 2c  _cache_add(path,
64d0: 20 66 73 75 69 64 2c 20 70 61 74 68 69 6e 66 6f   fsuid, pathinfo
64e0: 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 41  );..} else {...A
64f0: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
6500: 72 3a 20 49 6e 76 61 6c 69 64 20 74 79 70 65 20  r: Invalid type 
6510: 66 6f 72 20 5c 22 25 73 5c 22 20 66 72 6f 6d 20  for \"%s\" from 
6520: 54 63 6c 22 2c 20 70 61 74 68 29 3b 0a 09 7d 0a  Tcl", path);..}.
6530: 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
6540: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61 72  ;.}..static char
6550: 20 2a 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f   *appfs_prepare_
6560: 74 6f 5f 63 72 65 61 74 65 28 63 6f 6e 73 74 20  to_create(const 
6570: 63 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54  char *path) {..T
6580: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
6590: 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a  p;..const char *
65a0: 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20  real_path;..int 
65b0: 74 63 6c 5f 72 65 74 3b 0a 0a 09 61 70 70 66 73  tcl_ret;...appfs
65c0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
65d0: 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73  ache_flush(appfs
65e0: 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31  _get_fsuid(), -1
65f0: 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  );...interp = ap
6600: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  pfs_TclInterp();
6610: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
6620: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
6630: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70  (NULL);..}...app
6640: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54  fs_call_libtcl(T
6650: 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65  cl_Preserve(inte
6660: 72 70 29 3b 29 0a 0a 09 61 70 70 66 73 5f 63 61  rp);)...appfs_ca
6670: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c  ll_libtcl(...tcl
6680: 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c  _ret = appfs_Tcl
6690: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c  _Eval(interp, 2,
66a0: 20 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65 70 61   "::appfs::prepa
66b0: 72 65 5f 74 6f 5f 63 72 65 61 74 65 22 2c 20 70  re_to_create", p
66c0: 61 74 68 29 3b 0a 09 29 0a 09 69 66 20 28 74 63  ath);..)..if (tc
66d0: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
66e0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
66f0: 28 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65 70 61  ("::appfs::prepa
6700: 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 25 73 29  re_to_create(%s)
6710: 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29   failed.", path)
6720: 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ;...appfs_call_l
6730: 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f  ibtcl(....APPFS_
6740: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72  DEBUG("Tcl Error
6750: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
6760: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
6770: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61  terp));...)....a
6780: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
6790: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
67a0: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e  erp);)....return
67b0: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70  (NULL);..}...app
67c0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
67d0: 09 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63  ..real_path = Tc
67e0: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
67f0: 74 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09  t(interp);..)...
6800: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
6810: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  l(Tcl_Release(in
6820: 74 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72 65  terp);)...if (re
6830: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  al_path == NULL)
6840: 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c   {...return(NULL
6850: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 73  );..}...return(s
6860: 74 72 64 75 70 28 72 65 61 6c 5f 70 61 74 68 29  trdup(real_path)
6870: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61  );.}..static cha
6880: 72 20 2a 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61  r *appfs_localpa
6890: 74 68 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  th(const char *p
68a0: 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  ath) {..Tcl_Inte
68b0: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e  rp *interp;..con
68c0: 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 61  st char *real_pa
68d0: 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  th;..int tcl_ret
68e0: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  ;...interp = app
68f0: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a  fs_TclInterp();.
6900: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
6910: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
6920: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  NULL);..}...appf
6930: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
6940: 6c 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72  l_Preserve(inter
6950: 70 29 3b 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c  p);)...appfs_cal
6960: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f  l_libtcl(...tcl_
6970: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
6980: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20  Eval(interp, 2, 
6990: 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63 61 6c 70  "::appfs::localp
69a0: 61 74 68 22 2c 20 70 61 74 68 29 3b 0a 09 29 0a  ath", path);..).
69b0: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
69c0: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
69d0: 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73  S_DEBUG("::appfs
69e0: 3a 3a 6c 6f 63 61 6c 70 61 74 68 28 25 73 29 20  ::localpath(%s) 
69f0: 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b  failed.", path);
6a00: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
6a10: 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44  btcl(....APPFS_D
6a20: 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20  EBUG("Tcl Error 
6a30: 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74  is: %s", Tcl_Get
6a40: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
6a50: 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 72 65  erp));...)....re
6a60: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
6a70: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
6a80: 63 6c 28 0a 09 09 72 65 61 6c 5f 70 61 74 68 20  cl(...real_path 
6a90: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  = Tcl_GetStringR
6aa0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09  esult(interp);..
6ab0: 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  )...appfs_call_l
6ac0: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
6ad0: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 69 66  e(interp);)...if
6ae0: 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e   (real_path == N
6af0: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
6b00: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  NULL);..}...retu
6b10: 72 6e 28 73 74 72 64 75 70 28 72 65 61 6c 5f 70  rn(strdup(real_p
6b20: 61 74 68 29 29 3b 0a 7d 0a 0a 23 69 66 20 28 64  ath));.}..#if (d
6b30: 65 66 69 6e 65 64 28 44 45 42 55 47 29 20 26 26  efined(DEBUG) &&
6b40: 20 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45   defined(APPFS_E
6b50: 58 49 54 5f 50 41 54 48 29 29 20 7c 7c 20 64 65  XIT_PATH)) || de
6b60: 66 69 6e 65 64 28 41 50 50 46 53 5f 45 58 49 54  fined(APPFS_EXIT
6b70: 5f 50 41 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a  _PATH_ENABLE_MAJ
6b80: 4f 52 5f 53 45 43 55 52 49 54 59 5f 48 4f 4c 45  OR_SECURITY_HOLE
6b90: 29 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  ).static void ap
6ba0: 70 66 73 5f 65 78 69 74 28 76 6f 69 64 29 20 7b  pfs_exit(void) {
6bb0: 0a 09 69 6e 74 20 67 6c 6f 62 61 6c 5f 69 6e 74  ..int global_int
6bc0: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 3b 0a 0a  erp_reset_key;..
6bd0: 09 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72  .global_interp_r
6be0: 65 73 65 74 5f 6b 65 79 20 3d 20 5f 5f 73 79 6e  eset_key = __syn
6bf0: 63 5f 66 65 74 63 68 5f 61 6e 64 5f 61 64 64 28  c_fetch_and_add(
6c00: 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65  &interp_reset_ke
6c10: 79 2c 20 30 29 3b 0a 09 5f 5f 73 79 6e 63 5f 66  y, 0);..__sync_f
6c20: 65 74 63 68 5f 61 6e 64 5f 73 75 62 28 26 69 6e  etch_and_sub(&in
6c30: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20  terp_reset_key, 
6c40: 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65  global_interp_re
6c50: 73 65 74 5f 6b 65 79 29 3b 0a 0a 09 77 68 69 6c  set_key);...whil
6c60: 65 20 28 5f 5f 73 79 6e 63 5f 73 75 62 5f 61 6e  e (__sync_sub_an
6c70: 64 5f 66 65 74 63 68 28 26 69 6e 74 65 72 70 5f  d_fetch(&interp_
6c80: 72 65 73 65 74 5f 6b 65 79 2c 20 31 29 20 3e 3d  reset_key, 1) >=
6c90: 20 30 29 20 7b 0a 09 09 2f 2a 20 42 75 73 79 20   0) {.../* Busy 
6ca0: 4c 6f 6f 70 20 2a 2f 0a 09 7d 0a 0a 09 67 6c 6f  Loop */..}...glo
6cb0: 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74  bal_interp_reset
6cc0: 5f 6b 65 79 20 3d 20 5f 5f 73 79 6e 63 5f 66 65  _key = __sync_fe
6cd0: 74 63 68 5f 61 6e 64 5f 61 64 64 28 26 69 6e 74  tch_and_add(&int
6ce0: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 30  erp_reset_key, 0
6cf0: 29 3b 0a 09 69 66 20 28 67 6c 6f 62 61 6c 5f 69  );..if (global_i
6d00: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20  nterp_reset_key 
6d10: 21 3d 20 2d 31 29 20 7b 0a 09 09 41 50 50 46 53  != -1) {...APPFS
6d20: 5f 44 45 42 55 47 28 22 45 72 72 6f 72 20 73 65  _DEBUG("Error se
6d30: 6e 64 69 6e 67 20 6b 69 6c 6c 20 73 69 67 6e 61  nding kill signa
6d40: 6c 20 74 6f 20 61 6c 6c 20 74 68 72 65 61 64 73  l to all threads
6d50: 2c 20 61 62 6f 72 74 69 6e 67 20 61 6e 79 77 61  , aborting anywa
6d60: 79 2e 22 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73  y.");..}...appfs
6d70: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
6d80: 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c 20 2d  ache_flush(-1, -
6d90: 31 29 3b 0a 0a 09 66 75 73 65 5f 65 78 69 74 28  1);...fuse_exit(
6da0: 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65 78 74  fuse_get_context
6db0: 28 29 2d 3e 66 75 73 65 29 3b 0a 0a 09 72 65 74  ()->fuse);...ret
6dc0: 75 72 6e 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 73  urn;.}.#endif..s
6dd0: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
6de0: 66 75 73 65 5f 72 65 61 64 6c 69 6e 6b 28 63 6f  fuse_readlink(co
6df0: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
6e00: 63 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f  char *buf, size_
6e10: 74 20 73 69 7a 65 29 20 7b 0a 09 73 74 72 75 63  t size) {..struc
6e20: 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f  t appfs_pathinfo
6e30: 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69 6e 74 20   pathinfo;..int 
6e40: 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 41 50  retval = 0;...AP
6e50: 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72  PFS_DEBUG("Enter
6e60: 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e   (path = %s, ...
6e70: 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 70 61 74  )", path);...pat
6e80: 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41 50 50  hinfo.type = APP
6e90: 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41  FS_PATHTYPE_INVA
6ea0: 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  LID;...retval = 
6eb0: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
6ec0: 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69  nfo(path, &pathi
6ed0: 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65 74 76 61  nfo);..if (retva
6ee0: 6c 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  l != 0) {...retu
6ef0: 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a  rn(retval);..}..
6f00: 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 74 79  .if (pathinfo.ty
6f10: 70 65 20 21 3d 20 41 50 50 46 53 5f 50 41 54 48  pe != APPFS_PATH
6f20: 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 29 20 7b 0a  TYPE_SYMLINK) {.
6f30: 09 09 72 65 74 75 72 6e 28 2d 45 49 4e 56 41 4c  ..return(-EINVAL
6f40: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 73 74 72  );..}...if ((str
6f50: 6c 65 6e 28 70 61 74 68 69 6e 66 6f 2e 74 79 70  len(pathinfo.typ
6f60: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f  einfo.symlink.so
6f70: 75 72 63 65 29 20 2b 20 31 29 20 3e 20 73 69 7a  urce) + 1) > siz
6f80: 65 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  e) {...return(-E
6f90: 4e 41 4d 45 54 4f 4f 4c 4f 4e 47 29 3b 0a 09 7d  NAMETOOLONG);..}
6fa0: 0a 0a 09 6d 65 6d 63 70 79 28 62 75 66 2c 20 70  ...memcpy(buf, p
6fb0: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
6fc0: 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c  .symlink.source,
6fd0: 20 73 74 72 6c 65 6e 28 70 61 74 68 69 6e 66 6f   strlen(pathinfo
6fe0: 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e  .typeinfo.symlin
6ff0: 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31 29 3b 0a  k.source) + 1);.
7000: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
7010: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
7020: 5f 66 75 73 65 5f 67 65 74 61 74 74 72 28 63 6f  _fuse_getattr(co
7030: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
7040: 73 74 72 75 63 74 20 73 74 61 74 20 2a 73 74 62  struct stat *stb
7050: 75 66 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70  uf) {..struct ap
7060: 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74  pfs_pathinfo pat
7070: 68 69 6e 66 6f 3b 0a 09 69 6e 74 20 63 68 61 6e  hinfo;..int chan
7080: 67 65 4f 77 6e 65 72 54 6f 55 73 65 72 49 66 50  geOwnerToUserIfP
7090: 61 63 6b 61 67 65 64 3b 0a 09 69 6e 74 20 72 65  ackaged;..int re
70a0: 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 3d  tval;...retval =
70b0: 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55   0;...APPFS_DEBU
70c0: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
70d0: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
70e0: 29 3b 0a 0a 23 69 66 20 28 64 65 66 69 6e 65 64  );..#if (defined
70f0: 28 44 45 42 55 47 29 20 26 26 20 64 65 66 69 6e  (DEBUG) && defin
7100: 65 64 28 41 50 50 46 53 5f 45 58 49 54 5f 50 41  ed(APPFS_EXIT_PA
7110: 54 48 29 29 20 7c 7c 20 64 65 66 69 6e 65 64 28  TH)) || defined(
7120: 41 50 50 46 53 5f 45 58 49 54 5f 50 41 54 48 5f  APPFS_EXIT_PATH_
7130: 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f 53 45 43  ENABLE_MAJOR_SEC
7140: 55 52 49 54 59 5f 48 4f 4c 45 29 0a 09 2f 2a 0a  URITY_HOLE)../*.
7150: 09 20 2a 20 54 68 69 73 20 69 73 20 61 20 6d 61  . * This is a ma
7160: 6a 6f 72 20 73 65 63 75 72 69 74 79 20 69 73 73  jor security iss
7170: 75 65 20 73 6f 20 77 65 20 63 61 6e 6e 6f 74 20  ue so we cannot 
7180: 6c 65 74 20 69 74 20 62 65 20 63 6f 6d 70 69 6c  let it be compil
7190: 65 64 20 69 6e 74 6f 0a 09 20 2a 20 61 6e 79 20  ed into.. * any 
71a0: 72 65 6c 65 61 73 65 0a 09 20 2a 2f 0a 0a 09 69  release.. */...i
71b0: 66 20 28 73 74 72 63 6d 70 28 70 61 74 68 2c 20  f (strcmp(path, 
71c0: 22 2f 65 78 69 74 22 29 20 3d 3d 20 30 29 20 7b  "/exit") == 0) {
71d0: 0a 09 09 61 70 70 66 73 5f 65 78 69 74 28 29 3b  ...appfs_exit();
71e0: 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 70 61 74  ..}.#endif...pat
71f0: 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41 50 50  hinfo.type = APP
7200: 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41  FS_PATHTYPE_INVA
7210: 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  LID;...retval = 
7220: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
7230: 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69  nfo(path, &pathi
7240: 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65 74 76 61  nfo);..if (retva
7250: 6c 20 21 3d 20 30 29 20 7b 0a 09 09 69 66 20 28  l != 0) {...if (
7260: 72 65 74 76 61 6c 20 3d 3d 20 2d 45 4e 4f 45 4e  retval == -ENOEN
7270: 54 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45  T) {....APPFS_DE
7280: 42 55 47 28 22 67 65 74 5f 70 61 74 68 5f 69 6e  BUG("get_path_in
7290: 66 6f 20 72 65 74 75 72 6e 65 64 20 45 4e 4f 45  fo returned ENOE
72a0: 4e 54 2c 20 72 65 74 75 72 6e 69 6e 67 20 69 74  NT, returning it
72b0: 20 61 73 20 77 65 6c 6c 2e 22 29 3b 0a 09 09 7d   as well.");...}
72c0: 20 65 6c 73 65 20 7b 0a 09 09 09 41 50 50 46 53   else {....APPFS
72d0: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 67  _DEBUG("error: g
72e0: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20 66 61 69  et_path_info fai
72f0: 6c 65 64 22 29 3b 0a 09 09 7d 0a 0a 09 09 72 65  led");...}....re
7300: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d  turn(retval);..}
7310: 0a 0a 09 6d 65 6d 73 65 74 28 73 74 62 75 66 2c  ...memset(stbuf,
7320: 20 30 2c 20 73 69 7a 65 6f 66 28 73 74 72 75 63   0, sizeof(struc
7330: 74 20 73 74 61 74 29 29 3b 0a 0a 09 73 74 62 75  t stat));...stbu
7340: 66 2d 3e 73 74 5f 6d 74 69 6d 65 20 3d 20 70 61  f->st_mtime = pa
7350: 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74  thinfo.time;..st
7360: 62 75 66 2d 3e 73 74 5f 63 74 69 6d 65 20 3d 20  buf->st_ctime = 
7370: 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09  pathinfo.time;..
7380: 73 74 62 75 66 2d 3e 73 74 5f 61 74 69 6d 65 20  stbuf->st_atime 
7390: 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b  = pathinfo.time;
73a0: 0a 09 73 74 62 75 66 2d 3e 73 74 5f 69 6e 6f 20  ..stbuf->st_ino 
73b0: 20 20 3d 20 70 61 74 68 69 6e 66 6f 2e 69 6e 6f    = pathinfo.ino
73c0: 64 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 6d  de;..stbuf->st_m
73d0: 6f 64 65 20 20 3d 20 30 3b 0a 0a 09 63 68 61 6e  ode  = 0;...chan
73e0: 67 65 4f 77 6e 65 72 54 6f 55 73 65 72 49 66 50  geOwnerToUserIfP
73f0: 61 63 6b 61 67 65 64 20 3d 20 31 3b 0a 0a 09 73  ackaged = 1;...s
7400: 77 69 74 63 68 20 28 70 61 74 68 69 6e 66 6f 2e  witch (pathinfo.
7410: 74 79 70 65 29 20 7b 0a 09 09 63 61 73 65 20 41  type) {...case A
7420: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49  PPFS_PATHTYPE_DI
7430: 52 45 43 54 4f 52 59 3a 0a 09 09 09 73 74 62 75  RECTORY:....stbu
7440: 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49  f->st_mode = S_I
7450: 46 44 49 52 20 7c 20 30 35 35 35 3b 0a 09 09 09  FDIR | 0555;....
7460: 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20  stbuf->st_nlink 
7470: 3d 20 32 20 2b 20 70 61 74 68 69 6e 66 6f 2e 74  = 2 + pathinfo.t
7480: 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c  ypeinfo.dir.chil
7490: 64 63 6f 75 6e 74 3b 0a 09 09 09 62 72 65 61 6b  dcount;....break
74a0: 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50  ;...case APPFS_P
74b0: 41 54 48 54 59 50 45 5f 46 49 4c 45 3a 0a 09 09  ATHTYPE_FILE:...
74c0: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
74d0: 3d 20 53 5f 49 46 52 45 47 20 7c 20 30 34 34 34  = S_IFREG | 0444
74e0: 3b 0a 0a 09 09 09 69 66 20 28 70 61 74 68 69 6e  ;.....if (pathin
74f0: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  fo.typeinfo.file
7500: 2e 65 78 65 63 75 74 61 62 6c 65 29 20 7b 0a 09  .executable) {..
7510: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ...stbuf->st_mod
7520: 65 20 7c 3d 20 30 31 31 31 3b 0a 09 09 09 7d 0a  e |= 0111;....}.
7530: 0a 09 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f  ....if (pathinfo
7540: 2e 70 61 63 6b 61 67 65 64 29 20 7b 0a 09 09 09  .packaged) {....
7550: 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 74 79  .if (pathinfo.ty
7560: 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 75 69 64  peinfo.file.suid
7570: 52 6f 6f 74 29 20 7b 0a 09 09 09 09 09 63 68 61  Root) {......cha
7580: 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65 72 49 66  ngeOwnerToUserIf
7590: 50 61 63 6b 61 67 65 64 20 3d 20 30 3b 0a 0a 09  Packaged = 0;...
75a0: 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
75b0: 64 65 20 7c 3d 20 30 34 30 30 30 3b 0a 09 09 09  de |= 04000;....
75c0: 09 7d 0a 09 09 09 7d 0a 0a 09 09 09 69 66 20 28  .}....}.....if (
75d0: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66  pathinfo.typeinf
75e0: 6f 2e 66 69 6c 65 2e 77 6f 72 6c 64 61 63 63 65  o.file.worldacce
75f0: 73 73 69 62 6c 65 29 20 7b 0a 09 09 09 09 73 74  ssible) {.....st
7600: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 26 3d 20  buf->st_mode &= 
7610: 7e 30 37 37 3b 0a 09 09 09 7d 0a 0a 09 09 09 73  ~077;....}.....s
7620: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d  tbuf->st_nlink =
7630: 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74   1;....stbuf->st
7640: 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e 66 6f  _size = pathinfo
7650: 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73  .typeinfo.file.s
7660: 69 7a 65 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a  ize;.....break;.
7670: 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54  ..case APPFS_PAT
7680: 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3a 0a 09  HTYPE_SYMLINK:..
7690: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65  ..stbuf->st_mode
76a0: 20 3d 20 53 5f 49 46 4c 4e 4b 20 7c 20 30 35 35   = S_IFLNK | 055
76b0: 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  5;....stbuf->st_
76c0: 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74  nlink = 1;....st
76d0: 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 70  buf->st_size = p
76e0: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
76f0: 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 3b 0a 09  .symlink.size;..
7700: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20  ..break;...case 
7710: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53  APPFS_PATHTYPE_S
7720: 4f 43 4b 45 54 3a 0a 09 09 09 73 74 62 75 66 2d  OCKET:....stbuf-
7730: 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 53  >st_mode = S_IFS
7740: 4f 43 4b 20 7c 20 30 35 35 35 3b 0a 09 09 09 73  OCK | 0555;....s
7750: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d  tbuf->st_nlink =
7760: 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74   1;....stbuf->st
7770: 5f 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 62 72  _size = 0;....br
7780: 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46  eak;...case APPF
7790: 53 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3a  S_PATHTYPE_FIFO:
77a0: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
77b0: 64 65 20 3d 20 53 5f 49 46 49 46 4f 20 7c 20 30  de = S_IFIFO | 0
77c0: 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  555;....stbuf->s
77d0: 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09  t_nlink = 1;....
77e0: 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d  stbuf->st_size =
77f0: 20 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09   0;....break;...
7800: 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54  case APPFS_PATHT
7810: 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49  YPE_DOES_NOT_EXI
7820: 53 54 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20  ST:....retval = 
7830: 2d 45 4e 4f 45 4e 54 3b 0a 0a 09 09 09 62 72 65  -ENOENT;.....bre
7840: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53  ak;...case APPFS
7850: 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49  _PATHTYPE_INVALI
7860: 44 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20 2d  D:....retval = -
7870: 45 49 4f 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a  EIO;.....break;.
7880: 09 7d 0a 0a 09 69 66 20 28 28 70 61 74 68 69 6e  .}...if ((pathin
7890: 66 6f 2e 70 61 63 6b 61 67 65 64 20 26 26 20 63  fo.packaged && c
78a0: 68 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65 72  hangeOwnerToUser
78b0: 49 66 50 61 63 6b 61 67 65 64 29 20 7c 7c 20 28  IfPackaged) || (
78c0: 21 70 61 74 68 69 6e 66 6f 2e 70 61 63 6b 61 67  !pathinfo.packag
78d0: 65 64 29 29 20 7b 0a 09 09 73 74 62 75 66 2d 3e  ed)) {...stbuf->
78e0: 73 74 5f 75 69 64 20 20 20 3d 20 61 70 70 66 73  st_uid   = appfs
78f0: 5f 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 09 09  _get_fsuid();...
7900: 73 74 62 75 66 2d 3e 73 74 5f 67 69 64 20 20 20  stbuf->st_gid   
7910: 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69  = appfs_get_fsgi
7920: 64 28 29 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74  d();...stbuf->st
7930: 5f 6d 6f 64 65 20 7c 3d 20 30 32 30 30 3b 0a 09  _mode |= 0200;..
7940: 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61  }...return(retva
7950: 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  l);.}..static in
7960: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61  t appfs_fuse_rea
7970: 64 64 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20  ddir(const char 
7980: 2a 70 61 74 68 2c 20 76 6f 69 64 20 2a 62 75 66  *path, void *buf
7990: 2c 20 66 75 73 65 5f 66 69 6c 6c 5f 64 69 72 5f  , fuse_fill_dir_
79a0: 74 20 66 69 6c 6c 65 72 2c 20 6f 66 66 5f 74 20  t filler, off_t 
79b0: 6f 66 66 73 65 74 2c 20 73 74 72 75 63 74 20 66  offset, struct f
79c0: 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66  use_file_info *f
79d0: 69 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  i) {..Tcl_Interp
79e0: 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c 5f 4f   *interp;..Tcl_O
79f0: 62 6a 20 2a 2a 63 68 69 6c 64 72 65 6e 3b 0a 09  bj **children;..
7a00: 69 6e 74 20 63 68 69 6c 64 72 65 6e 5f 63 6f 75  int children_cou
7a10: 6e 74 2c 20 69 64 78 3b 0a 09 69 6e 74 20 74 63  nt, idx;..int tc
7a20: 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  l_ret;...APPFS_D
7a30: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
7a40: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
7a50: 61 74 68 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d  ath);...interp =
7a60: 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70   appfs_TclInterp
7a70: 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  ();..if (interp 
7a80: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50  == NULL) {...APP
7a90: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
7aa0: 20 55 6e 61 62 6c 65 20 74 6f 20 67 65 74 20 61   Unable to get a
7ab0: 6e 20 69 6e 74 65 72 70 72 65 74 65 72 22 29 3b  n interpreter");
7ac0: 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09  ....return(0);..
7ad0: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
7ae0: 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72  ibtcl(Tcl_Preser
7af0: 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 66  ve(interp);)...f
7b00: 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e 22 2c 20  iller(buf, ".", 
7b10: 4e 55 4c 4c 2c 20 30 29 3b 0a 09 66 69 6c 6c 65  NULL, 0);..fille
7b20: 72 28 62 75 66 2c 20 22 2e 2e 22 2c 20 4e 55 4c  r(buf, "..", NUL
7b30: 4c 2c 20 30 29 3b 0a 0a 09 74 63 6c 5f 72 65 74  L, 0);...tcl_ret
7b40: 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61   = appfs_Tcl_Eva
7b50: 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a  l(interp, 2, "::
7b60: 61 70 70 66 73 3a 3a 67 65 74 63 68 69 6c 64 72  appfs::getchildr
7b70: 65 6e 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20  en", path);..if 
7b80: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
7b90: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
7ba0: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65  BUG("::appfs::ge
7bb0: 74 63 68 69 6c 64 72 65 6e 28 25 73 29 20 66 61  tchildren(%s) fa
7bc0: 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09  iled.", path);..
7bd0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
7be0: 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42  cl(....APPFS_DEB
7bf0: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
7c00: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
7c10: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
7c20: 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66  p));...)....appf
7c30: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
7c40: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
7c50: 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 30 29  );)....return(0)
7c60: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
7c70: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f  l_libtcl(...tcl_
7c80: 72 65 74 20 3d 20 54 63 6c 5f 4c 69 73 74 4f 62  ret = Tcl_ListOb
7c90: 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e 74  jGetElements(int
7ca0: 65 72 70 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52  erp, Tcl_GetObjR
7cb0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 26  esult(interp), &
7cc0: 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c 20  children_count, 
7cd0: 26 63 68 69 6c 64 72 65 6e 29 3b 0a 09 29 0a 09  &children);..)..
7ce0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
7cf0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
7d00: 5f 44 45 42 55 47 28 22 50 61 72 73 69 6e 67 20  _DEBUG("Parsing 
7d10: 6c 69 73 74 20 6f 66 20 63 68 69 6c 64 72 65 6e  list of children
7d20: 20 6f 6e 20 70 61 74 68 20 25 73 20 66 61 69 6c   on path %s fail
7d30: 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61  ed.", path);...a
7d40: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
7d50: 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  (....APPFS_DEBUG
7d60: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20  ("Tcl Error is: 
7d70: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  %s", Tcl_GetStri
7d80: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
7d90: 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f  );...)....appfs_
7da0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
7db0: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
7dc0: 29 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a  )....return(0);.
7dd0: 09 7d 0a 0a 09 66 6f 72 20 28 69 64 78 20 3d 20  .}...for (idx = 
7de0: 30 3b 20 69 64 78 20 3c 20 63 68 69 6c 64 72 65  0; idx < childre
7df0: 6e 5f 63 6f 75 6e 74 3b 20 69 64 78 2b 2b 29 20  n_count; idx++) 
7e00: 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  {...appfs_call_l
7e10: 69 62 74 63 6c 28 0a 09 09 09 66 69 6c 6c 65 72  ibtcl(....filler
7e20: 28 62 75 66 2c 20 54 63 6c 5f 47 65 74 53 74 72  (buf, Tcl_GetStr
7e30: 69 6e 67 28 63 68 69 6c 64 72 65 6e 5b 69 64 78  ing(children[idx
7e40: 5d 29 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 09  ]), NULL, 0);...
7e50: 29 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  )..}...appfs_cal
7e60: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
7e70: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
7e80: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
7e90: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
7ea0: 66 75 73 65 5f 6f 70 65 6e 28 63 6f 6e 73 74 20  fuse_open(const 
7eb0: 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75  char *path, stru
7ec0: 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66  ct fuse_file_inf
7ed0: 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c 5f 49 6e  o *fi) {..Tcl_In
7ee0: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 73  terp *interp;..s
7ef0: 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68  truct appfs_path
7f00: 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09  info pathinfo;..
7f10: 63 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c  const char *real
7f20: 5f 70 61 74 68 2c 20 2a 6d 6f 64 65 3b 0a 09 69  _path, *mode;..i
7f30: 6e 74 20 67 70 69 5f 72 65 74 2c 20 74 63 6c 5f  nt gpi_ret, tcl_
7f40: 72 65 74 3b 0a 09 69 6e 74 20 66 68 3b 0a 0a 09  ret;..int fh;...
7f50: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
7f60: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
7f70: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 67  ..)", path);...g
7f80: 70 69 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 67  pi_ret = appfs_g
7f90: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61 74  et_path_info(pat
7fa0: 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a 0a  h, &pathinfo);..
7fb0: 09 69 66 20 28 28 66 69 2d 3e 66 6c 61 67 73 20  .if ((fi->flags 
7fc0: 26 20 28 4f 5f 57 52 4f 4e 4c 59 7c 4f 5f 43 52  & (O_WRONLY|O_CR
7fd0: 45 41 54 29 29 20 3d 3d 20 28 4f 5f 43 52 45 41  EAT)) == (O_CREA
7fe0: 54 7c 4f 5f 57 52 4f 4e 4c 59 29 29 20 7b 0a 09  T|O_WRONLY)) {..
7ff0: 09 2f 2a 20 54 68 65 20 66 69 6c 65 20 77 69 6c  ./* The file wil
8000: 6c 20 62 65 20 63 72 65 61 74 65 64 20 69 66 20  l be created if 
8010: 69 74 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73  it does not exis
8020: 74 20 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f 72  t */...if (gpi_r
8030: 65 74 20 21 3d 20 30 20 26 26 20 67 70 69 5f 72  et != 0 && gpi_r
8040: 65 74 20 21 3d 20 2d 45 4e 4f 45 4e 54 29 20 7b  et != -ENOENT) {
8050: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
8060: 22 65 72 72 6f 72 3a 20 67 65 74 5f 70 61 74 68  "error: get_path
8070: 5f 69 6e 66 6f 20 66 61 69 6c 65 64 22 29 3b 0a  _info failed");.
8080: 0a 09 09 09 72 65 74 75 72 6e 28 67 70 69 5f 72  ....return(gpi_r
8090: 65 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d 6f 64 65  et);...}....mode
80a0: 20 3d 20 22 63 72 65 61 74 65 22 3b 0a 0a 09 09   = "create";....
80b0: 2f 2a 0a 09 09 20 2a 20 57 65 20 68 61 76 65 20  /*... * We have 
80c0: 74 6f 20 63 6c 65 61 72 20 74 68 65 20 63 61 63  to clear the cac
80d0: 68 65 20 68 65 72 65 20 73 6f 20 74 68 61 74 20  he here so that 
80e0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a 09 09  the number of...
80f0: 20 2a 20 6c 69 6e 6b 73 20 67 65 74 73 20 6d 61   * links gets ma
8100: 69 6e 74 61 69 6e 65 64 20 6f 6e 20 74 68 65 20  intained on the 
8110: 70 61 72 65 6e 74 20 64 69 72 65 63 74 6f 72 79  parent directory
8120: 0a 09 09 20 2a 2f 0a 09 09 61 70 70 66 73 5f 67  ... */...appfs_g
8130: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
8140: 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73 5f 67  he_flush(appfs_g
8150: 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31 29 3b  et_fsuid(), -1);
8160: 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 2f 2a 20  ..} else {.../* 
8170: 54 68 65 20 66 69 6c 65 20 6d 75 73 74 20 61 6c  The file must al
8180: 72 65 61 64 79 20 65 78 69 73 74 20 2a 2f 0a 09  ready exist */..
8190: 09 69 66 20 28 67 70 69 5f 72 65 74 20 21 3d 20  .if (gpi_ret != 
81a0: 30 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45  0) {....APPFS_DE
81b0: 42 55 47 28 22 65 72 72 6f 72 3a 20 67 65 74 5f  BUG("error: get_
81c0: 70 61 74 68 5f 69 6e 66 6f 20 66 61 69 6c 65 64  path_info failed
81d0: 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 67  ");.....return(g
81e0: 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09  pi_ret);...}....
81f0: 6d 6f 64 65 20 3d 20 22 22 3b 0a 0a 09 09 69 66  mode = "";....if
8200: 20 28 28 66 69 2d 3e 66 6c 61 67 73 20 26 20 4f   ((fi->flags & O
8210: 5f 57 52 4f 4e 4c 59 29 20 3d 3d 20 4f 5f 57 52  _WRONLY) == O_WR
8220: 4f 4e 4c 59 29 20 7b 0a 09 09 09 6d 6f 64 65 20  ONLY) {....mode 
8230: 3d 20 22 77 72 69 74 65 22 3b 0a 09 09 7d 0a 09  = "write";...}..
8240: 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f  }...if (pathinfo
8250: 2e 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50  .type == APPFS_P
8260: 41 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52  ATHTYPE_DIRECTOR
8270: 59 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  Y) {...APPFS_DEB
8280: 55 47 28 22 65 72 72 6f 72 3a 20 41 73 6b 65 64  UG("error: Asked
8290: 20 74 6f 20 6f 70 65 6e 20 61 20 64 69 72 65 63   to open a direc
82a0: 74 6f 72 79 2e 22 29 3b 0a 0a 09 09 72 65 74 75  tory.");....retu
82b0: 72 6e 28 2d 45 49 53 44 49 52 29 3b 0a 09 7d 0a  rn(-EISDIR);..}.
82c0: 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
82d0: 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69  _TclInterp();..i
82e0: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
82f0: 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  L) {...APPFS_DEB
8300: 55 47 28 22 65 72 72 6f 72 3a 20 55 6e 61 62 6c  UG("error: Unabl
8310: 65 20 74 6f 20 67 65 74 20 61 6e 20 69 6e 74 65  e to get an inte
8320: 72 70 72 65 74 65 72 22 29 3b 0a 0a 09 09 72 65  rpreter");....re
8330: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
8340: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
8350: 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28  cl(Tcl_Preserve(
8360: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f  interp);)...tcl_
8370: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
8380: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 33 2c 20  Eval(interp, 3, 
8390: 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61  "::appfs::openpa
83a0: 74 68 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65 29  th", path, mode)
83b0: 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  ;..if (tcl_ret !
83c0: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50  = TCL_OK) {...AP
83d0: 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70  PFS_DEBUG("::app
83e0: 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28 25 73 2c  fs::openpath(%s,
83f0: 20 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70   %s) failed.", p
8400: 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 09 09 61 70  ath, mode);...ap
8410: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
8420: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
8430: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
8440: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
8450: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
8460: 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63  ;...)....appfs_c
8470: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
8480: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
8490: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  ....return(-EIO)
84a0: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
84b0: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 61 6c  l_libtcl(...real
84c0: 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74 53  _path = Tcl_GetS
84d0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
84e0: 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f  rp);..)...appfs_
84f0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
8500: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
8510: 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74  )...if (real_pat
8520: 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41  h == NULL) {...A
8530: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
8540: 72 3a 20 72 65 61 6c 5f 70 61 74 68 20 77 61 73  r: real_path was
8550: 20 4e 55 4c 4c 2e 22 29 0a 0a 09 09 72 65 74 75   NULL.")....retu
8560: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 41  rn(-EIO);..}...A
8570: 50 50 46 53 5f 44 45 42 55 47 28 22 54 72 61 6e  PPFS_DEBUG("Tran
8580: 73 6c 61 74 65 64 20 72 65 71 75 65 73 74 20 74  slated request t
8590: 6f 20 6f 70 65 6e 20 25 73 20 74 6f 20 6f 70 65  o open %s to ope
85a0: 6e 69 6e 67 20 25 73 20 28 6d 6f 64 65 20 3d 20  ning %s (mode = 
85b0: 5c 22 25 73 5c 22 29 22 2c 20 70 61 74 68 2c 20  \"%s\")", path, 
85c0: 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29  real_path, mode)
85d0: 3b 0a 0a 09 66 68 20 3d 20 6f 70 65 6e 28 72 65  ;...fh = open(re
85e0: 61 6c 5f 70 61 74 68 2c 20 66 69 2d 3e 66 6c 61  al_path, fi->fla
85f0: 67 73 2c 20 30 36 30 30 29 3b 0a 0a 09 69 66 20  gs, 0600);...if 
8600: 28 66 68 20 3c 20 30 29 20 7b 0a 09 09 41 50 50  (fh < 0) {...APP
8610: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
8620: 20 6f 70 65 6e 20 66 61 69 6c 65 64 22 29 3b 0a   open failed");.
8630: 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20  ...return(errno 
8640: 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66 69 2d 3e  * -1);..}...fi->
8650: 66 68 20 3d 20 66 68 3b 0a 0a 09 41 50 50 46 53  fh = fh;...APPFS
8660: 5f 44 45 42 55 47 28 22 4f 70 65 6e 65 64 20 5c  _DEBUG("Opened \
8670: 22 25 73 5c 22 20 28 66 6f 72 20 5c 22 25 73 5c  "%s\" (for \"%s\
8680: 22 29 20 77 69 74 68 20 66 69 6c 65 20 64 65 73  ") with file des
8690: 63 72 69 70 74 6f 72 20 25 69 22 2c 20 72 65 61  criptor %i", rea
86a0: 6c 5f 70 61 74 68 2c 20 70 61 74 68 2c 20 66 68  l_path, path, fh
86b0: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  );...return(0);.
86c0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
86d0: 70 66 73 5f 66 75 73 65 5f 63 6c 6f 73 65 28 63  pfs_fuse_close(c
86e0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
86f0: 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c   struct fuse_fil
8700: 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 69  e_info *fi) {..i
8710: 6e 74 20 63 6c 6f 73 65 5f 72 65 74 3b 0a 0a 09  nt close_ret;...
8720: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
8730: 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74  nfo_cache_rm(pat
8740: 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75  h, appfs_get_fsu
8750: 69 64 28 29 29 3b 0a 0a 09 63 6c 6f 73 65 5f 72  id());...close_r
8760: 65 74 20 3d 20 63 6c 6f 73 65 28 66 69 2d 3e 66  et = close(fi->f
8770: 68 29 3b 0a 09 69 66 20 28 63 6c 6f 73 65 5f 72  h);..if (close_r
8780: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50  et != 0) {...APP
8790: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
87a0: 20 63 6c 6f 73 65 20 66 61 69 6c 65 64 22 29 3b   close failed");
87b0: 0a 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f  ....return(errno
87c0: 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74   * -1);..}...ret
87d0: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69  urn(0);.}..stati
87e0: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
87f0: 5f 72 65 61 64 28 63 6f 6e 73 74 20 63 68 61 72  _read(const char
8800: 20 2a 70 61 74 68 2c 20 63 68 61 72 20 2a 62 75   *path, char *bu
8810: 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20  f, size_t size, 
8820: 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20 73 74  off_t offset, st
8830: 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69  ruct fuse_file_i
8840: 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 73 73 69 7a  nfo *fi) {..ssiz
8850: 65 5f 74 20 72 65 61 64 5f 72 65 74 3b 0a 09 69  e_t read_ret;..i
8860: 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09 41 50 50  nt retval;...APP
8870: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
8880: 28 70 61 74 68 20 3d 20 25 73 2c 20 62 75 66 2c  (path = %s, buf,
8890: 20 73 69 7a 65 20 3d 20 25 6c 6c 69 2c 20 6f 66   size = %lli, of
88a0: 66 73 65 74 20 3d 20 25 6c 6c 69 2c 20 66 64 20  fset = %lli, fd 
88b0: 3d 20 25 6c 6c 69 29 22 2c 20 70 61 74 68 2c 20  = %lli)", path, 
88c0: 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 69 7a 65  (long long) size
88d0: 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 6f 66  , (long long) of
88e0: 66 73 65 74 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67  fset, (long long
88f0: 29 20 66 69 2d 3e 66 68 29 3b 0a 0a 09 72 65 74  ) fi->fh);...ret
8900: 76 61 6c 20 3d 20 30 3b 0a 0a 09 77 68 69 6c 65  val = 0;...while
8910: 20 28 73 69 7a 65 20 21 3d 20 30 29 20 7b 0a 09   (size != 0) {..
8920: 09 72 65 61 64 5f 72 65 74 20 3d 20 70 72 65 61  .read_ret = prea
8930: 64 28 66 69 2d 3e 66 68 2c 20 62 75 66 2c 20 73  d(fi->fh, buf, s
8940: 69 7a 65 2c 20 6f 66 66 73 65 74 29 3b 0a 0a 09  ize, offset);...
8950: 09 69 66 20 28 72 65 61 64 5f 72 65 74 20 3c 20  .if (read_ret < 
8960: 30 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45  0) {....APPFS_DE
8970: 42 55 47 28 22 65 72 72 6f 72 3a 20 72 65 61 64  BUG("error: read
8980: 20 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09 09 72   failed");.....r
8990: 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31  eturn(errno * -1
89a0: 29 3b 0a 09 09 7d 0a 0a 09 09 69 66 20 28 72 65  );...}....if (re
89b0: 61 64 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09  ad_ret == 0) {..
89c0: 09 09 62 72 65 61 6b 3b 0a 09 09 7d 0a 0a 09 09  ..break;...}....
89d0: 73 69 7a 65 20 2d 3d 20 72 65 61 64 5f 72 65 74  size -= read_ret
89e0: 3b 0a 09 09 62 75 66 20 20 2b 3d 20 72 65 61 64  ;...buf  += read
89f0: 5f 72 65 74 3b 0a 09 09 6f 66 66 73 65 74 20 2b  _ret;...offset +
8a00: 3d 20 72 65 61 64 5f 72 65 74 3b 0a 09 09 72 65  = read_ret;...re
8a10: 74 76 61 6c 20 2b 3d 20 72 65 61 64 5f 72 65 74  tval += read_ret
8a20: 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 69 7a 65 20  ;..}...if (size 
8a30: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
8a40: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 69 6e  DEBUG("error: in
8a50: 63 6f 6d 70 6c 65 74 65 20 72 65 61 64 20 28 74  complete read (t
8a60: 68 69 73 20 6d 69 67 68 74 20 62 65 20 61 6e 20  his might be an 
8a70: 65 72 72 6f 72 20 62 65 63 61 75 73 65 20 46 55  error because FU
8a80: 53 45 20 77 69 6c 6c 20 72 65 71 75 65 73 74 20  SE will request 
8a90: 74 68 65 20 65 78 61 63 74 20 6c 65 6e 67 74 68  the exact length
8aa0: 20 6f 66 20 74 68 65 20 66 69 6c 65 29 22 29 3b   of the file)");
8ab0: 0a 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  ..}...APPFS_DEBU
8ac0: 47 28 22 52 65 74 75 72 6e 69 6e 67 3a 20 25 69  G("Returning: %i
8ad0: 22 2c 20 72 65 74 76 61 6c 29 3b 0a 0a 09 72 65  ", retval);...re
8ae0: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a  turn(retval);.}.
8af0: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
8b00: 73 5f 66 75 73 65 5f 77 72 69 74 65 28 63 6f 6e  s_fuse_write(con
8b10: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 63  st char *path, c
8b20: 6f 6e 73 74 20 63 68 61 72 20 2a 62 75 66 2c 20  onst char *buf, 
8b30: 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f 66 66  size_t size, off
8b40: 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63  _t offset, struc
8b50: 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f  t fuse_file_info
8b60: 20 2a 66 69 29 20 7b 0a 09 73 73 69 7a 65 5f 74   *fi) {..ssize_t
8b70: 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 69 6e 74   write_ret;..int
8b80: 20 72 65 74 76 61 6c 3b 0a 0a 09 41 50 50 46 53   retval;...APPFS
8b90: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
8ba0: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c  ath = %s, ...)",
8bb0: 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f   path);...appfs_
8bc0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
8bd0: 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70 70  che_rm(path, app
8be0: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b  fs_get_fsuid());
8bf0: 0a 0a 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a  ...retval = 0;..
8c00: 09 77 68 69 6c 65 20 28 73 69 7a 65 20 21 3d 20  .while (size != 
8c10: 30 29 20 7b 0a 09 09 77 72 69 74 65 5f 72 65 74  0) {...write_ret
8c20: 20 3d 20 70 77 72 69 74 65 28 66 69 2d 3e 66 68   = pwrite(fi->fh
8c30: 2c 20 62 75 66 2c 20 73 69 7a 65 2c 20 6f 66 66  , buf, size, off
8c40: 73 65 74 29 3b 0a 0a 09 09 69 66 20 28 77 72 69  set);....if (wri
8c50: 74 65 5f 72 65 74 20 3c 20 30 29 20 7b 0a 09 09  te_ret < 0) {...
8c60: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72  .APPFS_DEBUG("er
8c70: 72 6f 72 3a 20 77 72 69 74 65 20 66 61 69 6c 65  ror: write faile
8c80: 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28  d");.....return(
8c90: 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 09 7d  errno * -1);...}
8ca0: 0a 0a 09 09 69 66 20 28 77 72 69 74 65 5f 72 65  ....if (write_re
8cb0: 74 20 3d 3d 20 30 29 20 7b 0a 09 09 09 62 72 65  t == 0) {....bre
8cc0: 61 6b 3b 0a 09 09 7d 0a 0a 09 09 73 69 7a 65 20  ak;...}....size 
8cd0: 2d 3d 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 09  -= write_ret;...
8ce0: 62 75 66 20 20 2b 3d 20 77 72 69 74 65 5f 72 65  buf  += write_re
8cf0: 74 3b 0a 09 09 6f 66 66 73 65 74 20 2b 3d 20 77  t;...offset += w
8d00: 72 69 74 65 5f 72 65 74 3b 0a 09 09 72 65 74 76  rite_ret;...retv
8d10: 61 6c 20 2b 3d 20 77 72 69 74 65 5f 72 65 74 3b  al += write_ret;
8d20: 0a 09 7d 0a 0a 09 69 66 20 28 73 69 7a 65 20 21  ..}...if (size !
8d30: 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  = 0) {...APPFS_D
8d40: 45 42 55 47 28 22 65 72 72 6f 72 3a 20 69 6e 63  EBUG("error: inc
8d50: 6f 6d 70 6c 65 74 65 20 77 72 69 74 65 22 29 3b  omplete write");
8d60: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74  ..}...return(ret
8d70: 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  val);.}..static 
8d80: 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 6d  int appfs_fuse_m
8d90: 6b 6e 6f 64 28 63 6f 6e 73 74 20 63 68 61 72 20  knod(const char 
8da0: 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f  *path, mode_t mo
8db0: 64 65 2c 20 64 65 76 5f 74 20 64 65 76 69 63 65  de, dev_t device
8dc0: 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f  ) {..char *real_
8dd0: 70 61 74 68 3b 0a 09 69 6e 74 20 6d 6b 6e 6f 64  path;..int mknod
8de0: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
8df0: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
8e00: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
8e10: 74 68 29 3b 0a 0a 09 69 66 20 28 28 6d 6f 64 65  th);...if ((mode
8e20: 20 26 20 53 5f 49 46 43 48 52 29 20 3d 3d 20 53   & S_IFCHR) == S
8e30: 5f 49 46 43 48 52 29 20 7b 0a 09 09 72 65 74 75  _IFCHR) {...retu
8e40: 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a  rn(-EPERM);..}..
8e50: 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49  .if ((mode & S_I
8e60: 46 42 4c 4b 29 20 3d 3d 20 53 5f 49 46 42 4c 4b  FBLK) == S_IFBLK
8e70: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50  ) {...return(-EP
8e80: 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f  ERM);..}...real_
8e90: 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72 65  path = appfs_pre
8ea0: 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 70  pare_to_create(p
8eb0: 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f  ath);..if (real_
8ec0: 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  path == NULL) {.
8ed0: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
8ee0: 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c  .}...appfs_simul
8ef0: 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65  ate_user_fs_ente
8f00: 72 28 29 3b 0a 0a 09 6d 6b 6e 6f 64 5f 72 65 74  r();...mknod_ret
8f10: 20 3d 20 6d 6b 6e 6f 64 28 72 65 61 6c 5f 70 61   = mknod(real_pa
8f20: 74 68 2c 20 6d 6f 64 65 2c 20 64 65 76 69 63 65  th, mode, device
8f30: 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c  );...appfs_simul
8f40: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76  ate_user_fs_leav
8f50: 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c  e();...free(real
8f60: 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 6d 6b  _path);...if (mk
8f70: 6e 6f 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  nod_ret != 0) {.
8f80: 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a  ..return(errno *
8f90: 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72   -1);..}...retur
8fa0: 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n(0);.}..static 
8fb0: 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 63  int appfs_fuse_c
8fc0: 72 65 61 74 65 28 63 6f 6e 73 74 20 63 68 61 72  reate(const char
8fd0: 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d   *path, mode_t m
8fe0: 6f 64 65 2c 20 73 74 72 75 63 74 20 66 75 73 65  ode, struct fuse
8ff0: 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20  _file_info *fi) 
9000: 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61  {..char *real_pa
9010: 74 68 3b 0a 09 69 6e 74 20 66 64 3b 0a 0a 09 41  th;..int fd;...A
9020: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
9030: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
9040: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69 66  .)", path);...if
9050: 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 43 48   ((mode & S_IFCH
9060: 52 29 20 3d 3d 20 53 5f 49 46 43 48 52 29 20 7b  R) == S_IFCHR) {
9070: 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45 52 4d  ...return(-EPERM
9080: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 6d 6f 64  );..}...if ((mod
9090: 65 20 26 20 53 5f 49 46 42 4c 4b 29 20 3d 3d 20  e & S_IFBLK) == 
90a0: 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09 72 65 74  S_IFBLK) {...ret
90b0: 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a  urn(-EPERM);..}.
90c0: 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70  ..real_path = ap
90d0: 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63  pfs_prepare_to_c
90e0: 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09 69 66  reate(path);..if
90f0: 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e   (real_path == N
9100: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
9110: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  -EIO);..}...appf
9120: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
9130: 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 66 64  fs_enter();...fd
9140: 20 3d 20 63 72 65 61 74 28 72 65 61 6c 5f 70 61   = creat(real_pa
9150: 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61 70 70  th, mode);...app
9160: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
9170: 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66  _fs_leave();...f
9180: 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a  ree(real_path);.
9190: 0a 09 69 66 20 28 66 64 20 3c 20 30 29 20 7b 0a  ..if (fd < 0) {.
91a0: 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a  ..return(errno *
91b0: 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66 69 2d 3e 66   -1);..}...fi->f
91c0: 68 20 3d 20 66 64 3b 0a 0a 09 72 65 74 75 72 6e  h = fd;...return
91d0: 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  (0);.}..static i
91e0: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 74 72  nt appfs_fuse_tr
91f0: 75 6e 63 61 74 65 28 63 6f 6e 73 74 20 63 68 61  uncate(const cha
9200: 72 20 2a 70 61 74 68 2c 20 6f 66 66 5f 74 20 73  r *path, off_t s
9210: 69 7a 65 29 20 7b 0a 09 63 68 61 72 20 2a 72 65  ize) {..char *re
9220: 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74 72  al_path;..int tr
9230: 75 6e 63 61 74 65 5f 72 65 74 3b 0a 0a 09 41 50  uncate_ret;...AP
9240: 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72  PFS_DEBUG("Enter
9250: 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e   (path = %s, ...
9260: 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 72 65 61  )", path);...rea
9270: 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 6c  l_path = appfs_l
9280: 6f 63 61 6c 70 61 74 68 28 70 61 74 68 29 3b 0a  ocalpath(path);.
9290: 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d  .if (real_path =
92a0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
92b0: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
92c0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
92d0: 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68  fo_cache_rm(path
92e0: 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  , appfs_get_fsui
92f0: 64 28 29 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  d());...appfs_si
9300: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65  mulate_user_fs_e
9310: 6e 74 65 72 28 29 3b 0a 0a 09 74 72 75 6e 63 61  nter();...trunca
9320: 74 65 5f 72 65 74 20 3d 20 74 72 75 6e 63 61 74  te_ret = truncat
9330: 65 28 72 65 61 6c 5f 70 61 74 68 2c 20 73 69 7a  e(real_path, siz
9340: 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  e);...appfs_simu
9350: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
9360: 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61  ve();...free(rea
9370: 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 74  l_path);...if (t
9380: 72 75 6e 63 61 74 65 5f 72 65 74 20 21 3d 20 30  runcate_ret != 0
9390: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72  ) {...return(err
93a0: 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72  no * -1);..}...r
93b0: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61  eturn(0);.}..sta
93c0: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
93d0: 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72 28  se_unlink_rmdir(
93e0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
93f0: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
9400: 2a 69 6e 74 65 72 70 3b 0a 09 69 6e 74 20 74 63  *interp;..int tc
9410: 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  l_ret;...APPFS_D
9420: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
9430: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
9440: 61 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65  ath);...appfs_ge
9450: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
9460: 65 5f 66 6c 75 73 68 28 61 70 70 66 73 5f 67 65  e_flush(appfs_ge
9470: 74 5f 66 73 75 69 64 28 29 2c 20 2d 31 29 3b 0a  t_fsuid(), -1);.
9480: 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
9490: 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69  _TclInterp();..i
94a0: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
94b0: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  L) {...return(-E
94c0: 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  IO);..}...appfs_
94d0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
94e0: 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29  Preserve(interp)
94f0: 3b 29 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61  ;)...tcl_ret = a
9500: 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e  ppfs_Tcl_Eval(in
9510: 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66  terp, 2, "::appf
9520: 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68 22 2c 20  s::unlinkpath", 
9530: 70 61 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f  path);..if (tcl_
9540: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
9550: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
9560: 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c 69 6e 6b 70  ::appfs::unlinkp
9570: 61 74 68 28 25 73 29 20 66 61 69 6c 65 64 2e 22  ath(%s) failed."
9580: 2c 20 70 61 74 68 29 3b 0a 09 09 61 70 70 66 73  , path);...appfs
9590: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
95a0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63  .APPFS_DEBUG("Tc
95b0: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c  l Error is: %s",
95c0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
95d0: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09  sult(interp));..
95e0: 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  .)....appfs_call
95f0: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
9600: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
9610: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
9620: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
9630: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
9640: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 72 65  e(interp);)...re
9650: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
9660: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
9670: 65 5f 6d 6b 64 69 72 28 63 6f 6e 73 74 20 63 68  e_mkdir(const ch
9680: 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74  ar *path, mode_t
9690: 20 6d 6f 64 65 29 20 7b 0a 09 63 68 61 72 20 2a   mode) {..char *
96a0: 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20  real_path;..int 
96b0: 6d 6b 64 69 72 5f 72 65 74 3b 0a 0a 09 41 50 50  mkdir_ret;...APP
96c0: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
96d0: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
96e0: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 72 65 61 6c  ", path);...real
96f0: 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72  _path = appfs_pr
9700: 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28  epare_to_create(
9710: 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c  path);..if (real
9720: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
9730: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
9740: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  ..}...appfs_simu
9750: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
9760: 65 72 28 29 3b 0a 0a 09 6d 6b 64 69 72 5f 72 65  er();...mkdir_re
9770: 74 20 3d 20 6d 6b 64 69 72 28 72 65 61 6c 5f 70  t = mkdir(real_p
9780: 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61 70  ath, mode);...ap
9790: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
97a0: 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09  r_fs_leave();...
97b0: 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b  free(real_path);
97c0: 0a 0a 09 69 66 20 28 6d 6b 64 69 72 5f 72 65 74  ...if (mkdir_ret
97d0: 20 21 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 65   != 0) {...if (e
97e0: 72 72 6e 6f 20 21 3d 20 45 45 58 49 53 54 29 20  rrno != EEXIST) 
97f0: 7b 0a 09 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 09 7d 0a 09 7d 0a  o * -1);...}..}.
9810: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
9820: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
9830: 5f 66 75 73 65 5f 63 68 6d 6f 64 28 63 6f 6e 73  _fuse_chmod(cons
9840: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f  t char *path, mo
9850: 64 65 5f 74 20 6d 6f 64 65 29 20 7b 0a 09 54 63  de_t mode) {..Tc
9860: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
9870: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72  ;..const char *r
9880: 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74  eal_path;..int t
9890: 63 6c 5f 72 65 74 2c 20 63 68 6d 6f 64 5f 72 65  cl_ret, chmod_re
98a0: 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  t;...APPFS_DEBUG
98b0: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
98c0: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
98d0: 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61  ;...appfs_get_pa
98e0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d  th_info_cache_rm
98f0: 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74  (path, appfs_get
9900: 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 69 6e 74  _fsuid());...int
9910: 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49  erp = appfs_TclI
9920: 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e  nterp();..if (in
9930: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
9940: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
9950: 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .}...appfs_call_
9960: 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65  libtcl(Tcl_Prese
9970: 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  rve(interp);)...
9980: 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f  tcl_ret = appfs_
9990: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
99a0: 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6f 70   3, "::appfs::op
99b0: 65 6e 70 61 74 68 22 2c 20 70 61 74 68 2c 20 22  enpath", path, "
99c0: 77 72 69 74 65 22 29 3b 0a 09 69 66 20 28 74 63  write");..if (tc
99d0: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
99e0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
99f0: 28 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70  ("::appfs::openp
9a00: 61 74 68 28 25 73 2c 20 25 73 29 20 66 61 69 6c  ath(%s, %s) fail
9a10: 65 64 2e 22 2c 20 70 61 74 68 2c 20 22 77 72 69  ed.", path, "wri
9a20: 74 65 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61  te");...appfs_ca
9a30: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50  ll_libtcl(....AP
9a40: 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45  PFS_DEBUG("Tcl E
9a50: 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63  rror is: %s", Tc
9a60: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
9a70: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a  t(interp));...).
9a80: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
9a90: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
9aa0: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65  (interp);)....re
9ab0: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
9ac0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
9ad0: 63 6c 28 0a 09 09 72 65 61 6c 5f 70 61 74 68 20  cl(...real_path 
9ae0: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  = Tcl_GetStringR
9af0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09  esult(interp);..
9b00: 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  )...appfs_call_l
9b10: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
9b20: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 69 66  e(interp);)...if
9b30: 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e   (real_path == N
9b40: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
9b50: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  -EIO);..}...appf
9b60: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
9b70: 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 63 68  fs_enter();...ch
9b80: 6d 6f 64 5f 72 65 74 20 3d 20 63 68 6d 6f 64 28  mod_ret = chmod(
9b90: 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29  real_path, mode)
9ba0: 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61  ;...appfs_simula
9bb0: 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65  te_user_fs_leave
9bc0: 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 63 68 6d  ();...return(chm
9bd0: 6f 64 5f 72 65 74 29 3b 0a 7d 0a 0a 73 74 61 74  od_ret);.}..stat
9be0: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
9bf0: 65 5f 73 79 6d 6c 69 6e 6b 28 63 6f 6e 73 74 20  e_symlink(const 
9c00: 63 68 61 72 20 2a 6f 6c 64 70 61 74 68 2c 20 63  char *oldpath, c
9c10: 6f 6e 73 74 20 63 68 61 72 20 2a 6e 65 77 70 61  onst char *newpa
9c20: 74 68 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61  th) {..char *rea
9c30: 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 73 79 6d  l_path;..int sym
9c40: 6c 69 6e 6b 5f 72 65 74 3b 0a 0a 09 41 50 50 46  link_ret;...APPF
9c50: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
9c60: 70 61 74 68 20 3d 20 25 73 2c 20 25 73 29 22 2c  path = %s, %s)",
9c70: 20 6f 6c 64 70 61 74 68 2c 20 6e 65 77 70 61 74   oldpath, newpat
9c80: 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20  h);...real_path 
9c90: 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f  = appfs_prepare_
9ca0: 74 6f 5f 63 72 65 61 74 65 28 6e 65 77 70 61 74  to_create(newpat
9cb0: 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61  h);..if (real_pa
9cc0: 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th == NULL) {...
9cd0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
9ce0: 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  ...appfs_simulat
9cf0: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
9d00: 29 3b 0a 0a 09 73 79 6d 6c 69 6e 6b 5f 72 65 74  );...symlink_ret
9d10: 20 3d 20 73 79 6d 6c 69 6e 6b 28 6f 6c 64 70 61   = symlink(oldpa
9d20: 74 68 2c 20 72 65 61 6c 5f 70 61 74 68 29 3b 0a  th, real_path);.
9d30: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  ..appfs_simulate
9d40: 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29  _user_fs_leave()
9d50: 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61  ;...free(real_pa
9d60: 74 68 29 3b 0a 0a 09 69 66 20 28 73 79 6d 6c 69  th);...if (symli
9d70: 6e 6b 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  nk_ret != 0) {..
9d80: 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20  .return(errno * 
9d90: 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  -1);..}...return
9da0: 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 53 51  (0);.}../*. * SQ
9db0: 4c 69 74 65 33 20 6d 6f 64 65 3a 20 45 78 65 63  Lite3 mode: Exec
9dc0: 75 74 65 20 72 61 77 20 53 51 4c 20 61 6e 64 20  ute raw SQL and 
9dd0: 72 65 74 75 72 6e 20 73 75 63 63 65 73 73 20 6f  return success o
9de0: 72 20 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74  r failure. */.st
9df0: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 73  atic int appfs_s
9e00: 71 6c 69 74 65 33 28 63 6f 6e 73 74 20 63 68 61  qlite3(const cha
9e10: 72 20 2a 73 71 6c 29 20 7b 0a 09 54 63 6c 5f 49  r *sql) {..Tcl_I
9e20: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09  nterp *interp;..
9e30: 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 5f  const char *sql_
9e40: 72 65 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65  ret;..int tcl_re
9e50: 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  t;...interp = ap
9e60: 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e  pfs_create_TclIn
9e70: 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 09 69 66 20  terp(NULL);..if 
9e80: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
9e90: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
9ea0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
9eb0: 63 72 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74  create a Tcl int
9ec0: 65 72 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74  erpreter.  Abort
9ed0: 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74  ing.\n");....ret
9ee0: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c  urn(1);..}...tcl
9ef0: 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c  _ret = appfs_Tcl
9f00: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 35 2c  _Eval(interp, 5,
9f10: 20 22 3a 3a 61 70 70 66 73 3a 3a 64 62 22 2c 20   "::appfs::db", 
9f20: 22 65 76 61 6c 22 2c 20 73 71 6c 2c 20 22 72 6f  "eval", sql, "ro
9f30: 77 22 2c 20 22 75 6e 73 65 74 20 2d 6e 6f 63 6f  w", "unset -noco
9f40: 6d 70 6c 61 69 6e 20 72 6f 77 28 2a 29 3b 20 70  mplain row(*); p
9f50: 61 72 72 61 79 20 72 6f 77 3b 20 70 75 74 73 20  array row; puts 
9f60: 5c 22 2d 2d 2d 2d 5c 22 22 29 3b 0a 09 73 71 6c  \"----\"");..sql
9f70: 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 53 74  _ret = Tcl_GetSt
9f80: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
9f90: 70 29 3b 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65  p);...if (tcl_re
9fa0: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
9fb0: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
9fc0: 20 22 5b 65 72 72 6f 72 5d 20 25 73 5c 6e 22 2c   "[error] %s\n",
9fd0: 20 73 71 6c 5f 72 65 74 29 3b 0a 0a 09 09 72 65   sql_ret);....re
9fe0: 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 69 66  turn(1);..}...if
9ff0: 20 28 73 71 6c 5f 72 65 74 20 26 26 20 73 71 6c   (sql_ret && sql
a000: 5f 72 65 74 5b 30 5d 20 21 3d 20 27 5c 30 27 29  _ret[0] != '\0')
a010: 20 7b 0a 09 09 70 72 69 6e 74 66 28 22 25 73 5c   {...printf("%s\
a020: 6e 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a 09 7d  n", sql_ret);..}
a030: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a  ...return(0);.}.
a040: 0a 2f 2a 0a 20 2a 20 54 63 6c 20 6d 6f 64 65 3a  ./*. * Tcl mode:
a050: 20 45 78 65 63 75 74 65 20 72 61 77 20 54 63 6c   Execute raw Tcl
a060: 20 61 6e 64 20 72 65 74 75 72 6e 20 73 75 63 63   and return succ
a070: 65 73 73 20 6f 72 20 66 61 69 6c 75 72 65 0a 20  ess or failure. 
a080: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  */.static int ap
a090: 70 66 73 5f 74 63 6c 28 63 6f 6e 73 74 20 63 68  pfs_tcl(const ch
a0a0: 61 72 20 2a 74 63 6c 29 20 7b 0a 09 54 63 6c 5f  ar *tcl) {..Tcl_
a0b0: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a  Interp *interp;.
a0c0: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c  .const char *tcl
a0d0: 5f 72 65 73 75 6c 74 3b 0a 09 69 6e 74 20 74 63  _result;..int tc
a0e0: 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20  l_ret;...interp 
a0f0: 3d 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54  = appfs_create_T
a100: 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a  clInterp(NULL);.
a110: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
a120: 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  ULL) {...fprintf
a130: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
a140: 20 74 6f 20 63 72 65 61 74 65 20 61 20 54 63 6c   to create a Tcl
a150: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41   interpreter.  A
a160: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09  borting.\n");...
a170: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a  .return(1);..}..
a180: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45  .tcl_ret = Tcl_E
a190: 76 61 6c 28 69 6e 74 65 72 70 2c 20 74 63 6c 29  val(interp, tcl)
a1a0: 3b 0a 09 74 63 6c 5f 72 65 73 75 6c 74 20 3d 20  ;..tcl_result = 
a1b0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
a1c0: 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 69  ult(interp);...i
a1d0: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
a1e0: 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74  L_OK) {...fprint
a1f0: 66 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72 6f  f(stderr, "[erro
a200: 72 5d 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65  r] %s\n", Tcl_Ge
a210: 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 65 72  tVar(interp, "er
a220: 72 6f 72 49 6e 66 6f 22 2c 20 54 43 4c 5f 47 4c  rorInfo", TCL_GL
a230: 4f 42 41 4c 5f 4f 4e 4c 59 29 29 3b 0a 0a 09 09  OBAL_ONLY));....
a240: 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09  return(1);..}...
a250: 69 66 20 28 74 63 6c 5f 72 65 73 75 6c 74 20 26  if (tcl_result &
a260: 26 20 74 63 6c 5f 72 65 73 75 6c 74 5b 30 5d 20  & tcl_result[0] 
a270: 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09 70 72 69  != '\0') {...pri
a280: 6e 74 66 28 22 25 73 5c 6e 22 2c 20 74 63 6c 5f  ntf("%s\n", tcl_
a290: 72 65 73 75 6c 74 29 3b 0a 09 7d 0a 0a 09 72 65  result);..}...re
a2a0: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20  turn(0);.}../*. 
a2b0: 2a 20 41 70 70 46 53 64 20 50 61 63 6b 61 67 65  * AppFSd Package
a2c0: 20 66 6f 72 20 54 63 6c 3a 0a 20 2a 20 20 20 20   for Tcl:. *    
a2d0: 20 20 20 20 20 42 72 69 64 67 65 20 66 6f 72 20       Bridge for 
a2e0: 49 2f 4f 20 6f 70 65 72 61 74 69 6f 6e 73 20 74  I/O operations t
a2f0: 6f 20 72 65 71 75 65 73 74 20 69 6e 66 6f 72 6d  o request inform
a300: 61 74 69 6f 6e 20 61 62 6f 75 74 20 74 68 65 20  ation about the 
a310: 63 75 72 72 65 6e 74 0a 20 2a 20 20 20 20 20 20  current. *      
a320: 20 20 20 74 72 61 6e 73 61 63 74 69 6f 6e 0a 20     transaction. 
a330: 2a 2f 0a 2f 2a 0a 20 2a 20 54 63 6c 20 69 6e 74  */./*. * Tcl int
a340: 65 72 66 61 63 65 20 74 6f 20 67 65 74 20 74 68  erface to get th
a350: 65 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79  e home directory
a360: 20 66 6f 72 20 74 68 65 20 75 73 65 72 20 6d 61   for the user ma
a370: 6b 69 6e 67 20 74 68 65 20 22 63 75 72 72 65 6e  king the "curren
a380: 74 22 0a 20 2a 20 46 55 53 45 20 49 2f 4f 20 72  t". * FUSE I/O r
a390: 65 71 75 65 73 74 0a 20 2a 2f 0a 73 74 61 74 69  equest. */.stati
a3a0: 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f  c int tcl_appfs_
a3b0: 67 65 74 5f 68 6f 6d 65 64 69 72 28 43 6c 69 65  get_homedir(Clie
a3c0: 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49  ntData cd, Tcl_I
a3d0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69  nterp *interp, i
a3e0: 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a  nt objc, Tcl_Obj
a3f0: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20   *CONST objv[]) 
a400: 7b 0a 09 63 68 61 72 20 2a 68 6f 6d 65 64 69 72  {..char *homedir
a410: 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 68 6f 6d 65  ;..Tcl_Obj *home
a420: 64 69 72 5f 6f 62 6a 3b 0a 09 75 69 64 5f 74 20  dir_obj;..uid_t 
a430: 66 73 75 69 64 3b 0a 09 73 74 61 74 69 63 20 5f  fsuid;..static _
a440: 5f 74 68 72 65 61 64 20 54 63 6c 5f 4f 62 6a 20  _thread Tcl_Obj 
a450: 2a 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62  *last_homedir_ob
a460: 6a 20 3d 20 4e 55 4c 4c 3b 0a 09 73 74 61 74 69  j = NULL;..stati
a470: 63 20 5f 5f 74 68 72 65 61 64 20 75 69 64 5f 74  c __thread uid_t
a480: 20 6c 61 73 74 5f 66 73 75 69 64 20 3d 20 2d 31   last_fsuid = -1
a490: 3b 0a 0a 20 20 20 20 20 20 20 20 69 66 20 28 6f  ;..        if (o
a4a0: 62 6a 63 20 21 3d 20 31 29 20 7b 0a 20 20 20 20  bjc != 1) {.    
a4b0: 20 20 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f              Tcl_
a4c0: 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74  WrongNumArgs(int
a4d0: 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 4e 55  erp, 1, objv, NU
a4e0: 4c 4c 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  LL);.           
a4f0: 20 20 20 20 20 72 65 74 75 72 6e 28 54 43 4c 5f       return(TCL_
a500: 45 52 52 4f 52 29 3b 0a 20 20 20 20 20 20 20 20  ERROR);.        
a510: 7d 0a 0a 09 66 73 75 69 64 20 3d 20 61 70 70 66  }...fsuid = appf
a520: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 0a  s_get_fsuid();..
a530: 09 69 66 20 28 66 73 75 69 64 20 3d 3d 20 6c 61  .if (fsuid == la
a540: 73 74 5f 66 73 75 69 64 20 26 26 20 6c 61 73 74  st_fsuid && last
a550: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 21 3d 20  _homedir_obj != 
a560: 4e 55 4c 4c 29 20 7b 0a 09 09 68 6f 6d 65 64 69  NULL) {...homedi
a570: 72 5f 6f 62 6a 20 3d 20 6c 61 73 74 5f 68 6f 6d  r_obj = last_hom
a580: 65 64 69 72 5f 6f 62 6a 3b 0a 0a 09 09 54 63 6c  edir_obj;....Tcl
a590: 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 68 6f  _IncrRefCount(ho
a5a0: 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 7d 20 65  medir_obj);..} e
a5b0: 6c 73 65 20 7b 0a 09 09 68 6f 6d 65 64 69 72 20  lse {...homedir 
a5c0: 3d 20 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65  = appfs_get_home
a5d0: 64 69 72 28 61 70 70 66 73 5f 67 65 74 5f 66 73  dir(appfs_get_fs
a5e0: 75 69 64 28 29 29 3b 0a 0a 09 09 69 66 20 28 68  uid());....if (h
a5f0: 6f 6d 65 64 69 72 20 3d 3d 20 4e 55 4c 4c 29 20  omedir == NULL) 
a600: 7b 0a 09 09 09 72 65 74 75 72 6e 28 54 43 4c 5f  {....return(TCL_
a610: 45 52 52 4f 52 29 3b 0a 09 09 7d 0a 0a 09 09 68  ERROR);...}....h
a620: 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 54 63 6c  omedir_obj = Tcl
a630: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 68 6f  _NewStringObj(ho
a640: 6d 65 64 69 72 2c 20 2d 31 29 3b 0a 0a 09 09 66  medir, -1);....f
a650: 72 65 65 28 68 6f 6d 65 64 69 72 29 3b 0a 0a 09  ree(homedir);...
a660: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e  .Tcl_IncrRefCoun
a670: 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a  t(homedir_obj);.
a680: 0a 09 09 69 66 20 28 6c 61 73 74 5f 68 6f 6d 65  ...if (last_home
a690: 64 69 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29  dir_obj != NULL)
a6a0: 20 7b 0a 09 09 09 54 63 6c 5f 44 65 63 72 52 65   {....Tcl_DecrRe
a6b0: 66 43 6f 75 6e 74 28 6c 61 73 74 5f 68 6f 6d 65  fCount(last_home
a6c0: 64 69 72 5f 6f 62 6a 29 3b 0a 09 09 7d 0a 0a 09  dir_obj);...}...
a6d0: 09 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62  .last_homedir_ob
a6e0: 6a 20 3d 20 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b  j = homedir_obj;
a6f0: 0a 09 09 6c 61 73 74 5f 66 73 75 69 64 20 3d 20  ...last_fsuid = 
a700: 66 73 75 69 64 3b 0a 0a 09 09 54 63 6c 5f 49 6e  fsuid;....Tcl_In
a710: 63 72 52 65 66 43 6f 75 6e 74 28 68 6f 6d 65 64  crRefCount(homed
a720: 69 72 5f 6f 62 6a 29 3b 0a 09 7d 0a 0a 20 20 20  ir_obj);..}..   
a730: 20 20 20 20 09 54 63 6c 5f 53 65 74 4f 62 6a 52      .Tcl_SetObjR
a740: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 68 6f  esult(interp, ho
a750: 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 0a 09 54 63  medir_obj);...Tc
a760: 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 68  l_DecrRefCount(h
a770: 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 0a 20 20  omedir_obj);..  
a780: 20 20 20 20 20 20 72 65 74 75 72 6e 28 54 43 4c        return(TCL
a790: 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  _OK);.}..static 
a7a0: 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f 73 69  int tcl_appfs_si
a7b0: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65  mulate_user_fs_e
a7c0: 6e 74 65 72 28 43 6c 69 65 6e 74 44 61 74 61 20  nter(ClientData 
a7d0: 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  cd, Tcl_Interp *
a7e0: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63  interp, int objc
a7f0: 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54  , Tcl_Obj *CONST
a800: 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70 70 66   objv[]) {..appf
a810: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
a820: 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 72 65  fs_enter();...re
a830: 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a  turn(TCL_OK);.}.
a840: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f  .static int tcl_
a850: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
a860: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 43 6c 69  ser_fs_leave(Cli
a870: 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f  entData cd, Tcl_
a880: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20  Interp *interp, 
a890: 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62  int objc, Tcl_Ob
a8a0: 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29  j *CONST objv[])
a8b0: 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61   {..appfs_simula
a8c0: 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65  te_user_fs_leave
a8d0: 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c  ();...return(TCL
a8e0: 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  _OK);.}..static 
a8f0: 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f 67 65  int tcl_appfs_ge
a900: 74 5f 66 73 75 69 64 28 43 6c 69 65 6e 74 44 61  t_fsuid(ClientDa
a910: 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72  ta cd, Tcl_Inter
a920: 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f  p *interp, int o
a930: 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f  bjc, Tcl_Obj *CO
a940: 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 75  NST objv[]) {..u
a950: 69 64 5f 74 20 66 73 75 69 64 3b 0a 0a 09 66 73  id_t fsuid;...fs
a960: 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74 5f  uid = appfs_get_
a970: 66 73 75 69 64 28 29 3b 0a 0a 20 20 20 20 20 20  fsuid();..      
a980: 20 09 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75   .Tcl_SetObjResu
a990: 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e  lt(interp, Tcl_N
a9a0: 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 66 73 75  ewWideIntObj(fsu
a9b0: 69 64 29 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54  id));...return(T
a9c0: 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69  CL_OK);.}..stati
a9d0: 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f  c int tcl_appfs_
a9e0: 67 65 74 5f 66 73 67 69 64 28 43 6c 69 65 6e 74  get_fsgid(Client
a9f0: 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74  Data cd, Tcl_Int
aa00: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74  erp *interp, int
aa10: 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a   objc, Tcl_Obj *
aa20: 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a  CONST objv[]) {.
aa30: 09 67 69 64 5f 74 20 66 73 67 69 64 3b 0a 0a 09  .gid_t fsgid;...
aa40: 66 73 67 69 64 20 3d 20 61 70 70 66 73 5f 67 65  fsgid = appfs_ge
aa50: 74 5f 66 73 67 69 64 28 29 3b 0a 0a 20 20 20 20  t_fsgid();..    
aa60: 20 20 20 09 54 63 6c 5f 53 65 74 4f 62 6a 52 65     .Tcl_SetObjRe
aa70: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c  sult(interp, Tcl
aa80: 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 66  _NewWideIntObj(f
aa90: 73 67 69 64 29 29 3b 0a 0a 09 72 65 74 75 72 6e  sgid));...return
aaa0: 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61  (TCL_OK);.}..sta
aab0: 74 69 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66  tic int tcl_appf
aac0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
aad0: 63 61 63 68 65 5f 66 6c 75 73 68 28 43 6c 69 65  cache_flush(Clie
aae0: 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49  ntData cd, Tcl_I
aaf0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69  nterp *interp, i
ab00: 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a  nt objc, Tcl_Obj
ab10: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20   *CONST objv[]) 
ab20: 7b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a  {..int tcl_ret;.
ab30: 09 69 6e 74 20 6e 65 77 5f 73 69 7a 65 3b 0a 0a  .int new_size;..
ab40: 09 6e 65 77 5f 73 69 7a 65 20 3d 20 2d 31 3b 0a  .new_size = -1;.
ab50: 0a 09 69 66 20 28 6f 62 6a 63 20 3d 3d 20 32 29  ..if (objc == 2)
ab60: 20 7b 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54   {...tcl_ret = T
ab70: 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a  cl_GetIntFromObj
ab80: 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 31 5d  (interp, objv[1]
ab90: 2c 20 26 6e 65 77 5f 73 69 7a 65 29 3b 0a 09 09  , &new_size);...
aba0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
abb0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 72 65 74 75  CL_OK) {....retu
abc0: 72 6e 28 74 63 6c 5f 72 65 74 29 3b 0a 09 09 7d  rn(tcl_ret);...}
abd0: 0a 09 7d 20 65 6c 73 65 20 69 66 20 28 6f 62 6a  ..} else if (obj
abe0: 63 20 3e 20 32 20 7c 7c 20 6f 62 6a 63 20 3c 20  c > 2 || objc < 
abf0: 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20  1) {.           
ac00: 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75       Tcl_WrongNu
ac10: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
ac20: 20 6f 62 6a 76 2c 20 22 3f 6e 65 77 5f 63 61 63   objv, "?new_cac
ac30: 68 65 5f 73 69 7a 65 3f 22 29 3b 0a 09 09 72 65  he_size?");...re
ac40: 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b  turn(TCL_ERROR);
ac50: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f  ..}...appfs_get_
ac60: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
ac70: 66 6c 75 73 68 28 2d 31 2c 20 6e 65 77 5f 73 69  flush(-1, new_si
ac80: 7a 65 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43  ze);...return(TC
ac90: 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  L_OK);.}..static
aca0: 20 69 6e 74 20 41 70 70 66 73 64 5f 49 6e 69 74   int Appfsd_Init
acb0: 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  (Tcl_Interp *int
acc0: 65 72 70 29 20 7b 0a 23 69 66 64 65 66 20 55 53  erp) {.#ifdef US
acd0: 45 5f 54 43 4c 5f 53 54 55 42 53 0a 09 69 66 20  E_TCL_STUBS..if 
ace0: 28 54 63 6c 5f 49 6e 69 74 53 74 75 62 73 28 69  (Tcl_InitStubs(i
acf0: 6e 74 65 72 70 2c 20 54 43 4c 5f 56 45 52 53 49  nterp, TCL_VERSI
ad00: 4f 4e 2c 20 30 29 20 3d 3d 20 30 4c 29 20 7b 0a  ON, 0) == 0L) {.
ad10: 09 09 72 65 74 75 72 6e 28 54 43 4c 5f 45 52 52  ..return(TCL_ERR
ad20: 4f 52 29 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a  OR);..}.#endif..
ad30: 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f  .Tcl_CreateObjCo
ad40: 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61  mmand(interp, "a
ad50: 70 70 66 73 64 3a 3a 67 65 74 5f 68 6f 6d 65 64  ppfsd::get_homed
ad60: 69 72 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67  ir", tcl_appfs_g
ad70: 65 74 5f 68 6f 6d 65 64 69 72 2c 20 4e 55 4c 4c  et_homedir, NULL
ad80: 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72  , NULL);..Tcl_Cr
ad90: 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69  eateObjCommand(i
ada0: 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a  nterp, "appfsd::
adb0: 67 65 74 5f 66 73 75 69 64 22 2c 20 74 63 6c 5f  get_fsuid", tcl_
adc0: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 2c  appfs_get_fsuid,
add0: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54   NULL, NULL);..T
ade0: 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d  cl_CreateObjComm
adf0: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70  and(interp, "app
ae00: 66 73 64 3a 3a 67 65 74 5f 66 73 67 69 64 22 2c  fsd::get_fsgid",
ae10: 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66   tcl_appfs_get_f
ae20: 73 67 69 64 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  sgid, NULL, NULL
ae30: 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62  );..Tcl_CreateOb
ae40: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c  jCommand(interp,
ae50: 20 22 61 70 70 66 73 64 3a 3a 73 69 6d 75 6c 61   "appfsd::simula
ae60: 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72  te_user_fs_enter
ae70: 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 73 69 6d  ", tcl_appfs_sim
ae80: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
ae90: 74 65 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29  ter, NULL, NULL)
aea0: 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a  ;..Tcl_CreateObj
aeb0: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
aec0: 22 61 70 70 66 73 64 3a 3a 73 69 6d 75 6c 61 74  "appfsd::simulat
aed0: 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 22  e_user_fs_leave"
aee0: 2c 20 74 63 6c 5f 61 70 70 66 73 5f 73 69 6d 75  , tcl_appfs_simu
aef0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
af00: 76 65 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b  ve, NULL, NULL);
af10: 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43  ..Tcl_CreateObjC
af20: 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22  ommand(interp, "
af30: 61 70 70 66 73 64 3a 3a 67 65 74 5f 70 61 74 68  appfsd::get_path
af40: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73  _info_cache_flus
af50: 68 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67 65  h", tcl_appfs_ge
af60: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
af70: 65 5f 66 6c 75 73 68 2c 20 4e 55 4c 4c 2c 20 4e  e_flush, NULL, N
af80: 55 4c 4c 29 3b 0a 0a 09 54 63 6c 5f 50 6b 67 50  ULL);...Tcl_PkgP
af90: 72 6f 76 69 64 65 28 69 6e 74 65 72 70 2c 20 22  rovide(interp, "
afa0: 61 70 70 66 73 64 22 2c 20 22 31 2e 30 22 29 3b  appfsd", "1.0");
afb0: 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b  ...return(TCL_OK
afc0: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 48 6f 74 2d  );.}../*. * Hot-
afd0: 72 65 73 74 61 72 74 20 73 75 70 70 6f 72 74 0a  restart support.
afe0: 20 2a 2f 0a 2f 2a 20 49 6e 69 74 69 61 74 65 20   */./* Initiate 
aff0: 61 20 68 6f 74 2d 72 65 73 74 61 72 74 20 2a 2f  a hot-restart */
b000: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
b010: 66 73 5f 68 6f 74 5f 72 65 73 74 61 72 74 28 76  fs_hot_restart(v
b020: 6f 69 64 29 20 7b 0a 09 41 50 50 46 53 5f 44 45  oid) {..APPFS_DE
b030: 42 55 47 28 22 41 73 6b 65 64 20 74 6f 20 69 6e  BUG("Asked to in
b040: 69 74 69 61 74 65 20 68 6f 74 20 72 65 73 74 61  itiate hot resta
b050: 72 74 22 29 3b 0a 0a 09 61 70 70 66 73 5f 74 63  rt");...appfs_tc
b060: 6c 5f 52 65 73 65 74 49 6e 74 65 72 70 73 28 29  l_ResetInterps()
b070: 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61  ;...appfs_get_pa
b080: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c  th_info_cache_fl
b090: 75 73 68 28 2d 31 2c 20 2d 31 29 3b 0a 0a 09 72  ush(-1, -1);...r
b0a0: 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  eturn;.}../*. * 
b0b0: 53 69 67 6e 61 6c 20 68 61 6e 64 6c 65 72 0a 20  Signal handler. 
b0c0: 2a 20 20 20 20 20 20 20 20 20 53 49 47 48 55 50  *         SIGHUP
b0d0: 20 69 6e 69 74 69 61 74 65 73 20 61 20 68 6f 74   initiates a hot
b0e0: 20 72 65 73 74 61 72 74 0a 20 2a 2f 0a 73 74 61   restart. */.sta
b0f0: 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 73  tic void appfs_s
b100: 69 67 6e 61 6c 5f 68 61 6e 64 6c 65 72 28 69 6e  ignal_handler(in
b110: 74 20 73 69 67 29 20 7b 0a 09 2f 2a 20 44 6f 20  t sig) {../* Do 
b120: 6e 6f 74 20 68 61 6e 64 6c 65 20 73 69 67 6e 61  not handle signa
b130: 6c 73 20 75 6e 74 69 6c 20 46 55 53 45 20 68 61  ls until FUSE ha
b140: 73 20 62 65 65 6e 20 73 74 61 72 74 65 64 20 2a  s been started *
b150: 2f 0a 09 69 66 20 28 21 61 70 70 66 73 5f 66 75  /..if (!appfs_fu
b160: 73 65 5f 73 74 61 72 74 65 64 29 20 7b 0a 09 09  se_started) {...
b170: 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 2f 2a 20  return;..}.../* 
b180: 52 65 71 75 65 73 74 20 74 6f 20 70 65 72 66 6f  Request to perfo
b190: 72 6d 20 61 20 22 68 6f 74 22 20 72 65 73 74 61  rm a "hot" resta
b1a0: 72 74 20 2a 2f 0a 09 69 66 20 28 73 69 67 20 3d  rt */..if (sig =
b1b0: 3d 20 53 49 47 48 55 50 29 20 7b 0a 09 09 61 70  = SIGHUP) {...ap
b1c0: 70 66 73 5f 68 6f 74 5f 72 65 73 74 61 72 74 28  pfs_hot_restart(
b1d0: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a  );..}...return;.
b1e0: 7d 0a 0a 2f 2a 0a 20 2a 20 54 65 72 6d 69 6e 61  }../*. * Termina
b1f0: 74 65 20 61 20 74 68 72 65 61 64 0a 20 2a 2f 0a  te a thread. */.
b200: 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66  static void appf
b210: 73 5f 74 65 72 6d 69 6e 61 74 65 5f 69 6e 74 65  s_terminate_inte
b220: 72 70 5f 61 6e 64 5f 74 68 72 65 61 64 28 76 6f  rp_and_thread(vo
b230: 69 64 20 2a 5f 69 6e 74 65 72 70 29 20 7b 0a 09  id *_interp) {..
b240: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
b250: 72 70 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  rp;...APPFS_DEBU
b260: 47 28 22 43 61 6c 6c 65 64 3a 20 5f 69 6e 74 65  G("Called: _inte
b270: 72 70 20 3d 20 25 70 22 2c 20 5f 69 6e 74 65 72  rp = %p", _inter
b280: 70 29 3b 0a 0a 09 69 66 20 28 5f 69 6e 74 65 72  p);...if (_inter
b290: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41  p == NULL) {...A
b2a0: 50 50 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d  PPFS_DEBUG("Term
b2b0: 69 6e 61 74 69 6e 67 20 74 68 72 65 61 64 20 77  inating thread w
b2c0: 69 74 68 20 6e 6f 20 69 6e 74 65 72 70 72 65 74  ith no interpret
b2d0: 65 72 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b  er");....return;
b2e0: 0a 09 7d 0a 0a 09 69 6e 74 65 72 70 20 3d 20 5f  ..}...interp = _
b2f0: 69 6e 74 65 72 70 3b 0a 0a 09 41 50 50 46 53 5f  interp;...APPFS_
b300: 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69  DEBUG("Terminati
b310: 6e 67 20 69 6e 74 65 72 70 72 65 74 65 72 20 64  ng interpreter d
b320: 75 65 20 74 6f 20 74 68 72 65 61 64 20 74 65 72  ue to thread ter
b330: 6d 69 6e 61 74 69 6f 6e 22 29 3b 0a 0a 09 61 70  mination");...ap
b340: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
b350: 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74  ...Tcl_DeleteInt
b360: 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a  erp(interp);..).
b370: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
b380: 74 63 6c 28 0a 09 09 54 63 6c 5f 46 69 6e 61 6c  tcl(...Tcl_Final
b390: 69 7a 65 54 68 72 65 61 64 28 29 3b 0a 09 29 0a  izeThread();..).
b3a0: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a  ..return;.}../*.
b3b0: 20 2a 20 43 6f 6d 6d 61 6e 64 2d 6c 69 6e 65 20   * Command-line 
b3c0: 70 61 72 73 69 6e 67 20 74 6f 6f 6c 73 0a 20 2a  parsing tools. *
b3d0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  /.static void ap
b3e0: 70 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28 46  pfs_print_help(F
b3f0: 49 4c 45 20 2a 63 68 61 6e 6e 65 6c 29 20 7b 0a  ILE *channel) {.
b400: 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c  .fprintf(channel
b410: 2c 20 22 55 73 61 67 65 3a 20 7b 61 70 70 66 73  , "Usage: {appfs
b420: 64 7c 6d 6f 75 6e 74 2e 61 70 70 66 73 7d 20 5b  d|mount.appfs} [
b430: 2d 6f 20 3c 6f 70 74 69 6f 6e 3e 5d 20 5b 2d 64  -o <option>] [-d
b440: 66 73 68 5d 20 3c 63 61 63 68 65 64 69 72 3e 20  fsh] <cachedir> 
b450: 3c 6d 6f 75 6e 74 70 6f 69 6e 74 3e 5c 6e 22 29  <mountpoint>\n")
b460: 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e  ;..fprintf(chann
b470: 65 6c 2c 20 22 5c 6e 22 29 3b 0a 09 66 70 72 69  el, "\n");..fpri
b480: 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 4f 70  ntf(channel, "Op
b490: 74 69 6f 6e 73 3a 5c 6e 22 29 3b 0a 09 66 70 72  tions:\n");..fpr
b4a0: 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20  intf(channel, " 
b4b0: 20 2d 64 20 20 20 20 20 20 20 20 20 20 20 20 20   -d             
b4c0: 20 45 6e 61 62 6c 65 20 46 55 53 45 20 64 65 62   Enable FUSE deb
b4d0: 75 67 20 6d 6f 64 65 2e 5c 6e 22 29 3b 0a 09 66  ug mode.\n");..f
b4e0: 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20  printf(channel, 
b4f0: 22 20 20 2d 66 20 20 20 20 20 20 20 20 20 20 20  "  -f           
b500: 20 20 20 52 75 6e 20 69 6e 20 66 6f 72 65 67 72     Run in foregr
b510: 6f 75 6e 64 2e 5c 6e 22 29 3b 0a 09 66 70 72 69  ound.\n");..fpri
b520: 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20 20  ntf(channel, "  
b530: 2d 73 20 20 20 20 20 20 20 20 20 20 20 20 20 20  -s              
b540: 45 6e 61 62 6c 65 20 73 69 6e 67 6c 65 20 74 68  Enable single th
b550: 72 65 61 64 65 64 20 6d 6f 64 65 2e 5c 6e 22 29  readed mode.\n")
b560: 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e  ;..fprintf(chann
b570: 65 6c 2c 20 22 20 20 2d 68 20 20 20 20 20 20 20  el, "  -h       
b580: 20 20 20 20 20 20 20 47 69 76 65 20 74 68 69 73         Give this
b590: 20 68 65 6c 70 2e 5c 6e 22 29 3b 0a 09 66 70 72   help.\n");..fpr
b5a0: 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20  intf(channel, " 
b5b0: 20 2d 6f 20 6e 6f 74 68 72 65 61 64 73 20 20 20   -o nothreads   
b5c0: 20 45 6e 61 62 6c 65 20 73 69 6e 67 6c 65 20 74   Enable single t
b5d0: 68 72 65 61 64 65 64 20 6d 6f 64 65 2e 5c 6e 22  hreaded mode.\n"
b5e0: 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e  );..fprintf(chan
b5f0: 6e 65 6c 2c 20 22 20 20 2d 6f 20 61 6c 6c 6f 77  nel, "  -o allow
b600: 5f 6f 74 68 65 72 20 20 41 6c 6c 6f 77 20 6f 74  _other  Allow ot
b610: 68 65 72 20 75 73 65 72 73 20 74 6f 20 61 63 63  her users to acc
b620: 65 73 73 20 74 68 69 73 20 6d 6f 75 6e 74 70 6f  ess this mountpo
b630: 69 6e 74 20 28 64 65 66 61 75 6c 74 5c 6e 22 29  int (default\n")
b640: 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e  ;..fprintf(chann
b650: 65 6c 2c 20 22 20 20 20 20 20 20 20 20 20 20 20  el, "           
b660: 20 20 20 20 20 20 20 69 66 20 72 6f 6f 74 29 2e         if root).
b670: 5c 6e 22 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a  \n");...return;.
b680: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
b690: 70 66 73 5f 6f 70 74 5f 70 61 72 73 65 28 69 6e  pfs_opt_parse(in
b6a0: 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a 61  t argc, char **a
b6b0: 72 67 76 2c 20 20 73 74 72 75 63 74 20 66 75 73  rgv,  struct fus
b6c0: 65 5f 61 72 67 73 20 2a 61 72 67 73 29 20 7b 0a  e_args *args) {.
b6d0: 09 69 6e 74 20 63 68 3b 0a 09 63 68 61 72 20 2a  .int ch;..char *
b6e0: 6f 70 74 73 74 72 2c 20 2a 6f 70 74 73 74 72 5f  optstr, *optstr_
b6f0: 6e 65 78 74 2c 20 2a 6f 70 74 73 74 72 5f 73 3b  next, *optstr_s;
b700: 0a 09 63 68 61 72 20 66 61 6b 65 5f 61 72 67 5b  ..char fake_arg[
b710: 33 5d 20 3d 20 7b 27 2d 27 2c 20 30 2c 20 30 7d  3] = {'-', 0, 0}
b720: 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 44 65 66 61 75  ;.../*.. * Defau
b730: 6c 74 20 76 61 6c 75 65 73 0a 09 20 2a 2f 0a 23  lt values.. */.#
b740: 69 66 64 65 66 20 54 43 4c 5f 54 48 52 45 41 44  ifdef TCL_THREAD
b750: 53 0a 09 61 70 70 66 73 5f 74 68 72 65 61 64 65  S..appfs_threade
b760: 64 5f 74 63 6c 20 3d 20 31 3b 0a 23 65 6c 73 65  d_tcl = 1;.#else
b770: 0a 09 61 70 70 66 73 5f 74 68 72 65 61 64 65 64  ..appfs_threaded
b780: 5f 74 63 6c 20 3d 20 30 3b 0a 23 65 6e 64 69 66  _tcl = 0;.#endif
b790: 0a 0a 09 2f 2a 2a 0a 09 20 2a 2a 20 41 64 64 20  .../**.. ** Add 
b7a0: 46 55 53 45 20 61 72 67 75 6d 65 6e 74 73 20 77  FUSE arguments w
b7b0: 68 69 63 68 20 77 65 20 61 6c 77 61 79 73 20 73  hich we always s
b7c0: 75 70 70 6c 79 0a 09 20 2a 2a 2f 0a 09 66 75 73  upply.. **/..fus
b7d0: 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72  e_opt_add_arg(ar
b7e0: 67 73 2c 20 22 2d 6f 64 65 66 61 75 6c 74 5f 70  gs, "-odefault_p
b7f0: 65 72 6d 69 73 73 69 6f 6e 73 2c 66 73 6e 61 6d  ermissions,fsnam
b800: 65 3d 61 70 70 66 73 2c 73 75 62 74 79 70 65 3d  e=appfs,subtype=
b810: 61 70 70 66 73 64 2c 75 73 65 5f 69 6e 6f 2c 65  appfsd,use_ino,e
b820: 6e 74 72 79 5f 74 69 6d 65 6f 75 74 3d 30 2c 61  ntry_timeout=0,a
b830: 74 74 72 5f 74 69 6d 65 6f 75 74 3d 30 2c 62 69  ttr_timeout=0,bi
b840: 67 5f 77 72 69 74 65 73 2c 69 6e 74 72 2c 68 61  g_writes,intr,ha
b850: 72 64 5f 72 65 6d 6f 76 65 22 29 3b 0a 0a 09 69  rd_remove");...i
b860: 66 20 28 67 65 74 75 69 64 28 29 20 3d 3d 20 30  f (getuid() == 0
b870: 29 20 7b 0a 09 09 66 75 73 65 5f 6f 70 74 5f 70  ) {...fuse_opt_p
b880: 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c  arse(args, NULL,
b890: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09   NULL, NULL);...
b8a0: 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67  fuse_opt_add_arg
b8b0: 28 61 72 67 73 2c 20 22 2d 6f 61 6c 6c 6f 77 5f  (args, "-oallow_
b8c0: 6f 74 68 65 72 22 29 3b 0a 0a 09 09 2f 2a 0a 09  other");..../*..
b8d0: 09 20 2a 20 54 68 69 73 20 73 68 6f 75 6c 64 20  . * This should 
b8e0: 67 65 6e 65 72 61 6c 6c 79 20 62 65 20 61 76 6f  generally be avo
b8f0: 69 64 65 64 2c 20 62 75 74 20 69 66 20 74 68 65  ided, but if the
b900: 72 65 20 61 72 65 20 73 65 63 75 72 69 74 79 0a  re are security.
b910: 09 09 20 2a 20 63 6f 6e 63 65 72 6e 73 20 73 75  .. * concerns su
b920: 69 64 20 63 61 6e 20 62 65 20 64 69 73 61 62 6c  id can be disabl
b930: 65 64 20 63 6f 6d 70 6c 65 74 65 6c 79 20 6f 6e  ed completely on
b940: 20 74 68 65 20 63 6f 6d 6d 61 6e 64 6c 69 6e 65   the commandline
b950: 0a 09 09 20 2a 2f 0a 09 09 66 75 73 65 5f 6f 70  ... */...fuse_op
b960: 74 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55  t_parse(args, NU
b970: 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b  LL, NULL, NULL);
b980: 0a 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f  ...fuse_opt_add_
b990: 61 72 67 28 61 72 67 73 2c 20 22 2d 6f 73 75 69  arg(args, "-osui
b9a0: 64 22 29 3b 0a 09 7d 0a 0a 09 77 68 69 6c 65 20  d");..}...while 
b9b0: 28 28 63 68 20 3d 20 67 65 74 6f 70 74 28 61 72  ((ch = getopt(ar
b9c0: 67 63 2c 20 61 72 67 76 2c 20 22 64 66 73 68 76  gc, argv, "dfshv
b9d0: 6f 3a 22 29 29 20 21 3d 20 2d 31 29 20 7b 0a 09  o:")) != -1) {..
b9e0: 09 73 77 69 74 63 68 20 28 63 68 29 20 7b 0a 09  .switch (ch) {..
b9f0: 09 09 63 61 73 65 20 27 76 27 3a 0a 09 09 09 09  ..case 'v':.....
ba00: 2f 2a 20 49 67 6e 6f 72 65 64 20 2a 2f 0a 09 09  /* Ignored */...
ba10: 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65  ..break;....case
ba20: 20 27 6f 27 3a 0a 09 09 09 09 6f 70 74 73 74 72   'o':.....optstr
ba30: 5f 6e 65 78 74 20 3d 20 6f 70 74 73 74 72 20 3d  _next = optstr =
ba40: 20 6f 70 74 73 74 72 5f 73 20 3d 20 73 74 72 64   optstr_s = strd
ba50: 75 70 28 6f 70 74 61 72 67 29 3b 0a 0a 09 09 09  up(optarg);.....
ba60: 09 77 68 69 6c 65 20 28 31 29 20 7b 0a 09 09 09  .while (1) {....
ba70: 09 09 6f 70 74 73 74 72 20 3d 20 6f 70 74 73 74  ..optstr = optst
ba80: 72 5f 6e 65 78 74 3b 0a 0a 09 09 09 09 09 69 66  r_next;.......if
ba90: 20 28 21 6f 70 74 73 74 72 29 20 7b 0a 09 09 09   (!optstr) {....
baa0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 09 7d  ...break;......}
bab0: 0a 0a 09 09 09 09 09 6f 70 74 73 74 72 5f 6e 65  .......optstr_ne
bac0: 78 74 20 3d 20 73 74 72 63 68 72 28 6f 70 74 73  xt = strchr(opts
bad0: 74 72 2c 20 27 2c 27 29 3b 0a 09 09 09 09 09 69  tr, ',');......i
bae0: 66 20 28 6f 70 74 73 74 72 5f 6e 65 78 74 29 20  f (optstr_next) 
baf0: 7b 0a 09 09 09 09 09 09 2a 6f 70 74 73 74 72 5f  {.......*optstr_
bb00: 6e 65 78 74 20 3d 20 27 5c 30 27 3b 0a 09 09 09  next = '\0';....
bb10: 09 09 09 6f 70 74 73 74 72 5f 6e 65 78 74 2b 2b  ...optstr_next++
bb20: 3b 0a 09 09 09 09 09 7d 0a 0a 09 09 09 09 09 69  ;......}.......i
bb30: 66 20 28 73 74 72 63 6d 70 28 6f 70 74 73 74 72  f (strcmp(optstr
bb40: 2c 20 22 6e 6f 74 68 72 65 61 64 73 22 29 20 3d  , "nothreads") =
bb50: 3d 20 30 29 20 7b 0a 09 09 09 09 09 09 41 50 50  = 0) {.......APP
bb60: 46 53 5f 44 45 42 55 47 28 22 50 61 73 73 69 6e  FS_DEBUG("Passin
bb70: 67 20 6f 70 74 69 6f 6e 20 74 6f 20 46 55 53 45  g option to FUSE
bb80: 3a 20 2d 73 22 29 3b 0a 0a 09 09 09 09 09 09 66  : -s");........f
bb90: 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72  use_opt_parse(ar
bba0: 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20  gs, NULL, NULL, 
bbb0: 4e 55 4c 4c 29 3b 0a 09 09 09 09 09 09 66 75 73  NULL);.......fus
bbc0: 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72  e_opt_add_arg(ar
bbd0: 67 73 2c 20 22 2d 73 22 29 3b 0a 0a 09 09 09 09  gs, "-s");......
bbe0: 09 09 61 70 70 66 73 5f 74 68 72 65 61 64 65 64  ..appfs_threaded
bbf0: 5f 74 63 6c 20 3d 20 30 3b 0a 09 09 09 09 09 7d  _tcl = 0;......}
bc00: 20 65 6c 73 65 20 69 66 20 28 73 74 72 63 6d 70   else if (strcmp
bc10: 28 6f 70 74 73 74 72 2c 20 22 61 6c 6c 6f 77 5f  (optstr, "allow_
bc20: 6f 74 68 65 72 22 29 20 3d 3d 20 30 29 20 7b 0a  other") == 0) {.
bc30: 09 09 09 09 09 09 41 50 50 46 53 5f 44 45 42 55  ......APPFS_DEBU
bc40: 47 28 22 50 61 73 73 69 6e 67 20 6f 70 74 69 6f  G("Passing optio
bc50: 6e 20 74 6f 20 46 55 53 45 3a 20 2d 6f 20 61 6c  n to FUSE: -o al
bc60: 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 0a 09 09  low_other");....
bc70: 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 70 61 72  ....fuse_opt_par
bc80: 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e  se(args, NULL, N
bc90: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09 09 09  ULL, NULL);.....
bca0: 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61  ..fuse_opt_add_a
bcb0: 72 67 28 61 72 67 73 2c 20 22 2d 6f 61 6c 6c 6f  rg(args, "-oallo
bcc0: 77 5f 6f 74 68 65 72 22 29 3b 0a 09 09 09 09 09  w_other");......
bcd0: 7d 20 65 6c 73 65 20 69 66 20 28 73 74 72 63 6d  } else if (strcm
bce0: 70 28 6f 70 74 73 74 72 2c 20 22 72 77 22 29 20  p(optstr, "rw") 
bcf0: 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09 09 2f 2a  == 0) {......./*
bd00: 20 49 67 6e 6f 72 65 64 20 2a 2f 0a 09 09 09 09   Ignored */.....
bd10: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 09 09  .} else {.......
bd20: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
bd30: 22 61 70 70 66 73 64 3a 20 69 6e 76 61 6c 69 64  "appfsd: invalid
bd40: 20 6f 70 74 69 6f 6e 3a 20 5c 22 2d 6f 20 25 73   option: \"-o %s
bd50: 5c 22 5c 6e 22 2c 20 6f 70 74 73 74 72 29 3b 0a  \"\n", optstr);.
bd60: 0a 09 09 09 09 09 09 66 72 65 65 28 6f 70 74 73  .......free(opts
bd70: 74 72 5f 73 29 3b 0a 0a 09 09 09 09 09 09 72 65  tr_s);........re
bd80: 74 75 72 6e 28 31 29 3b 0a 09 09 09 09 09 7d 0a  turn(1);......}.
bd90: 09 09 09 09 7d 0a 0a 09 09 09 09 66 72 65 65 28  ....}......free(
bda0: 6f 70 74 73 74 72 5f 73 29 3b 0a 0a 09 09 09 09  optstr_s);......
bdb0: 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27  break;....case '
bdc0: 64 27 3a 0a 09 09 09 63 61 73 65 20 27 66 27 3a  d':....case 'f':
bdd0: 0a 09 09 09 63 61 73 65 20 27 73 27 3a 0a 09 09  ....case 's':...
bde0: 09 09 69 66 20 28 63 68 20 3d 3d 20 27 73 27 29  ..if (ch == 's')
bdf0: 20 7b 0a 09 09 09 09 09 61 70 70 66 73 5f 74 68   {......appfs_th
be00: 72 65 61 64 65 64 5f 74 63 6c 20 3d 20 30 3b 0a  readed_tcl = 0;.
be10: 09 09 09 09 7d 0a 0a 09 09 09 09 66 61 6b 65 5f  ....}......fake_
be20: 61 72 67 5b 31 5d 20 3d 20 63 68 3b 0a 0a 09 09  arg[1] = ch;....
be30: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 50  ..APPFS_DEBUG("P
be40: 61 73 73 69 6e 67 20 6f 70 74 69 6f 6e 20 74 6f  assing option to
be50: 20 46 55 53 45 3a 20 25 73 22 2c 20 66 61 6b 65   FUSE: %s", fake
be60: 5f 61 72 67 29 3b 0a 0a 09 09 09 09 66 75 73 65  _arg);......fuse
be70: 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67 73 2c  _opt_parse(args,
be80: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c   NULL, NULL, NUL
be90: 4c 29 3b 0a 09 09 09 09 66 75 73 65 5f 6f 70 74  L);.....fuse_opt
bea0: 5f 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20 66  _add_arg(args, f
beb0: 61 6b 65 5f 61 72 67 29 3b 0a 09 09 09 09 62 72  ake_arg);.....br
bec0: 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 68 27  eak;....case 'h'
bed0: 3a 0a 09 09 09 09 61 70 70 66 73 5f 70 72 69 6e  :.....appfs_prin
bee0: 74 5f 68 65 6c 70 28 73 74 64 6f 75 74 29 3b 0a  t_help(stdout);.
bef0: 0a 09 09 09 09 72 65 74 75 72 6e 28 2d 31 29 3b  .....return(-1);
bf00: 0a 09 09 09 63 61 73 65 20 27 3a 27 3a 0a 09 09  ....case ':':...
bf10: 09 63 61 73 65 20 27 3f 27 3a 0a 09 09 09 64 65  .case '?':....de
bf20: 66 61 75 6c 74 3a 0a 09 09 09 09 61 70 70 66 73  fault:.....appfs
bf30: 5f 70 72 69 6e 74 5f 68 65 6c 70 28 73 74 64 65  _print_help(stde
bf40: 72 72 29 3b 0a 0a 09 09 09 09 72 65 74 75 72 6e  rr);......return
bf50: 28 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 69 66  (1);...}..}...if
bf60: 20 28 28 6f 70 74 69 6e 64 20 2b 20 32 29 20 21   ((optind + 2) !
bf70: 3d 20 61 72 67 63 29 20 7b 0a 09 09 69 66 20 28  = argc) {...if (
bf80: 28 6f 70 74 69 6e 64 20 2b 20 32 29 20 3c 20 61  (optind + 2) < a
bf90: 72 67 63 29 20 7b 0a 09 09 09 66 70 72 69 6e 74  rgc) {....fprint
bfa0: 66 28 73 74 64 65 72 72 2c 20 22 54 6f 6f 20 6d  f(stderr, "Too m
bfb0: 61 6e 79 20 61 72 67 75 6d 65 6e 74 73 5c 6e 22  any arguments\n"
bfc0: 29 3b 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09  );...} else {...
bfd0: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
bfe0: 20 22 4d 69 73 73 69 6e 67 20 63 61 63 68 65 64   "Missing cached
bff0: 69 72 20 6f 72 20 6d 6f 75 6e 74 70 6f 69 6e 74  ir or mountpoint
c000: 5c 6e 22 29 3b 0a 09 09 7d 0a 0a 09 09 61 70 70  \n");...}....app
c010: 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28 73 74  fs_print_help(st
c020: 64 65 72 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e  derr);....return
c030: 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  (1);..}.../*.. *
c040: 20 53 65 74 20 63 61 63 68 65 20 64 69 72 20 61   Set cache dir a
c050: 73 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74  s first argument
c060: 20 28 74 68 65 20 22 64 65 76 69 63 65 22 2c 20   (the "device", 
c070: 65 73 73 65 6e 74 69 61 6c 6c 79 29 0a 09 20 2a  essentially).. *
c080: 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65 64 69  /..appfs_cachedi
c090: 72 20 3d 20 61 72 67 76 5b 6f 70 74 69 6e 64 5d  r = argv[optind]
c0a0: 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 50 61 73 73 20  ;.../*.. * Pass 
c0b0: 74 68 65 20 72 65 6d 61 69 6e 69 6e 67 20 61 72  the remaining ar
c0c0: 67 75 6d 65 6e 74 20 74 6f 20 46 55 53 45 20 61  gument to FUSE a
c0d0: 73 20 74 68 65 20 64 69 72 65 63 74 6f 72 79 0a  s the directory.
c0e0: 09 20 2a 2f 0a 09 66 75 73 65 5f 6f 70 74 5f 70  . */..fuse_opt_p
c0f0: 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c  arse(args, NULL,
c100: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 66   NULL, NULL);..f
c110: 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28  use_opt_add_arg(
c120: 61 72 67 73 2c 20 61 72 67 76 5b 6f 70 74 69 6e  args, argv[optin
c130: 64 20 2b 20 31 5d 29 3b 0a 0a 09 72 65 74 75 72  d + 1]);...retur
c140: 6e 28 30 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 20 2a 20  n(0);.}.../*. * 
c150: 46 55 53 45 20 6f 70 65 72 61 74 69 6f 6e 73 20  FUSE operations 
c160: 73 74 72 75 63 74 75 72 65 0a 20 2a 2f 0a 73 74  structure. */.st
c170: 61 74 69 63 20 73 74 72 75 63 74 20 66 75 73 65  atic struct fuse
c180: 5f 6f 70 65 72 61 74 69 6f 6e 73 20 61 70 70 66  _operations appf
c190: 73 5f 6f 70 65 72 61 74 69 6f 6e 73 20 3d 20 7b  s_operations = {
c1a0: 0a 09 2e 67 65 74 61 74 74 72 20 20 20 3d 20 61  ...getattr   = a
c1b0: 70 70 66 73 5f 66 75 73 65 5f 67 65 74 61 74 74  ppfs_fuse_getatt
c1c0: 72 2c 0a 09 2e 72 65 61 64 64 69 72 20 20 20 3d  r,...readdir   =
c1d0: 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64   appfs_fuse_read
c1e0: 64 69 72 2c 0a 09 2e 72 65 61 64 6c 69 6e 6b 20  dir,...readlink 
c1f0: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65   = appfs_fuse_re
c200: 61 64 6c 69 6e 6b 2c 0a 09 2e 6f 70 65 6e 20 20  adlink,...open  
c210: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
c220: 5f 6f 70 65 6e 2c 0a 09 2e 72 65 6c 65 61 73 65  _open,...release
c230: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
c240: 63 6c 6f 73 65 2c 0a 09 2e 72 65 61 64 20 20 20  close,...read   
c250: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
c260: 72 65 61 64 2c 0a 09 2e 77 72 69 74 65 20 20 20  read,...write   
c270: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 77    = appfs_fuse_w
c280: 72 69 74 65 2c 0a 09 2e 6d 6b 6e 6f 64 20 20 20  rite,...mknod   
c290: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 6d    = appfs_fuse_m
c2a0: 6b 6e 6f 64 2c 0a 09 2e 63 72 65 61 74 65 20 20  knod,...create  
c2b0: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 63    = appfs_fuse_c
c2c0: 72 65 61 74 65 2c 0a 09 2e 74 72 75 6e 63 61 74  reate,...truncat
c2d0: 65 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f  e  = appfs_fuse_
c2e0: 74 72 75 6e 63 61 74 65 2c 0a 09 2e 75 6e 6c 69  truncate,...unli
c2f0: 6e 6b 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75  nk    = appfs_fu
c300: 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72 2c  se_unlink_rmdir,
c310: 0a 09 2e 72 6d 64 69 72 20 20 20 20 20 3d 20 61  ...rmdir     = a
c320: 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b  ppfs_fuse_unlink
c330: 5f 72 6d 64 69 72 2c 0a 09 2e 6d 6b 64 69 72 20  _rmdir,...mkdir 
c340: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
c350: 5f 6d 6b 64 69 72 2c 0a 09 2e 63 68 6d 6f 64 20  _mkdir,...chmod 
c360: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
c370: 5f 63 68 6d 6f 64 2c 0a 09 2e 73 79 6d 6c 69 6e  _chmod,...symlin
c380: 6b 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  k   = appfs_fuse
c390: 5f 73 79 6d 6c 69 6e 6b 2c 0a 7d 3b 0a 0a 2f 2a  _symlink,.};../*
c3a0: 0a 20 2a 20 45 6e 74 72 79 20 70 6f 69 6e 74 20  . * Entry point 
c3b0: 69 6e 74 6f 20 74 68 69 73 20 70 72 6f 67 72 61  into this progra
c3c0: 6d 2e 0a 20 2a 2f 0a 69 6e 74 20 6d 61 69 6e 28  m.. */.int main(
c3d0: 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a  int argc, char *
c3e0: 2a 61 72 67 76 29 20 7b 0a 09 54 63 6c 5f 49 6e  *argv) {..Tcl_In
c3f0: 74 65 72 70 20 2a 74 65 73 74 5f 69 6e 74 65 72  terp *test_inter
c400: 70 3b 0a 09 63 68 61 72 20 2a 74 65 73 74 5f 69  p;..char *test_i
c410: 6e 74 65 72 70 5f 65 72 72 6f 72 3b 0a 09 73 74  nterp_error;..st
c420: 72 75 63 74 20 66 75 73 65 5f 61 72 67 73 20 61  ruct fuse_args a
c430: 72 67 73 20 3d 20 46 55 53 45 5f 41 52 47 53 5f  rgs = FUSE_ARGS_
c440: 49 4e 49 54 28 30 2c 20 4e 55 4c 4c 29 3b 0a 09  INIT(0, NULL);..
c450: 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 2c  int pthread_ret,
c460: 20 61 6f 70 5f 72 65 74 3b 0a 09 76 6f 69 64 20   aop_ret;..void 
c470: 2a 73 69 67 6e 61 6c 5f 72 65 74 3b 0a 09 63 68  *signal_ret;..ch
c480: 61 72 20 2a 61 72 67 76 30 3b 0a 0a 09 2f 2a 0a  ar *argv0;.../*.
c490: 09 20 2a 20 53 6b 69 70 20 70 61 73 73 65 64 20  . * Skip passed 
c4a0: 70 72 6f 67 72 61 6d 20 6e 61 6d 65 0a 09 20 2a  program name.. *
c4b0: 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20 30  /..if (argc == 0
c4c0: 20 7c 7c 20 61 72 67 76 20 3d 3d 20 4e 55 4c 4c   || argv == NULL
c4d0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 31 29 3b  ) {...return(1);
c4e0: 0a 09 7d 0a 0a 09 61 72 67 76 30 20 3d 20 61 72  ..}...argv0 = ar
c4f0: 67 76 5b 30 5d 3b 0a 0a 09 61 72 67 63 2d 2d 3b  gv[0];...argc--;
c500: 0a 09 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09  ..argv++;.../*..
c510: 20 2a 20 53 65 74 20 61 70 70 72 6f 70 72 69 61   * Set appropria
c520: 74 65 20 75 6d 61 73 6b 0a 09 20 2a 2f 0a 09 75  te umask.. */..u
c530: 6d 61 73 6b 28 30 32 32 29 3b 0a 0a 09 2f 2a 0a  mask(022);.../*.
c540: 09 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76  . * Set global v
c550: 61 72 69 61 62 6c 65 73 2c 20 74 68 65 73 65 20  ariables, these 
c560: 73 68 6f 75 6c 64 20 62 65 20 63 6f 6e 66 69 67  should be config
c570: 75 72 61 74 69 6f 6e 20 6f 70 74 69 6f 6e 73 2e  uration options.
c580: 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63  .. */..appfs_cac
c590: 68 65 64 69 72 20 3d 20 41 50 50 46 53 5f 43 41  hedir = APPFS_CA
c5a0: 43 48 45 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20 2a  CHEDIR;.../*.. *
c5b0: 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69   Set global vari
c5c0: 61 62 6c 65 20 66 6f 72 20 22 62 6f 6f 74 20 74  able for "boot t
c5d0: 69 6d 65 22 20 74 6f 20 73 65 74 20 61 20 74 69  ime" to set a ti
c5e0: 6d 65 20 6f 6e 20 64 69 72 65 63 74 6f 72 69 65  me on directorie
c5f0: 73 0a 09 20 2a 20 74 68 61 74 20 77 65 20 66 61  s.. * that we fa
c600: 6b 65 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f  ke... */..appfs_
c610: 62 6f 6f 74 74 69 6d 65 20 3d 20 74 69 6d 65 28  boottime = time(
c620: 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20  NULL);.../*.. * 
c630: 52 65 67 69 73 74 65 72 20 22 73 68 61 31 22 20  Register "sha1" 
c640: 61 6e 64 20 22 61 70 70 66 73 64 22 20 70 61 63  and "appfsd" pac
c650: 6b 61 67 65 20 77 69 74 68 20 6c 69 62 74 63 6c  kage with libtcl
c660: 20 73 6f 20 74 68 61 74 20 61 6e 79 20 6e 65 77   so that any new
c670: 0a 09 20 2a 20 69 6e 74 65 72 70 72 65 74 65 72  .. * interpreter
c680: 73 20 63 72 65 61 74 65 64 20 28 77 68 69 63 68  s created (which
c690: 20 61 72 65 20 64 6f 6e 65 20 64 79 6e 61 6d 69   are done dynami
c6a0: 63 61 6c 6c 79 20 62 79 20 46 55 53 45 29 20 63  cally by FUSE) c
c6b0: 61 6e 20 68 61 76 65 0a 09 20 2a 20 74 68 65 20  an have.. * the 
c6c0: 61 70 70 72 6f 70 72 69 61 74 65 20 63 6f 6e 66  appropriate conf
c6d0: 69 67 75 72 61 74 69 6f 6e 20 64 6f 6e 65 20 61  iguration done a
c6e0: 75 74 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 09 20  utomatically... 
c6f0: 2a 2f 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61  */..Tcl_StaticPa
c700: 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 73 68 61  ckage(NULL, "sha
c710: 31 22 2c 20 53 68 61 31 5f 49 6e 69 74 2c 20 4e  1", Sha1_Init, N
c720: 55 4c 4c 29 3b 0a 09 54 63 6c 5f 53 74 61 74 69  ULL);..Tcl_Stati
c730: 63 50 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22  cPackage(NULL, "
c740: 61 70 70 66 73 64 22 2c 20 41 70 70 66 73 64 5f  appfsd", Appfsd_
c750: 49 6e 69 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 2f  Init, NULL);.../
c760: 2a 0a 09 20 2a 20 43 72 65 61 74 65 20 61 20 74  *.. * Create a t
c770: 68 72 65 61 64 2d 73 70 65 63 69 66 69 63 2d 64  hread-specific-d
c780: 61 74 61 20 28 54 53 44 29 20 6b 65 79 20 66 6f  ata (TSD) key fo
c790: 72 20 65 61 63 68 20 74 68 72 65 61 64 20 74 6f  r each thread to
c7a0: 20 72 65 66 65 72 0a 09 20 2a 20 74 6f 20 69 74   refer.. * to it
c7b0: 73 20 6f 77 6e 20 54 63 6c 20 69 6e 74 65 72 70  s own Tcl interp
c7c0: 72 65 74 65 72 2e 20 20 54 63 6c 20 69 6e 74 65  reter.  Tcl inte
c7d0: 72 70 72 65 74 65 72 73 20 6d 75 73 74 20 62 65  rpreters must be
c7e0: 20 75 6e 69 71 75 65 20 70 65 72 0a 09 20 2a 20   unique per.. * 
c7f0: 74 68 72 65 61 64 20 61 6e 64 20 6e 65 77 20 74  thread and new t
c800: 68 72 65 61 64 73 20 61 72 65 20 64 79 6e 61 6d  hreads are dynam
c810: 69 63 61 6c 6c 79 20 63 72 65 61 74 65 64 20 62  ically created b
c820: 79 20 46 55 53 45 2e 0a 09 20 2a 2f 0a 09 70 74  y FUSE... */..pt
c830: 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72  hread_ret = pthr
c840: 65 61 64 5f 6b 65 79 5f 63 72 65 61 74 65 28 26  ead_key_create(&
c850: 69 6e 74 65 72 70 4b 65 79 2c 20 61 70 70 66 73  interpKey, appfs
c860: 5f 74 65 72 6d 69 6e 61 74 65 5f 69 6e 74 65 72  _terminate_inter
c870: 70 5f 61 6e 64 5f 74 68 72 65 61 64 29 3b 0a 09  p_and_thread);..
c880: 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20  if (pthread_ret 
c890: 21 3d 20 30 29 20 7b 0a 09 09 66 70 72 69 6e 74  != 0) {...fprint
c8a0: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
c8b0: 65 20 74 6f 20 63 72 65 61 74 65 20 54 53 44 20  e to create TSD 
c8c0: 6b 65 79 20 66 6f 72 20 54 63 6c 2e 20 20 41 62  key for Tcl.  Ab
c8d0: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09  orting.\n");....
c8e0: 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09  return(1);..}...
c8f0: 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61 6c 6c 79 20  /*.. * Manually 
c900: 73 70 65 63 69 66 79 20 63 61 63 68 65 20 64 69  specify cache di
c910: 72 65 63 74 6f 72 79 2c 20 77 69 74 68 6f 75 74  rectory, without
c920: 20 46 55 53 45 20 63 61 6c 6c 62 61 63 6b 0a 09   FUSE callback..
c930: 20 2a 20 54 68 69 73 20 6f 70 74 69 6f 6e 20 6f   * This option o
c940: 6e 6c 79 20 77 6f 72 6b 73 20 77 68 65 6e 20 6e  nly works when n
c950: 6f 74 20 75 73 69 6e 67 20 46 55 53 45 2c 20 73  ot using FUSE, s
c960: 69 6e 63 65 20 77 65 0a 09 20 2a 20 64 6f 20 6e  ince we.. * do n
c970: 6f 74 20 70 72 6f 63 65 73 73 20 69 74 20 77 69  ot process it wi
c980: 74 68 20 46 55 53 45 73 20 6f 70 74 69 6f 6e 20  th FUSEs option 
c990: 70 72 6f 63 65 73 73 69 6e 67 2e 0a 09 20 2a 2f  processing... */
c9a0: 0a 09 69 66 20 28 61 72 67 63 20 3e 3d 20 32 29  ..if (argc >= 2)
c9b0: 20 7b 0a 09 09 69 66 20 28 73 74 72 63 6d 70 28   {...if (strcmp(
c9c0: 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 63 61 63 68  argv[0], "--cach
c9d0: 65 64 69 72 22 29 20 3d 3d 20 30 29 20 7b 0a 09  edir") == 0) {..
c9e0: 09 09 61 70 70 66 73 5f 63 61 63 68 65 64 69 72  ..appfs_cachedir
c9f0: 20 3d 20 73 74 72 64 75 70 28 61 72 67 76 5b 31   = strdup(argv[1
ca00: 5d 29 3b 0a 0a 09 09 09 61 72 67 63 20 2d 3d 20  ]);.....argc -= 
ca10: 32 3b 0a 09 09 09 61 72 67 76 20 2b 3d 20 32 3b  2;....argv += 2;
ca20: 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  ...}..}.../*.. *
ca30: 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 2c 20 66   SQLite3 mode, f
ca40: 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77 20 53  or running raw S
ca50: 51 4c 20 61 67 61 69 6e 73 74 20 74 68 65 20 63  QL against the c
ca60: 61 63 68 65 20 64 61 74 61 62 61 73 65 0a 09 20  ache database.. 
ca70: 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20  */..if (argc == 
ca80: 32 20 26 26 20 73 74 72 63 6d 70 28 61 72 67 76  2 && strcmp(argv
ca90: 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69 74 65 33 22  [0], "--sqlite3"
caa0: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  ) == 0) {...retu
cab0: 72 6e 28 61 70 70 66 73 5f 73 71 6c 69 74 65 33  rn(appfs_sqlite3
cac0: 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 0a  (argv[1]));..}..
cad0: 09 2f 2a 0a 09 20 2a 20 54 63 6c 20 6d 6f 64 65  ./*.. * Tcl mode
cae0: 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61  , for running ra
caf0: 77 20 54 63 6c 20 69 6e 20 74 68 65 20 73 61 6d  w Tcl in the sam
cb00: 65 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 41 70  e environment Ap
cb10: 70 46 53 64 20 77 6f 75 6c 64 0a 09 20 2a 20 72  pFSd would.. * r
cb20: 75 6e 20 63 6f 64 65 2e 0a 09 20 2a 2f 0a 09 69  un code... */..i
cb30: 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26 26 20  f (argc == 2 && 
cb40: 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20  strcmp(argv[0], 
cb50: 22 2d 2d 74 63 6c 22 29 20 3d 3d 20 30 29 20 7b  "--tcl") == 0) {
cb60: 0a 09 09 72 65 74 75 72 6e 28 61 70 70 66 73 5f  ...return(appfs_
cb70: 74 63 6c 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09  tcl(argv[1]));..
cb80: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 67 69 73  }.../*.. * Regis
cb90: 74 65 72 20 61 20 73 69 67 6e 61 6c 20 68 61 6e  ter a signal han
cba0: 64 6c 65 72 20 66 6f 72 20 68 6f 74 2d 72 65 73  dler for hot-res
cbb0: 74 61 72 74 20 72 65 71 75 65 73 74 73 0a 09 20  tart requests.. 
cbc0: 2a 2f 0a 09 73 69 67 6e 61 6c 5f 72 65 74 20 3d  */..signal_ret =
cbd0: 20 73 69 67 6e 61 6c 28 53 49 47 48 55 50 2c 20   signal(SIGHUP, 
cbe0: 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f 68 61 6e  appfs_signal_han
cbf0: 64 6c 65 72 29 3b 0a 09 69 66 20 28 73 69 67 6e  dler);..if (sign
cc00: 61 6c 5f 72 65 74 20 3d 3d 20 53 49 47 5f 45 52  al_ret == SIG_ER
cc10: 52 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  R) {...fprintf(s
cc20: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
cc30: 6f 20 69 6e 73 74 61 6c 6c 20 73 69 67 6e 61 6c  o install signal
cc40: 20 68 61 6e 64 6c 65 72 20 66 6f 72 20 68 6f 74   handler for hot
cc50: 2d 72 65 73 74 61 72 74 5c 6e 22 29 3b 0a 09 09  -restart\n");...
cc60: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
cc70: 22 48 6f 74 2d 72 65 73 74 61 72 74 20 77 69 6c  "Hot-restart wil
cc80: 6c 20 6e 6f 74 20 62 65 20 61 76 61 69 6c 61 62  l not be availab
cc90: 6c 65 2e 5c 6e 22 29 3b 0a 09 7d 0a 0a 09 2f 2a  le.\n");..}.../*
cca0: 0a 09 20 2a 20 50 61 72 73 65 20 63 6f 6d 6d 61  .. * Parse comma
ccb0: 6e 64 20 6c 69 6e 65 20 61 72 67 75 6d 65 6e 74  nd line argument
ccc0: 73 0a 09 20 2a 2f 0a 09 2f 2a 2a 0a 09 20 2a 2a  s.. */../**.. **
ccd0: 20 52 65 73 74 6f 72 65 20 61 72 67 63 2f 61 72   Restore argc/ar
cce0: 67 76 20 74 6f 20 6f 72 69 67 69 6e 61 6c 20 76  gv to original v
ccf0: 61 6c 75 65 73 2c 20 72 65 70 6c 61 63 69 6e 67  alues, replacing
cd00: 20 61 72 67 76 5b 30 5d 20 69 6e 20 63 61 73 65   argv[0] in case
cd10: 0a 09 20 2a 2a 20 69 74 20 77 61 73 20 6d 6f 69  .. ** it was moi
cd20: 66 69 65 64 20 62 79 20 2d 2d 63 61 63 68 65 64  fied by --cached
cd30: 69 72 20 6f 70 74 69 6f 6e 2e 0a 09 20 2a 2a 2f  ir option... **/
cd40: 0a 09 61 72 67 63 2b 2b 3b 0a 09 61 72 67 76 2d  ..argc++;..argv-
cd50: 2d 3b 0a 09 61 72 67 76 5b 30 5d 20 3d 20 61 72  -;..argv[0] = ar
cd60: 67 76 30 3b 0a 0a 09 2f 2a 2a 0a 09 20 2a 2a 20  gv0;.../**.. ** 
cd70: 50 65 72 66 6f 72 6d 20 74 68 65 20 61 72 67 75  Perform the argu
cd80: 6d 65 6e 74 20 70 61 72 73 69 6e 67 0a 09 20 2a  ment parsing.. *
cd90: 2a 2f 0a 09 61 6f 70 5f 72 65 74 20 3d 20 61 70  */..aop_ret = ap
cda0: 70 66 73 5f 6f 70 74 5f 70 61 72 73 65 28 61 72  pfs_opt_parse(ar
cdb0: 67 63 2c 20 61 72 67 76 2c 20 26 61 72 67 73 29  gc, argv, &args)
cdc0: 3b 0a 09 69 66 20 28 61 6f 70 5f 72 65 74 20 21  ;..if (aop_ret !
cdd0: 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 61 6f 70  = 0) {...if (aop
cde0: 5f 72 65 74 20 3c 20 30 29 20 7b 0a 09 09 09 72  _ret < 0) {....r
cdf0: 65 74 75 72 6e 28 30 29 3b 0a 09 09 7d 0a 0a 09  eturn(0);...}...
ce00: 09 72 65 74 75 72 6e 28 61 6f 70 5f 72 65 74 29  .return(aop_ret)
ce10: 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72  ;..}.../*.. * Cr
ce20: 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72  eate a Tcl inter
ce30: 70 72 65 74 65 72 20 6a 75 73 74 20 74 6f 20 76  preter just to v
ce40: 65 72 69 66 79 20 74 68 61 74 20 74 68 69 6e 67  erify that thing
ce50: 73 20 61 72 65 20 69 6e 20 77 6f 72 6b 69 6e 67  s are in working
ce60: 20 0a 09 20 2a 20 6f 72 64 65 72 20 62 65 66 6f   .. * order befo
ce70: 72 65 20 77 65 20 62 65 63 6f 6d 65 20 61 20 64  re we become a d
ce80: 61 65 6d 6f 6e 2e 0a 09 20 2a 2f 0a 09 74 65 73  aemon... */..tes
ce90: 74 5f 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  t_interp = appfs
cea0: 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72  _create_TclInter
ceb0: 70 28 26 74 65 73 74 5f 69 6e 74 65 72 70 5f 65  p(&test_interp_e
cec0: 72 72 6f 72 29 3b 0a 09 69 66 20 28 74 65 73 74  rror);..if (test
ced0: 5f 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  _interp == NULL)
cee0: 20 7b 0a 09 09 69 66 20 28 74 65 73 74 5f 69 6e   {...if (test_in
cef0: 74 65 72 70 5f 65 72 72 6f 72 20 3d 3d 20 4e 55  terp_error == NU
cf00: 4c 4c 29 20 7b 0a 09 09 09 74 65 73 74 5f 69 6e  LL) {....test_in
cf10: 74 65 72 70 5f 65 72 72 6f 72 20 3d 20 22 55 6e  terp_error = "Un
cf20: 6b 6e 6f 77 6e 20 65 72 72 6f 72 22 3b 0a 09 09  known error";...
cf30: 7d 0a 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64  }....fprintf(std
cf40: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
cf50: 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 69  initialize Tcl i
cf60: 6e 74 65 72 70 72 65 74 65 72 20 66 6f 72 20 41  nterpreter for A
cf70: 70 70 46 53 64 3a 5c 6e 22 29 3b 0a 09 09 66 70  ppFSd:\n");...fp
cf80: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25  rintf(stderr, "%
cf90: 73 5c 6e 22 2c 20 74 65 73 74 5f 69 6e 74 65 72  s\n", test_inter
cfa0: 70 5f 65 72 72 6f 72 29 3b 0a 0a 09 09 72 65 74  p_error);....ret
cfb0: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 54 63 6c  urn(1);..}...Tcl
cfc0: 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 74 65  _DeleteInterp(te
cfd0: 73 74 5f 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66  st_interp);...if
cfe0: 20 28 61 70 70 66 73 5f 74 68 72 65 61 64 65 64   (appfs_threaded
cff0: 5f 74 63 6c 29 20 7b 0a 09 09 54 63 6c 5f 46 69  _tcl) {...Tcl_Fi
d000: 6e 61 6c 69 7a 65 4e 6f 74 69 66 69 65 72 28 4e  nalizeNotifier(N
d010: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  ULL);..}.../*.. 
d020: 2a 20 45 6e 74 65 72 20 74 68 65 20 46 55 53 45  * Enter the FUSE
d030: 20 6d 61 69 6e 20 6c 6f 6f 70 20 2d 2d 20 74 68   main loop -- th
d040: 69 73 20 77 69 6c 6c 20 70 72 6f 63 65 73 73 20  is will process 
d050: 61 6e 79 20 61 72 67 75 6d 65 6e 74 73 0a 09 20  any arguments.. 
d060: 2a 20 61 6e 64 20 73 74 61 72 74 20 73 65 72 76  * and start serv
d070: 69 63 69 6e 67 20 72 65 71 75 65 73 74 73 2e 0a  icing requests..
d080: 09 20 2a 2f 0a 09 61 70 70 66 73 5f 66 75 73 65  . */..appfs_fuse
d090: 5f 73 74 61 72 74 65 64 20 3d 20 31 3b 0a 09 72  _started = 1;..r
d0a0: 65 74 75 72 6e 28 66 75 73 65 5f 6d 61 69 6e 28  eturn(fuse_main(
d0b0: 61 72 67 73 2e 61 72 67 63 2c 20 61 72 67 73 2e  args.argc, args.
d0c0: 61 72 67 76 2c 20 26 61 70 70 66 73 5f 6f 70 65  argv, &appfs_ope
d0d0: 72 61 74 69 6f 6e 73 2c 20 4e 55 4c 4c 29 29 3b  rations, NULL));
d0e0: 0a 7d 0a                                         .}.