Hex Artifact Content

Artifact b81dc3008d536bafb7d0791ccde9416741cf5167:


0000: 2f 2a 0a 20 2a 20 43 6f 70 79 72 69 67 68 74 20  /*. * Copyright 
0010: 28 63 29 20 32 30 31 34 2c 20 32 30 31 35 20 20  (c) 2014, 2015  
0020: 52 6f 79 20 4b 65 65 6e 65 0a 20 2a 0a 20 2a 20  Roy Keene. *. * 
0030: 50 65 72 6d 69 73 73 69 6f 6e 20 69 73 20 68 65  Permission is he
0040: 72 65 62 79 20 67 72 61 6e 74 65 64 2c 20 66 72  reby granted, fr
0050: 65 65 20 6f 66 20 63 68 61 72 67 65 2c 20 74 6f  ee of charge, to
0060: 20 61 6e 79 20 70 65 72 73 6f 6e 20 6f 62 74 61   any person obta
0070: 69 6e 69 6e 67 20 61 20 63 6f 70 79 0a 20 2a 20  ining a copy. * 
0080: 6f 66 20 74 68 69 73 20 73 6f 66 74 77 61 72 65  of this software
0090: 20 61 6e 64 20 61 73 73 6f 63 69 61 74 65 64 20   and associated 
00a0: 64 6f 63 75 6d 65 6e 74 61 74 69 6f 6e 20 66 69  documentation fi
00b0: 6c 65 73 20 28 74 68 65 20 22 53 6f 66 74 77 61  les (the "Softwa
00c0: 72 65 22 29 2c 20 74 6f 20 64 65 61 6c 0a 20 2a  re"), to deal. *
00d0: 20 69 6e 20 74 68 65 20 53 6f 66 74 77 61 72 65   in the Software
00e0: 20 77 69 74 68 6f 75 74 20 72 65 73 74 72 69 63   without restric
00f0: 74 69 6f 6e 2c 20 69 6e 63 6c 75 64 69 6e 67 20  tion, including 
0100: 77 69 74 68 6f 75 74 20 6c 69 6d 69 74 61 74 69  without limitati
0110: 6f 6e 20 74 68 65 20 72 69 67 68 74 73 0a 20 2a  on the rights. *
0120: 20 74 6f 20 75 73 65 2c 20 63 6f 70 79 2c 20 6d   to use, copy, m
0130: 6f 64 69 66 79 2c 20 6d 65 72 67 65 2c 20 70 75  odify, merge, pu
0140: 62 6c 69 73 68 2c 20 64 69 73 74 72 69 62 75 74  blish, distribut
0150: 65 2c 20 73 75 62 6c 69 63 65 6e 73 65 2c 20 61  e, sublicense, a
0160: 6e 64 2f 6f 72 20 73 65 6c 6c 0a 20 2a 20 63 6f  nd/or sell. * co
0170: 70 69 65 73 20 6f 66 20 74 68 65 20 53 6f 66 74  pies of the Soft
0180: 77 61 72 65 2c 20 61 6e 64 20 74 6f 20 70 65 72  ware, and to per
0190: 6d 69 74 20 70 65 72 73 6f 6e 73 20 74 6f 20 77  mit persons to w
01a0: 68 6f 6d 20 74 68 65 20 53 6f 66 74 77 61 72 65  hom the Software
01b0: 20 69 73 0a 20 2a 20 66 75 72 6e 69 73 68 65 64   is. * furnished
01c0: 20 74 6f 20 64 6f 20 73 6f 2c 20 73 75 62 6a 65   to do so, subje
01d0: 63 74 20 74 6f 20 74 68 65 20 66 6f 6c 6c 6f 77  ct to the follow
01e0: 69 6e 67 20 63 6f 6e 64 69 74 69 6f 6e 73 3a 0a  ing conditions:.
01f0: 20 2a 0a 20 2a 20 54 68 65 20 61 62 6f 76 65 20   *. * The above 
0200: 63 6f 70 79 72 69 67 68 74 20 6e 6f 74 69 63 65  copyright notice
0210: 20 61 6e 64 20 74 68 69 73 20 70 65 72 6d 69 73   and this permis
0220: 73 69 6f 6e 20 6e 6f 74 69 63 65 20 73 68 61 6c  sion notice shal
0230: 6c 20 62 65 20 69 6e 63 6c 75 64 65 64 20 69 6e  l be included in
0240: 0a 20 2a 20 61 6c 6c 20 63 6f 70 69 65 73 20 6f  . * all copies o
0250: 72 20 73 75 62 73 74 61 6e 74 69 61 6c 20 70 6f  r substantial po
0260: 72 74 69 6f 6e 73 20 6f 66 20 74 68 65 20 53 6f  rtions of the So
0270: 66 74 77 61 72 65 2e 0a 20 2a 0a 20 2a 20 54 48  ftware.. *. * TH
0280: 45 20 53 4f 46 54 57 41 52 45 20 49 53 20 50 52  E SOFTWARE IS PR
0290: 4f 56 49 44 45 44 20 22 41 53 20 49 53 22 2c 20  OVIDED "AS IS", 
02a0: 57 49 54 48 4f 55 54 20 57 41 52 52 41 4e 54 59  WITHOUT WARRANTY
02b0: 20 4f 46 20 41 4e 59 20 4b 49 4e 44 2c 20 45 58   OF ANY KIND, EX
02c0: 50 52 45 53 53 20 4f 52 0a 20 2a 20 49 4d 50 4c  PRESS OR. * IMPL
02d0: 49 45 44 2c 20 49 4e 43 4c 55 44 49 4e 47 20 42  IED, INCLUDING B
02e0: 55 54 20 4e 4f 54 20 4c 49 4d 49 54 45 44 20 54  UT NOT LIMITED T
02f0: 4f 20 54 48 45 20 57 41 52 52 41 4e 54 49 45 53  O THE WARRANTIES
0300: 20 4f 46 20 4d 45 52 43 48 41 4e 54 41 42 49 4c   OF MERCHANTABIL
0310: 49 54 59 2c 0a 20 2a 20 46 49 54 4e 45 53 53 20  ITY,. * FITNESS 
0320: 46 4f 52 20 41 20 50 41 52 54 49 43 55 4c 41 52  FOR A PARTICULAR
0330: 20 50 55 52 50 4f 53 45 20 41 4e 44 20 4e 4f 4e   PURPOSE AND NON
0340: 49 4e 46 52 49 4e 47 45 4d 45 4e 54 2e 20 49 4e  INFRINGEMENT. IN
0350: 20 4e 4f 20 45 56 45 4e 54 20 53 48 41 4c 4c 20   NO EVENT SHALL 
0360: 54 48 45 0a 20 2a 20 41 55 54 48 4f 52 53 20 4f  THE. * AUTHORS O
0370: 52 20 43 4f 50 59 52 49 47 48 54 20 48 4f 4c 44  R COPYRIGHT HOLD
0380: 45 52 53 20 42 45 20 4c 49 41 42 4c 45 20 46 4f  ERS BE LIABLE FO
0390: 52 20 41 4e 59 20 43 4c 41 49 4d 2c 20 44 41 4d  R ANY CLAIM, DAM
03a0: 41 47 45 53 20 4f 52 20 4f 54 48 45 52 0a 20 2a  AGES OR OTHER. *
03b0: 20 4c 49 41 42 49 4c 49 54 59 2c 20 57 48 45 54   LIABILITY, WHET
03c0: 48 45 52 20 49 4e 20 41 4e 20 41 43 54 49 4f 4e  HER IN AN ACTION
03d0: 20 4f 46 20 43 4f 4e 54 52 41 43 54 2c 20 54 4f   OF CONTRACT, TO
03e0: 52 54 20 4f 52 20 4f 54 48 45 52 57 49 53 45 2c  RT OR OTHERWISE,
03f0: 20 41 52 49 53 49 4e 47 20 46 52 4f 4d 2c 0a 20   ARISING FROM,. 
0400: 2a 20 4f 55 54 20 4f 46 20 4f 52 20 49 4e 20 43  * OUT OF OR IN C
0410: 4f 4e 4e 45 43 54 49 4f 4e 20 57 49 54 48 20 54  ONNECTION WITH T
0420: 48 45 20 53 4f 46 54 57 41 52 45 20 4f 52 20 54  HE SOFTWARE OR T
0430: 48 45 20 55 53 45 20 4f 52 20 4f 54 48 45 52 20  HE USE OR OTHER 
0440: 44 45 41 4c 49 4e 47 53 20 49 4e 0a 20 2a 20 54  DEALINGS IN. * T
0450: 48 45 20 53 4f 46 54 57 41 52 45 2e 0a 20 2a 2f  HE SOFTWARE.. */
0460: 0a 23 64 65 66 69 6e 65 20 46 55 53 45 5f 55 53  .#define FUSE_US
0470: 45 5f 56 45 52 53 49 4f 4e 20 32 36 0a 0a 23 69  E_VERSION 26..#i
0480: 6e 63 6c 75 64 65 20 3c 73 79 73 2f 66 73 75 69  nclude <sys/fsui
0490: 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73  d.h>.#include <s
04a0: 79 73 2f 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63  ys/types.h>.#inc
04b0: 6c 75 64 65 20 3c 73 79 73 2f 74 69 6d 65 2e 68  lude <sys/time.h
04c0: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 70 74 68 72  >.#include <pthr
04d0: 65 61 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  ead.h>.#include 
04e0: 3c 6c 69 6d 69 74 73 2e 68 3e 0a 23 69 6e 63 6c  <limits.h>.#incl
04f0: 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23  ude <string.h>.#
0500: 69 6e 63 6c 75 64 65 20 3c 73 74 64 61 72 67 2e  include <stdarg.
0510: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64  h>.#include <std
0520: 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  lib.h>.#include 
0530: 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c  <unistd.h>.#incl
0540: 75 64 65 20 3c 65 72 72 6e 6f 2e 68 3e 0a 23 69  ude <errno.h>.#i
0550: 6e 63 6c 75 64 65 20 3c 66 63 6e 74 6c 2e 68 3e  nclude <fcntl.h>
0560: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f  .#include <stdio
0570: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 66 75  .h>.#include <fu
0580: 73 65 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  se.h>.#include <
0590: 70 77 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  pwd.h>.#include 
05a0: 3c 74 63 6c 2e 68 3e 0a 0a 2f 2a 0a 20 2a 20 44  <tcl.h>../*. * D
05b0: 65 66 61 75 6c 74 20 63 61 63 68 65 20 64 69 72  efault cache dir
05c0: 65 63 74 6f 72 79 0a 20 2a 2f 0a 23 69 66 6e 64  ectory. */.#ifnd
05d0: 65 66 20 41 50 50 46 53 5f 43 41 43 48 45 44 49  ef APPFS_CACHEDI
05e0: 52 0a 23 64 65 66 69 6e 65 20 41 50 50 46 53 5f  R.#define APPFS_
05f0: 43 41 43 48 45 44 49 52 20 22 2f 76 61 72 2f 63  CACHEDIR "/var/c
0600: 61 63 68 65 2f 61 70 70 66 73 22 0a 23 65 6e 64  ache/appfs".#end
0610: 69 66 0a 0a 2f 2a 20 44 65 62 75 67 67 69 6e 67  if../* Debugging
0620: 20 6d 61 63 72 6f 73 20 2a 2f 0a 23 69 66 64 65   macros */.#ifde
0630: 66 20 44 45 42 55 47 0a 46 49 4c 45 20 2a 61 70  f DEBUG.FILE *ap
0640: 70 66 73 5f 64 65 62 75 67 5f 66 64 20 3d 20 4e  pfs_debug_fd = N
0650: 55 4c 4c 3b 0a 0a 23 69 66 6e 64 65 66 20 41 50  ULL;..#ifndef AP
0660: 50 46 53 5f 44 45 42 55 47 5f 46 44 0a 23 20 20  PFS_DEBUG_FD.#  
0670: 69 66 64 65 66 20 41 50 50 46 53 5f 44 45 42 55  ifdef APPFS_DEBU
0680: 47 5f 46 49 4c 45 0a 23 20 20 20 20 64 65 66 69  G_FILE.#    defi
0690: 6e 65 20 41 50 50 46 53 5f 44 45 42 55 47 5f 46  ne APPFS_DEBUG_F
06a0: 44 20 66 6f 70 65 6e 28 41 50 50 46 53 5f 44 45  D fopen(APPFS_DE
06b0: 42 55 47 5f 46 49 4c 45 2c 20 22 61 22 29 0a 23  BUG_FILE, "a").#
06c0: 20 20 65 6c 73 65 0a 23 20 20 20 20 64 65 66 69    else.#    defi
06d0: 6e 65 20 41 50 50 46 53 5f 44 45 42 55 47 5f 46  ne APPFS_DEBUG_F
06e0: 44 20 66 6f 70 65 6e 28 22 2f 74 6d 70 2f 61 70  D fopen("/tmp/ap
06f0: 70 66 73 64 2e 6c 6f 67 22 2c 20 22 61 22 29 0a  pfsd.log", "a").
0700: 23 20 20 65 6e 64 69 66 0a 23 65 6e 64 69 66 0a  #  endif.#endif.
0710: 0a 23 64 65 66 69 6e 65 20 41 50 50 46 53 5f 44  .#define APPFS_D
0720: 45 42 55 47 28 78 2e 2e 2e 29 20 7b 20 5c 0a 09  EBUG(x...) { \..
0730: 63 68 61 72 20 62 75 66 5b 38 31 39 32 5d 3b 20  char buf[8192]; 
0740: 5c 0a 09 69 6e 74 20 62 75 66 6f 66 66 20 3d 20  \..int bufoff = 
0750: 30 3b 20 5c 0a 09 69 66 20 28 61 70 70 66 73 5f  0; \..if (appfs_
0760: 64 65 62 75 67 5f 66 64 20 3d 3d 20 4e 55 4c 4c  debug_fd == NULL
0770: 29 20 7b 20 5c 0a 09 09 61 70 70 66 73 5f 64 65  ) { \...appfs_de
0780: 62 75 67 5f 66 64 20 3d 20 41 50 50 46 53 5f 44  bug_fd = APPFS_D
0790: 45 42 55 47 5f 46 44 3b 20 5c 0a 09 7d 3b 20 5c  EBUG_FD; \..}; \
07a0: 0a 09 69 66 20 28 61 70 70 66 73 5f 64 65 62 75  ..if (appfs_debu
07b0: 67 5f 66 64 20 3d 3d 20 4e 55 4c 4c 29 20 7b 20  g_fd == NULL) { 
07c0: 61 70 70 66 73 5f 64 65 62 75 67 5f 66 64 20 3d  appfs_debug_fd =
07d0: 20 73 74 64 65 72 72 3b 20 7d 20 5c 0a 09 62 75   stderr; } \..bu
07e0: 66 6f 66 66 20 3d 20 73 6e 70 72 69 6e 74 66 28  foff = snprintf(
07f0: 62 75 66 2c 20 73 69 7a 65 6f 66 28 62 75 66 29  buf, sizeof(buf)
0800: 2c 20 22 5b 64 65 62 75 67 5d 20 5b 74 3d 25 6c  , "[debug] [t=%l
0810: 6c 78 5d 20 25 73 3a 25 69 3a 25 73 3a 20 22 2c  lx] %s:%i:%s: ",
0820: 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20   (unsigned long 
0830: 6c 6f 6e 67 29 20 70 74 68 72 65 61 64 5f 73 65  long) pthread_se
0840: 6c 66 28 29 2c 20 5f 5f 46 49 4c 45 5f 5f 2c 20  lf(), __FILE__, 
0850: 5f 5f 4c 49 4e 45 5f 5f 2c 20 5f 5f 66 75 6e 63  __LINE__, __func
0860: 5f 5f 29 3b 20 5c 0a 09 69 66 20 28 62 75 66 6f  __); \..if (bufo
0870: 66 66 20 3c 20 73 69 7a 65 6f 66 28 62 75 66 29  ff < sizeof(buf)
0880: 29 20 7b 20 5c 0a 09 09 62 75 66 6f 66 66 20 2b  ) { \...bufoff +
0890: 3d 20 73 6e 70 72 69 6e 74 66 28 62 75 66 20 2b  = snprintf(buf +
08a0: 20 62 75 66 6f 66 66 2c 20 73 69 7a 65 6f 66 28   bufoff, sizeof(
08b0: 62 75 66 29 20 2d 20 62 75 66 6f 66 66 2c 20 78  buf) - bufoff, x
08c0: 29 3b 20 5c 0a 09 7d 3b 20 5c 0a 09 69 66 20 28  ); \..}; \..if (
08d0: 62 75 66 6f 66 66 20 3c 20 73 69 7a 65 6f 66 28  bufoff < sizeof(
08e0: 62 75 66 29 29 20 7b 20 5c 0a 09 09 62 75 66 6f  buf)) { \...bufo
08f0: 66 66 20 2b 3d 20 73 6e 70 72 69 6e 74 66 28 62  ff += snprintf(b
0900: 75 66 20 2b 20 62 75 66 6f 66 66 2c 20 73 69 7a  uf + bufoff, siz
0910: 65 6f 66 28 62 75 66 29 20 2d 20 62 75 66 6f 66  eof(buf) - bufof
0920: 66 2c 20 22 5c 6e 22 29 3b 5c 0a 09 7d 20 5c 0a  f, "\n");\..} \.
0930: 09 69 66 20 28 62 75 66 6f 66 66 20 3e 20 73 69  .if (bufoff > si
0940: 7a 65 6f 66 28 62 75 66 29 29 20 7b 20 5c 0a 09  zeof(buf)) { \..
0950: 09 62 75 66 6f 66 66 20 3d 20 73 69 7a 65 6f 66  .bufoff = sizeof
0960: 28 62 75 66 29 3b 20 5c 0a 09 7d 3b 20 5c 0a 09  (buf); \..}; \..
0970: 66 70 72 69 6e 74 66 28 61 70 70 66 73 5f 64 65  fprintf(appfs_de
0980: 62 75 67 5f 66 64 2c 20 22 25 2e 2a 73 22 2c 20  bug_fd, "%.*s", 
0990: 62 75 66 6f 66 66 2c 20 62 75 66 29 3b 20 5c 0a  bufoff, buf); \.
09a0: 09 66 66 6c 75 73 68 28 61 70 70 66 73 5f 64 65  .fflush(appfs_de
09b0: 62 75 67 5f 66 64 29 3b 20 5c 0a 7d 0a 23 64 65  bug_fd); \.}.#de
09c0: 66 69 6e 65 20 41 50 50 46 53 5f 45 52 52 4f 52  fine APPFS_ERROR
09d0: 28 78 2e 2e 2e 29 20 41 50 50 46 53 5f 44 45 42  (x...) APPFS_DEB
09e0: 55 47 28 78 29 0a 23 65 6c 73 65 0a 23 64 65 66  UG(x).#else.#def
09f0: 69 6e 65 20 41 50 50 46 53 5f 44 45 42 55 47 28  ine APPFS_DEBUG(
0a00: 78 2e 2e 2e 29 20 2f 2a 2a 2f 0a 23 64 65 66 69  x...) /**/.#defi
0a10: 6e 65 20 41 50 50 46 53 5f 45 52 52 4f 52 28 78  ne APPFS_ERROR(x
0a20: 2e 2e 2e 29 20 66 70 72 69 6e 74 66 28 73 74 64  ...) fprintf(std
0a30: 65 72 72 2c 20 78 29 3b 20 66 70 72 69 6e 74 66  err, x); fprintf
0a40: 28 73 74 64 65 72 72 2c 20 22 5c 6e 22 29 3b 0a  (stderr, "\n");.
0a50: 23 65 6e 64 69 66 0a 0a 2f 2a 0a 20 2a 20 53 48  #endif../*. * SH
0a60: 41 31 20 54 63 6c 20 50 61 63 6b 61 67 65 20 69  A1 Tcl Package i
0a70: 6e 69 74 69 61 6c 69 7a 65 72 2c 20 66 72 6f 6d  nitializer, from
0a80: 20 73 68 61 31 2e 6f 0a 20 2a 2f 0a 69 6e 74 20   sha1.o. */.int 
0a90: 53 68 61 31 5f 49 6e 69 74 28 54 63 6c 5f 49 6e  Sha1_Init(Tcl_In
0aa0: 74 65 72 70 20 2a 69 6e 74 65 72 70 29 3b 0a 0a  terp *interp);..
0ab0: 2f 2a 0a 20 2a 20 54 68 72 65 61 64 20 53 70 65  /*. * Thread Spe
0ac0: 63 69 66 69 63 20 44 61 74 61 20 28 54 53 44 29  cific Data (TSD)
0ad0: 20 66 6f 72 20 54 63 6c 20 49 6e 74 65 72 70 72   for Tcl Interpr
0ae0: 65 74 65 72 20 66 6f 72 20 74 68 65 20 63 75 72  eter for the cur
0af0: 72 65 6e 74 20 74 68 72 65 61 64 0a 20 2a 2f 0a  rent thread. */.
0b00: 73 74 61 74 69 63 20 70 74 68 72 65 61 64 5f 6b  static pthread_k
0b10: 65 79 5f 74 20 69 6e 74 65 72 70 4b 65 79 3b 0a  ey_t interpKey;.
0b20: 0a 2f 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20 76 61  ./*. * Global va
0b30: 72 69 61 62 6c 65 73 2c 20 6e 65 65 64 65 64 20  riables, needed 
0b40: 66 6f 72 20 61 6c 6c 20 74 68 72 65 61 64 73 20  for all threads 
0b50: 62 75 74 20 6f 6e 6c 79 20 69 6e 69 74 69 61 6c  but only initial
0b60: 69 7a 65 64 20 62 65 66 6f 72 65 20 61 6e 79 0a  ized before any.
0b70: 20 2a 20 46 55 53 45 20 74 68 72 65 61 64 73 20   * FUSE threads 
0b80: 61 72 65 20 63 72 65 61 74 65 64 0a 20 2a 2f 0a  are created. */.
0b90: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 70 70 66  const char *appf
0ba0: 73 5f 63 61 63 68 65 64 69 72 3b 0a 74 69 6d 65  s_cachedir;.time
0bb0: 5f 74 20 61 70 70 66 73 5f 62 6f 6f 74 74 69 6d  _t appfs_boottim
0bc0: 65 3b 0a 69 6e 74 20 61 70 70 66 73 5f 66 75 73  e;.int appfs_fus
0bd0: 65 5f 73 74 61 72 74 65 64 20 3d 20 30 3b 0a 69  e_started = 0;.i
0be0: 6e 74 20 61 70 70 66 73 5f 74 68 72 65 61 64 65  nt appfs_threade
0bf0: 64 5f 74 63 6c 3b 0a 0a 2f 2a 0a 20 2a 20 47 6c  d_tcl;../*. * Gl
0c00: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20 66  obal variables f
0c10: 6f 72 20 41 70 70 46 53 20 63 61 63 68 69 6e 67  or AppFS caching
0c20: 0a 20 2a 2f 0a 70 74 68 72 65 61 64 5f 6d 75 74  . */.pthread_mut
0c30: 65 78 5f 74 20 61 70 70 66 73 5f 70 61 74 68 5f  ex_t appfs_path_
0c40: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
0c50: 20 3d 20 50 54 48 52 45 41 44 5f 4d 55 54 45 58   = PTHREAD_MUTEX
0c60: 5f 49 4e 49 54 49 41 4c 49 5a 45 52 3b 0a 69 6e  _INITIALIZER;.in
0c70: 74 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  t appfs_path_inf
0c80: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 38  o_cache_size = 8
0c90: 32 30 39 3b 0a 73 74 72 75 63 74 20 61 70 70 66  209;.struct appf
0ca0: 73 5f 70 61 74 68 69 6e 66 6f 20 2a 61 70 70 66  s_pathinfo *appf
0cb0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
0cc0: 65 20 3d 20 4e 55 4c 4c 3b 0a 0a 23 69 66 20 21  e = NULL;..#if !
0cd0: 64 65 66 69 6e 65 64 28 54 43 4c 5f 54 48 52 45  defined(TCL_THRE
0ce0: 41 44 53 29 20 7c 7c 20 54 43 4c 5f 54 48 52 45  ADS) || TCL_THRE
0cf0: 41 44 53 20 21 3d 20 31 0a 2f 2a 0a 20 2a 20 48  ADS != 1./*. * H
0d00: 61 6e 64 6c 65 20 75 6e 74 68 72 65 61 64 65 64  andle unthreaded
0d10: 20 54 63 6c 0a 20 2a 2f 0a 70 74 68 72 65 61 64   Tcl. */.pthread
0d20: 5f 6d 75 74 65 78 5f 74 20 61 70 70 66 73 5f 74  _mutex_t appfs_t
0d30: 63 6c 5f 62 69 67 5f 67 6c 6f 62 61 6c 5f 6c 6f  cl_big_global_lo
0d40: 63 6b 20 3d 20 50 54 48 52 45 41 44 5f 4d 55 54  ck = PTHREAD_MUT
0d50: 45 58 5f 49 4e 49 54 49 41 4c 49 5a 45 52 3b 0a  EX_INITIALIZER;.
0d60: 23 64 65 66 69 6e 65 20 61 70 70 66 73 5f 63 61  #define appfs_ca
0d70: 6c 6c 5f 6c 69 62 74 63 6c 5f 65 6e 74 65 72 20  ll_libtcl_enter 
0d80: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f  pthread_mutex_lo
0d90: 63 6b 28 26 61 70 70 66 73 5f 74 63 6c 5f 62 69  ck(&appfs_tcl_bi
0da0: 67 5f 67 6c 6f 62 61 6c 5f 6c 6f 63 6b 29 3b 0a  g_global_lock);.
0db0: 23 64 65 66 69 6e 65 20 61 70 70 66 73 5f 63 61  #define appfs_ca
0dc0: 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74 20 70  ll_libtcl_exit p
0dd0: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c  thread_mutex_unl
0de0: 6f 63 6b 28 26 61 70 70 66 73 5f 74 63 6c 5f 62  ock(&appfs_tcl_b
0df0: 69 67 5f 67 6c 6f 62 61 6c 5f 6c 6f 63 6b 29 3b  ig_global_lock);
0e00: 0a 23 65 6c 73 65 0a 23 64 65 66 69 6e 65 20 61  .#else.#define a
0e10: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
0e20: 5f 65 6e 74 65 72 20 2f 2a 2a 2f 0a 23 64 65 66  _enter /**/.#def
0e30: 69 6e 65 20 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ine appfs_call_l
0e40: 69 62 74 63 6c 5f 65 78 69 74 20 2f 2a 2a 2f 0a  ibtcl_exit /**/.
0e50: 23 65 6e 64 69 66 0a 23 64 65 66 69 6e 65 20 61  #endif.#define a
0e60: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
0e70: 28 78 2e 2e 2e 29 20 61 70 70 66 73 5f 63 61 6c  (x...) appfs_cal
0e80: 6c 5f 6c 69 62 74 63 6c 5f 65 6e 74 65 72 20 78  l_libtcl_enter x
0e90: 20 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74   appfs_call_libt
0ea0: 63 6c 5f 65 78 69 74 0a 0a 2f 2a 0a 20 2a 20 47  cl_exit../*. * G
0eb0: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20  lobal variables 
0ec0: 66 6f 72 20 41 70 70 46 53 20 54 63 6c 20 49 6e  for AppFS Tcl In
0ed0: 74 65 72 70 72 65 74 65 72 20 72 65 73 74 61 72  terpreter restar
0ee0: 74 69 6e 67 0a 20 2a 2f 0a 69 6e 74 20 69 6e 74  ting. */.int int
0ef0: 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20  erp_reset_key = 
0f00: 30 3b 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 20  0;../*. * AppFS 
0f10: 50 61 74 68 20 54 79 70 65 3a 20 20 44 65 73 63  Path Type:  Desc
0f20: 72 69 62 65 73 20 74 68 65 20 74 79 70 65 20 6f  ribes the type o
0f30: 66 20 70 61 74 68 20 61 20 67 69 76 65 6e 20 66  f path a given f
0f40: 69 6c 65 20 69 73 0a 20 2a 2f 0a 74 79 70 65 64  ile is. */.typed
0f50: 65 66 20 65 6e 75 6d 20 7b 0a 09 41 50 50 46 53  ef enum {..APPFS
0f60: 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49  _PATHTYPE_INVALI
0f70: 44 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59  D,..APPFS_PATHTY
0f80: 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53  PE_DOES_NOT_EXIS
0f90: 54 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59  T,..APPFS_PATHTY
0fa0: 50 45 5f 46 49 4c 45 2c 0a 09 41 50 50 46 53 5f  PE_FILE,..APPFS_
0fb0: 50 41 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f  PATHTYPE_DIRECTO
0fc0: 52 59 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54  RY,..APPFS_PATHT
0fd0: 59 50 45 5f 53 59 4d 4c 49 4e 4b 2c 0a 09 41 50  YPE_SYMLINK,..AP
0fe0: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 4f 43  PFS_PATHTYPE_SOC
0ff0: 4b 45 54 2c 0a 09 41 50 50 46 53 5f 50 41 54 48  KET,..APPFS_PATH
1000: 54 59 50 45 5f 46 49 46 4f 2c 0a 7d 20 61 70 70  TYPE_FIFO,.} app
1010: 66 73 5f 70 61 74 68 74 79 70 65 5f 74 3b 0a 0a  fs_pathtype_t;..
1020: 2f 2a 0a 20 2a 20 41 70 70 46 53 20 50 61 74 68  /*. * AppFS Path
1030: 20 49 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 20 2a   Information:. *
1040: 20 20 20 20 20 20 20 20 20 43 6f 6d 70 6c 65 74           Complet
1050: 65 6c 79 20 64 65 73 63 72 69 62 65 73 20 61 20  ely describes a 
1060: 73 70 65 63 69 66 69 63 20 70 61 74 68 2c 20 68  specific path, h
1070: 6f 77 20 69 74 20 73 68 6f 75 6c 64 20 62 65 20  ow it should be 
1080: 72 65 74 75 72 6e 65 64 20 74 6f 0a 20 2a 20 20  returned to. *  
1090: 20 20 20 20 20 20 20 74 6f 20 74 68 65 20 6b 65         to the ke
10a0: 72 6e 65 6c 0a 20 2a 2f 0a 73 74 72 75 63 74 20  rnel. */.struct 
10b0: 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 7b  appfs_pathinfo {
10c0: 0a 09 61 70 70 66 73 5f 70 61 74 68 74 79 70 65  ..appfs_pathtype
10d0: 5f 74 20 74 79 70 65 3b 0a 09 74 69 6d 65 5f 74  _t type;..time_t
10e0: 20 74 69 6d 65 3b 0a 09 63 68 61 72 20 68 6f 73   time;..char hos
10f0: 74 6e 61 6d 65 5b 32 35 36 5d 3b 0a 09 69 6e 74  tname[256];..int
1100: 20 70 61 63 6b 61 67 65 64 3b 0a 09 75 6e 73 69   packaged;..unsi
1110: 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 20 69  gned long long i
1120: 6e 6f 64 65 3b 0a 09 75 6e 69 6f 6e 20 7b 0a 09  node;..union {..
1130: 09 73 74 72 75 63 74 20 7b 0a 09 09 09 69 6e 74  .struct {....int
1140: 20 63 68 69 6c 64 63 6f 75 6e 74 3b 0a 09 09 7d   childcount;...}
1150: 20 64 69 72 3b 0a 09 09 73 74 72 75 63 74 20 7b   dir;...struct {
1160: 0a 09 09 09 69 6e 74 20 65 78 65 63 75 74 61 62  ....int executab
1170: 6c 65 3b 0a 09 09 09 69 6e 74 20 73 75 69 64 52  le;....int suidR
1180: 6f 6f 74 3b 0a 09 09 09 69 6e 74 20 77 6f 72 6c  oot;....int worl
1190: 64 61 63 63 65 73 73 69 62 6c 65 3b 0a 09 09 09  daccessible;....
11a0: 6f 66 66 5f 74 20 73 69 7a 65 3b 0a 09 09 7d 20  off_t size;...} 
11b0: 66 69 6c 65 3b 0a 09 09 73 74 72 75 63 74 20 7b  file;...struct {
11c0: 0a 09 09 09 6f 66 66 5f 74 20 73 69 7a 65 3b 0a  ....off_t size;.
11d0: 09 09 09 63 68 61 72 20 73 6f 75 72 63 65 5b 32  ...char source[2
11e0: 35 36 5d 3b 0a 09 09 7d 20 73 79 6d 6c 69 6e 6b  56];...} symlink
11f0: 3b 0a 09 7d 20 74 79 70 65 69 6e 66 6f 3b 0a 0a  ;..} typeinfo;..
1200: 09 2f 2a 20 41 74 74 72 69 62 75 74 65 73 20 75  ./* Attributes u
1210: 73 65 64 20 6f 6e 6c 79 20 66 6f 72 20 63 61 63  sed only for cac
1220: 68 69 6e 67 20 65 6e 74 72 69 65 73 20 2a 2f 0a  hing entries */.
1230: 09 63 68 61 72 20 2a 5f 63 61 63 68 65 5f 70 61  .char *_cache_pa
1240: 74 68 3b 0a 09 75 69 64 5f 74 20 5f 63 61 63 68  th;..uid_t _cach
1250: 65 5f 75 69 64 3b 0a 7d 3b 0a 0a 2f 2a 0a 20 2a  e_uid;.};../*. *
1260: 20 43 72 65 61 74 65 20 61 20 6e 65 77 20 54 63   Create a new Tc
1270: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 20 61 6e  l interpreter an
1280: 64 20 63 6f 6d 70 6c 65 74 65 6c 79 20 69 6e 69  d completely ini
1290: 74 69 61 6c 69 7a 65 20 69 74 0a 20 2a 2f 0a 73  tialize it. */.s
12a0: 74 61 74 69 63 20 54 63 6c 5f 49 6e 74 65 72 70  tatic Tcl_Interp
12b0: 20 2a 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54   *appfs_create_T
12c0: 63 6c 49 6e 74 65 72 70 28 63 68 61 72 20 2a 2a  clInterp(char **
12d0: 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a  error_string) {.
12e0: 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  .Tcl_Interp *int
12f0: 65 72 70 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65  erp;..int tcl_re
1300: 74 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a  t;..const char *
1310: 74 63 6c 5f 73 65 74 76 61 72 5f 72 65 74 3b 0a  tcl_setvar_ret;.
1320: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 43  ..APPFS_DEBUG("C
1330: 72 65 61 74 69 6e 67 20 6e 65 77 20 54 63 6c 20  reating new Tcl 
1340: 69 6e 74 65 72 70 72 65 74 65 72 20 66 6f 72 20  interpreter for 
1350: 54 49 44 20 3d 20 30 78 25 6c 6c 78 22 2c 20 28  TID = 0x%llx", (
1360: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
1370: 6e 67 29 20 70 74 68 72 65 61 64 5f 73 65 6c 66  ng) pthread_self
1380: 28 29 29 3b 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ());...appfs_cal
1390: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 69 6e 74 65  l_libtcl(...inte
13a0: 72 70 20 3d 20 54 63 6c 5f 43 72 65 61 74 65 49  rp = Tcl_CreateI
13b0: 6e 74 65 72 70 28 29 3b 0a 09 29 0a 09 69 66 20  nterp();..)..if 
13c0: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
13d0: 20 7b 0a 09 09 41 50 50 46 53 5f 45 52 52 4f 52   {...APPFS_ERROR
13e0: 28 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61  ("Unable to crea
13f0: 74 65 20 54 63 6c 20 49 6e 74 65 72 70 72 65 74  te Tcl Interpret
1400: 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 22 29  er.  Aborting.")
1410: 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73  ;....if (error_s
1420: 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72 72  tring) {....*err
1430: 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64  or_string = strd
1440: 75 70 28 22 55 6e 61 62 6c 65 20 74 6f 20 63 72  up("Unable to cr
1450: 65 61 74 65 20 54 63 6c 20 69 6e 74 65 72 70 72  eate Tcl interpr
1460: 65 74 65 72 2e 22 29 3b 0a 09 09 7d 0a 0a 09 09  eter.");...}....
1470: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
1480: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
1490: 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76  btcl(Tcl_Preserv
14a0: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 61 70  e(interp);)...ap
14b0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
14c0: 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
14d0: 5f 49 6e 69 74 28 69 6e 74 65 72 70 29 3b 0a 09  _Init(interp);..
14e0: 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  )..if (tcl_ret !
14f0: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50  = TCL_OK) {...AP
1500: 50 46 53 5f 45 52 52 4f 52 28 22 55 6e 61 62 6c  PFS_ERROR("Unabl
1510: 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20  e to initialize 
1520: 54 63 6c 2e 20 20 41 62 6f 72 74 69 6e 67 2e 22  Tcl.  Aborting."
1530: 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f  );...appfs_call_
1540: 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53  libtcl(....APPFS
1550: 5f 45 52 52 4f 52 28 22 54 63 6c 20 45 72 72 6f  _ERROR("Tcl Erro
1560: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
1570: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
1580: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09  nterp));...)....
1590: 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67  if (error_string
15a0: 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c  ) {....appfs_cal
15b0: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65  l_libtcl(.....*e
15c0: 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74  rror_string = st
15d0: 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69  rdup(Tcl_GetStri
15e0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
15f0: 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61  );....)...}....a
1600: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1610: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74  (Tcl_Release(int
1620: 65 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f  erp);)....APPFS_
1630: 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69  DEBUG("Terminati
1640: 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  ng Tcl interpret
1650: 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f  er.");....appfs_
1660: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
1670: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
1680: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e  erp);)....return
1690: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70  (NULL);..}...app
16a0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
16b0: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
16c0: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 70 61  Eval(interp, "pa
16d0: 63 6b 61 67 65 20 69 66 6e 65 65 64 65 64 20 73  ckage ifneeded s
16e0: 68 61 31 20 31 2e 30 20 5b 6c 69 73 74 20 6c 6f  ha1 1.0 [list lo
16f0: 61 64 20 7b 7d 20 73 68 61 31 5d 22 29 3b 0a 09  ad {} sha1]");..
1700: 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  )..if (tcl_ret !
1710: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50  = TCL_OK) {...AP
1720: 50 46 53 5f 45 52 52 4f 52 28 22 55 6e 61 62 6c  PFS_ERROR("Unabl
1730: 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20  e to initialize 
1740: 54 63 6c 20 53 48 41 31 2e 20 20 41 62 6f 72 74  Tcl SHA1.  Abort
1750: 69 6e 67 2e 22 29 3b 0a 09 09 61 70 70 66 73 5f  ing.");...appfs_
1760: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
1770: 41 50 50 46 53 5f 45 52 52 4f 52 28 22 54 63 6c  APPFS_ERROR("Tcl
1780: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20   Error is: %s", 
1790: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
17a0: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
17b0: 29 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73  )....if (error_s
17c0: 74 72 69 6e 67 29 20 7b 0a 09 09 09 61 70 70 66  tring) {....appf
17d0: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
17e0: 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67  ...*error_string
17f0: 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65   = strdup(Tcl_Ge
1800: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
1810: 74 65 72 70 29 29 3b 0a 09 09 09 29 0a 09 09 7d  terp));....)...}
1820: 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
1830: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
1840: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 41  e(interp);)....A
1850: 50 50 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d  PPFS_DEBUG("Term
1860: 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e 74 65  inating Tcl inte
1870: 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 61  rpreter.");....a
1880: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1890: 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72  (Tcl_DeleteInter
18a0: 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72  p(interp);)....r
18b0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
18c0: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
18d0: 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d  tcl(...tcl_ret =
18e0: 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70   Tcl_Eval(interp
18f0: 2c 20 22 70 61 63 6b 61 67 65 20 69 66 6e 65 65  , "package ifnee
1900: 64 65 64 20 61 70 70 66 73 64 20 31 2e 30 20 5b  ded appfsd 1.0 [
1910: 6c 69 73 74 20 6c 6f 61 64 20 7b 7d 20 61 70 70  list load {} app
1920: 66 73 64 5d 22 29 3b 0a 09 29 0a 09 69 66 20 28  fsd]");..)..if (
1930: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
1940: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 45 52 52  K) {...APPFS_ERR
1950: 4f 52 28 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e  OR("Unable to in
1960: 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 41 70 70  itialize Tcl App
1970: 46 53 20 50 61 63 6b 61 67 65 2e 20 20 41 62 6f  FS Package.  Abo
1980: 72 74 69 6e 67 2e 22 29 3b 0a 09 09 61 70 70 66  rting.");...appf
1990: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
19a0: 09 09 41 50 50 46 53 5f 45 52 52 4f 52 28 22 54  ..APPFS_ERROR("T
19b0: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22  cl Error is: %s"
19c0: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
19d0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
19e0: 09 09 29 0a 0a 09 09 69 66 20 28 65 72 72 6f 72  ..)....if (error
19f0: 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 61 70  _string) {....ap
1a00: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
1a10: 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69  .....*error_stri
1a20: 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f  ng = strdup(Tcl_
1a30: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
1a40: 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29 0a 09  interp));....)..
1a50: 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  .}....appfs_call
1a60: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
1a70: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
1a80: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 65  .APPFS_DEBUG("Te
1a90: 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e  rminating Tcl in
1aa0: 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09  terpreter.");...
1ab0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
1ac0: 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74  cl(Tcl_DeleteInt
1ad0: 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  erp(interp);)...
1ae0: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
1af0: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4c 6f 61 64 20  }.../*.. * Load 
1b00: 22 70 6b 69 2e 74 63 6c 22 20 69 6e 20 74 68 65  "pki.tcl" in the
1b10: 20 73 61 6d 65 20 77 61 79 20 61 73 20 61 70 70   same way as app
1b20: 66 73 64 2e 74 63 6c 20 28 73 65 65 20 62 65 6c  fsd.tcl (see bel
1b30: 6f 77 29 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f  ow).. */..appfs_
1b40: 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 6e 74 65  call_libtcl_ente
1b50: 72 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63  r...tcl_ret = Tc
1b60: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22  l_Eval(interp, "
1b70: 22 0a 23 69 6e 63 6c 75 64 65 20 22 70 6b 69 2e  ".#include "pki.
1b80: 74 63 6c 2e 68 22 0a 09 09 22 22 29 3b 0a 09 61  tcl.h"..."");..a
1b90: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1ba0: 5f 65 78 69 74 0a 09 69 66 20 28 74 63 6c 5f 72  _exit..if (tcl_r
1bb0: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
1bc0: 09 09 41 50 50 46 53 5f 45 52 52 4f 52 28 22 55  ..APPFS_ERROR("U
1bd0: 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c  nable to initial
1be0: 69 7a 65 20 54 63 6c 20 50 4b 49 2e 20 20 41 62  ize Tcl PKI.  Ab
1bf0: 6f 72 74 69 6e 67 2e 22 29 3b 0a 09 09 61 70 70  orting.");...app
1c00: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a  fs_call_libtcl(.
1c10: 09 09 09 41 50 50 46 53 5f 45 52 52 4f 52 28 22  ...APPFS_ERROR("
1c20: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
1c30: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
1c40: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
1c50: 0a 09 09 29 0a 0a 09 09 69 66 20 28 65 72 72 6f  ...)....if (erro
1c60: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 61  r_string) {....a
1c70: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1c80: 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74 72  (.....*error_str
1c90: 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c  ing = strdup(Tcl
1ca0: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
1cb0: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29 0a  (interp));....).
1cc0: 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c  ..}....appfs_cal
1cd0: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
1ce0: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
1cf0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
1d00: 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20 69  erminating Tcl i
1d10: 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a  nterpreter.");..
1d20: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
1d30: 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e  tcl(Tcl_DeleteIn
1d40: 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a  terp(interp);)..
1d50: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
1d60: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4c 6f 61 64  .}.../*.. * Load
1d70: 20 74 68 65 20 22 61 70 70 66 73 64 2e 74 63 6c   the "appfsd.tcl
1d80: 22 20 73 63 72 69 70 74 2c 20 77 68 69 63 68 20  " script, which 
1d90: 69 73 20 22 63 6f 6d 70 69 6c 65 64 22 20 69 6e  is "compiled" in
1da0: 74 6f 20 61 20 43 20 68 65 61 64 65 72 0a 09 20  to a C header.. 
1db0: 2a 20 73 6f 20 74 68 61 74 20 69 74 20 64 6f 65  * so that it doe
1dc0: 73 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 65 78  s not need to ex
1dd0: 69 73 74 20 6f 6e 20 74 68 65 20 66 69 6c 65 73  ist on the files
1de0: 79 73 74 65 6d 20 61 6e 64 20 63 61 6e 20 62 65  ystem and can be
1df0: 0a 09 20 2a 20 64 69 72 65 63 74 6c 79 20 65 76  .. * directly ev
1e00: 61 6c 75 61 74 65 64 2e 0a 09 20 2a 2f 0a 09 61  aluated... */..a
1e10: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
1e20: 5f 65 6e 74 65 72 0a 09 09 74 63 6c 5f 72 65 74  _enter...tcl_ret
1e30: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65   = Tcl_Eval(inte
1e40: 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64 65 20  rp, "".#include 
1e50: 22 61 70 70 66 73 64 2e 74 63 6c 2e 68 22 0a 09  "appfsd.tcl.h"..
1e60: 09 22 22 29 3b 0a 09 61 70 70 66 73 5f 63 61 6c  ."");..appfs_cal
1e70: 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74 0a 09 69  l_libtcl_exit..i
1e80: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
1e90: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
1ea0: 45 52 52 4f 52 28 22 55 6e 61 62 6c 65 20 74 6f  ERROR("Unable to
1eb0: 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20   initialize Tcl 
1ec0: 41 70 70 46 53 20 73 63 72 69 70 74 2e 20 20 41  AppFS script.  A
1ed0: 62 6f 72 74 69 6e 67 2e 22 29 3b 0a 09 09 61 70  borting.");...ap
1ee0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
1ef0: 0a 09 09 09 41 50 50 46 53 5f 45 52 52 4f 52 28  ....APPFS_ERROR(
1f00: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
1f10: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
1f20: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
1f30: 3b 0a 09 09 29 0a 0a 09 09 69 66 20 28 65 72 72  ;...)....if (err
1f40: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09  or_string) {....
1f50: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
1f60: 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74  l(.....*error_st
1f70: 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63  ring = strdup(Tc
1f80: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
1f90: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29  t(interp));....)
1fa0: 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61  ...}....appfs_ca
1fb0: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65  ll_libtcl(Tcl_Re
1fc0: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a  lease(interp);).
1fd0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
1fe0: 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20  Terminating Tcl 
1ff0: 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a  interpreter.");.
2000: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
2010: 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49  btcl(Tcl_DeleteI
2020: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a  nterp(interp);).
2030: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
2040: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65 74  ..}.../*.. * Set
2050: 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65   global variable
2060: 73 20 66 72 6f 6d 20 43 20 74 6f 20 54 63 6c 0a  s from C to Tcl.
2070: 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c  . */..appfs_call
2080: 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 73  _libtcl(...tcl_s
2090: 65 74 76 61 72 5f 72 65 74 20 3d 20 54 63 6c 5f  etvar_ret = Tcl_
20a0: 53 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22  SetVar(interp, "
20b0: 3a 3a 61 70 70 66 73 3a 3a 63 61 63 68 65 64 69  ::appfs::cachedi
20c0: 72 22 2c 20 61 70 70 66 73 5f 63 61 63 68 65 64  r", appfs_cached
20d0: 69 72 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f  ir, TCL_GLOBAL_O
20e0: 4e 4c 59 29 3b 0a 09 29 0a 09 69 66 20 28 74 63  NLY);..)..if (tc
20f0: 6c 5f 73 65 74 76 61 72 5f 72 65 74 20 3d 3d 20  l_setvar_ret == 
2100: 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f  NULL) {...APPFS_
2110: 45 52 52 4f 52 28 22 55 6e 61 62 6c 65 20 74 6f  ERROR("Unable to
2120: 20 73 65 74 20 63 61 63 68 65 20 64 69 72 65 63   set cache direc
2130: 74 6f 72 79 2e 20 20 54 68 69 73 20 73 68 6f 75  tory.  This shou
2140: 6c 64 20 6e 65 76 65 72 20 66 61 69 6c 2e 22 29  ld never fail.")
2150: 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73  ;....if (error_s
2160: 74 72 69 6e 67 29 20 7b 0a 09 09 09 61 70 70 66  tring) {....appf
2170: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
2180: 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67  ...*error_string
2190: 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65   = strdup(Tcl_Ge
21a0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
21b0: 74 65 72 70 29 29 3b 0a 09 09 09 29 0a 09 09 7d  terp));....)...}
21c0: 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ....appfs_call_l
21d0: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
21e0: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 41  e(interp);)....A
21f0: 50 50 46 53 5f 44 45 42 55 47 28 22 54 65 72 6d  PPFS_DEBUG("Term
2200: 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 6e 74 65  inating Tcl inte
2210: 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09 09 61  rpreter.");....a
2220: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
2230: 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72  (Tcl_DeleteInter
2240: 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72  p(interp);)....r
2250: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
2260: 0a 09 2f 2a 0a 09 20 2a 20 49 6e 69 74 69 61 6c  ../*.. * Initial
2270: 69 7a 65 20 74 68 65 20 22 61 70 70 66 73 64 2e  ize the "appfsd.
2280: 74 63 6c 22 20 65 6e 76 69 72 6f 6e 6d 65 6e 74  tcl" environment
2290: 2c 20 77 68 69 63 68 20 6d 75 73 74 20 62 65 20  , which must be 
22a0: 64 6f 6e 65 20 61 66 74 65 72 0a 09 20 2a 20 67  done after.. * g
22b0: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20  lobal variables 
22c0: 61 72 65 20 73 65 74 2e 0a 09 20 2a 2f 0a 09 61  are set... */..a
22d0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
22e0: 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63  (...tcl_ret = Tc
22f0: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22  l_Eval(interp, "
2300: 3a 3a 61 70 70 66 73 3a 3a 69 6e 69 74 22 29 3b  ::appfs::init");
2310: 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ..)..if (tcl_ret
2320: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
2330: 41 50 50 46 53 5f 45 52 52 4f 52 28 22 55 6e 61  APPFS_ERROR("Una
2340: 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a  ble to initializ
2350: 65 20 54 63 6c 20 41 70 70 46 53 20 73 63 72 69  e Tcl AppFS scri
2360: 70 74 20 28 3a 3a 61 70 70 66 73 3a 3a 69 6e 69  pt (::appfs::ini
2370: 74 29 2e 20 20 41 62 6f 72 74 69 6e 67 2e 22 29  t).  Aborting.")
2380: 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  ;...appfs_call_l
2390: 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f  ibtcl(....APPFS_
23a0: 45 52 52 4f 52 28 22 54 63 6c 20 45 72 72 6f 72  ERROR("Tcl Error
23b0: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
23c0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
23d0: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69  terp));...)....i
23e0: 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29  f (error_string)
23f0: 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c   {....appfs_call
2400: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72  _libtcl(.....*er
2410: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
2420: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
2430: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
2440: 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70  ;....)...}....ap
2450: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
2460: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
2470: 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44  rp);)....APPFS_D
2480: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e  EBUG("Terminatin
2490: 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  g Tcl interprete
24a0: 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63  r.");....appfs_c
24b0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44  all_libtcl(Tcl_D
24c0: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65  eleteInterp(inte
24d0: 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28  rp);)....return(
24e0: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  NULL);..}.../*..
24f0: 20 2a 20 48 69 64 65 20 73 6f 6d 65 20 54 63 6c   * Hide some Tcl
2500: 20 63 6f 6d 6d 61 6e 64 73 20 74 68 61 74 20 77   commands that w
2510: 65 20 64 6f 20 6e 6f 74 20 63 61 72 65 20 74 6f  e do not care to
2520: 20 75 73 65 20 61 6e 64 20 77 68 69 63 68 20 6d   use and which m
2530: 61 79 0a 09 20 2a 20 73 6c 6f 77 20 64 6f 77 6e  ay.. * slow down
2540: 20 72 75 6e 2d 74 69 6d 65 20 6f 70 65 72 61 74   run-time operat
2550: 69 6f 6e 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 66  ions... */..appf
2560: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
2570: 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61 6e 64  .Tcl_HideCommand
2580: 28 69 6e 74 65 72 70 2c 20 22 61 75 74 6f 5f 6c  (interp, "auto_l
2590: 6f 61 64 5f 69 6e 64 65 78 22 2c 20 22 61 75 74  oad_index", "aut
25a0: 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22 29 3b 0a  o_load_index");.
25b0: 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61 6e  ..Tcl_HideComman
25c0: 64 28 69 6e 74 65 72 70 2c 20 22 75 6e 6b 6e 6f  d(interp, "unkno
25d0: 77 6e 22 2c 20 22 75 6e 6b 6e 6f 77 6e 22 29 3b  wn", "unknown");
25e0: 0a 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61  ...Tcl_HideComma
25f0: 6e 64 28 69 6e 74 65 72 70 2c 20 22 65 78 69 74  nd(interp, "exit
2600: 22 2c 20 22 65 78 69 74 22 29 3b 0a 09 29 0a 0a  ", "exit");..)..
2610: 09 2f 2a 0a 09 20 2a 20 52 65 6c 65 61 73 65 20  ./*.. * Release 
2620: 74 68 65 20 68 6f 6c 64 20 77 65 20 68 61 76 65  the hold we have
2630: 20 6f 6e 20 74 68 65 20 69 6e 74 65 72 70 72 65   on the interpre
2640: 74 65 72 20 73 6f 20 74 68 61 74 20 69 74 20 6d  ter so that it m
2650: 61 79 20 62 65 0a 09 20 2a 20 64 65 6c 65 74 65  ay be.. * delete
2660: 64 20 69 66 20 6e 65 65 64 65 64 0a 09 20 2a 2f  d if needed.. */
2670: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
2680: 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28  tcl(Tcl_Release(
2690: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 2f 2a 0a 09  interp);).../*..
26a0: 20 2a 20 52 65 74 75 72 6e 20 74 68 65 20 63 6f   * Return the co
26b0: 6d 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61 6c  mpletely initial
26c0: 69 7a 65 64 20 69 6e 74 65 72 70 72 65 74 65 72  ized interpreter
26d0: 0a 09 20 2a 2f 0a 09 72 65 74 75 72 6e 28 69 6e  .. */..return(in
26e0: 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  terp);.}../*. * 
26f0: 52 65 74 75 72 6e 20 74 68 65 20 74 68 72 65 61  Return the threa
2700: 64 2d 73 70 65 63 69 66 69 63 20 54 63 6c 20 69  d-specific Tcl i
2710: 6e 74 65 72 70 72 65 74 65 72 2c 20 63 72 65 61  nterpreter, crea
2720: 74 69 6e 67 20 69 74 20 69 66 20 6e 65 65 64 65  ting it if neede
2730: 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 54 63 6c  d. */.static Tcl
2740: 5f 49 6e 74 65 72 70 20 2a 61 70 70 66 73 5f 54  _Interp *appfs_T
2750: 63 6c 49 6e 74 65 72 70 28 76 6f 69 64 29 20 7b  clInterp(void) {
2760: 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  ..Tcl_Interp *in
2770: 74 65 72 70 3b 0a 09 69 6e 74 20 70 74 68 72 65  terp;..int pthre
2780: 61 64 5f 72 65 74 3b 0a 09 73 74 61 74 69 63 20  ad_ret;..static 
2790: 5f 5f 74 68 72 65 61 64 20 69 6e 74 20 74 68 72  __thread int thr
27a0: 65 61 64 5f 69 6e 74 65 72 70 5f 72 65 73 65 74  ead_interp_reset
27b0: 5f 6b 65 79 20 3d 20 30 3b 0a 09 69 6e 74 20 67  _key = 0;..int g
27c0: 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73  lobal_interp_res
27d0: 65 74 5f 6b 65 79 3b 0a 0a 09 67 6c 6f 62 61 6c  et_key;...global
27e0: 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65  _interp_reset_ke
27f0: 79 20 3d 20 5f 5f 73 79 6e 63 5f 66 65 74 63 68  y = __sync_fetch
2800: 5f 61 6e 64 5f 61 64 64 28 26 69 6e 74 65 72 70  _and_add(&interp
2810: 5f 72 65 73 65 74 5f 6b 65 79 2c 20 30 29 3b 0a  _reset_key, 0);.
2820: 0a 09 69 6e 74 65 72 70 20 3d 20 70 74 68 72 65  ..interp = pthre
2830: 61 64 5f 67 65 74 73 70 65 63 69 66 69 63 28 69  ad_getspecific(i
2840: 6e 74 65 72 70 4b 65 79 29 3b 0a 09 69 66 20 28  nterpKey);..if (
2850: 69 6e 74 65 72 70 20 21 3d 20 4e 55 4c 4c 20 26  interp != NULL &
2860: 26 20 74 68 72 65 61 64 5f 69 6e 74 65 72 70 5f  & thread_interp_
2870: 72 65 73 65 74 5f 6b 65 79 20 21 3d 20 67 6c 6f  reset_key != glo
2880: 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74  bal_interp_reset
2890: 5f 6b 65 79 29 20 7b 0a 09 09 41 50 50 46 53 5f  _key) {...APPFS_
28a0: 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69  DEBUG("Terminati
28b0: 6e 67 20 6f 6c 64 20 69 6e 74 65 72 70 72 65 74  ng old interpret
28c0: 65 72 20 61 6e 64 20 72 65 73 74 61 72 74 69 6e  er and restartin
28d0: 67 20 64 75 65 20 74 6f 20 72 65 73 65 74 20 72  g due to reset r
28e0: 65 71 75 65 73 74 2e 22 29 3b 0a 0a 09 09 61 70  equest.");....ap
28f0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
2900: 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70  Tcl_DeleteInterp
2910: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 69 6e  (interp);)....in
2920: 74 65 72 70 20 3d 20 4e 55 4c 4c 3b 0a 0a 09 09  terp = NULL;....
2930: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
2940: 68 72 65 61 64 5f 73 65 74 73 70 65 63 69 66 69  hread_setspecifi
2950: 63 28 69 6e 74 65 72 70 4b 65 79 2c 20 69 6e 74  c(interpKey, int
2960: 65 72 70 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 67  erp);..}...if (g
2970: 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73  lobal_interp_res
2980: 65 74 5f 6b 65 79 20 3d 3d 20 2d 31 29 20 7b 0a  et_key == -1) {.
2990: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 52  ..APPFS_DEBUG("R
29a0: 65 74 75 72 6e 69 6e 67 20 4e 55 4c 4c 20 73 69  eturning NULL si
29b0: 6e 63 65 20 77 65 20 61 72 65 20 69 6e 20 74 68  nce we are in th
29c0: 65 20 70 72 6f 63 65 73 73 20 6f 66 20 74 65 72  e process of ter
29d0: 6d 69 6e 61 74 69 6e 67 20 61 6c 6c 20 74 68 72  minating all thr
29e0: 65 61 64 73 2e 22 29 3b 0a 0a 09 09 72 65 74 75  eads.");....retu
29f0: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74  rn(NULL);..}...t
2a00: 68 72 65 61 64 5f 69 6e 74 65 72 70 5f 72 65 73  hread_interp_res
2a10: 65 74 5f 6b 65 79 20 3d 20 67 6c 6f 62 61 6c 5f  et_key = global_
2a20: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
2a30: 3b 0a 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  ;...if (interp =
2a40: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 6e 74 65  = NULL) {...inte
2a50: 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61 74  rp = appfs_creat
2a60: 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c 4c  e_TclInterp(NULL
2a70: 29 3b 0a 0a 09 09 69 66 20 28 69 6e 74 65 72 70  );....if (interp
2a80: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 41   == NULL) {....A
2a90: 50 50 46 53 5f 44 45 42 55 47 28 22 43 72 65 61  PPFS_DEBUG("Crea
2aa0: 74 65 20 69 6e 74 65 72 70 20 66 61 69 6c 65 64  te interp failed
2ab0: 2c 20 72 65 74 75 72 6e 69 6e 67 20 69 6e 20 66  , returning in f
2ac0: 61 69 6c 75 72 65 2e 22 29 3b 0a 0a 09 09 09 72  ailure.");.....r
2ad0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d  eturn(NULL);...}
2ae0: 0a 0a 09 09 70 74 68 72 65 61 64 5f 72 65 74 20  ....pthread_ret 
2af0: 3d 20 70 74 68 72 65 61 64 5f 73 65 74 73 70 65  = pthread_setspe
2b00: 63 69 66 69 63 28 69 6e 74 65 72 70 4b 65 79 2c  cific(interpKey,
2b10: 20 69 6e 74 65 72 70 29 3b 0a 09 09 69 66 20 28   interp);...if (
2b20: 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30  pthread_ret != 0
2b30: 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42  ) {....APPFS_DEB
2b40: 55 47 28 22 70 74 68 72 65 61 64 5f 73 65 74 73  UG("pthread_sets
2b50: 70 65 63 69 66 69 63 28 29 20 66 61 69 6c 65 64  pecific() failed
2b60: 2e 20 20 54 65 72 6d 69 6e 61 74 69 6e 67 20 54  .  Terminating T
2b70: 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22  cl interpreter."
2b80: 29 3b 0a 0a 09 09 09 61 70 70 66 73 5f 63 61 6c  );.....appfs_cal
2b90: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c  l_libtcl(Tcl_Del
2ba0: 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70  eteInterp(interp
2bb0: 29 3b 29 0a 0a 09 09 09 72 65 74 75 72 6e 28 4e  );).....return(N
2bc0: 55 4c 4c 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72  ULL);...}..}...r
2bd0: 65 74 75 72 6e 28 69 6e 74 65 72 70 29 3b 0a 7d  eturn(interp);.}
2be0: 0a 0a 2f 2a 0a 20 2a 20 45 76 61 6c 75 61 74 65  ../*. * Evaluate
2bf0: 20 61 20 54 63 6c 20 73 63 72 69 70 74 20 63 6f   a Tcl script co
2c00: 6e 73 74 72 75 63 74 65 64 20 62 79 20 63 6f 6e  nstructed by con
2c10: 63 61 74 65 6e 61 74 69 6e 67 20 61 20 62 75 6e  catenating a bun
2c20: 63 68 20 6f 66 20 43 20 73 74 72 69 6e 67 73 0a  ch of C strings.
2c30: 20 2a 20 74 6f 67 65 74 68 65 72 2e 0a 20 2a 2f   * together.. */
2c40: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
2c50: 73 5f 54 63 6c 5f 45 76 61 6c 28 54 63 6c 5f 49  s_Tcl_Eval(Tcl_I
2c60: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69  nterp *interp, i
2c70: 6e 74 20 6f 62 6a 63 2c 20 63 6f 6e 73 74 20 63  nt objc, const c
2c80: 68 61 72 20 2a 63 6d 64 2c 20 2e 2e 2e 29 20 7b  har *cmd, ...) {
2c90: 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a 6f 62 6a 76  ..Tcl_Obj **objv
2ca0: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 61  ;..const char *a
2cb0: 72 67 3b 0a 09 76 61 5f 6c 69 73 74 20 61 72 67  rg;..va_list arg
2cc0: 70 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a  p;..int retval;.
2cd0: 09 69 6e 74 20 69 3b 0a 0a 09 69 66 20 28 69 6e  .int i;...if (in
2ce0: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
2cf0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 49  ..APPFS_DEBUG("I
2d00: 6e 76 61 6c 69 64 20 69 6e 74 65 72 70 72 65 74  nvalid interpret
2d10: 65 72 20 70 61 73 73 65 64 20 69 6e 2c 20 72 65  er passed in, re
2d20: 74 75 72 6e 69 6e 67 20 69 6e 20 66 61 69 6c 75  turning in failu
2d30: 72 65 2e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  re.");....return
2d40: 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a  (TCL_ERROR);..}.
2d50: 0a 09 6f 62 6a 76 20 3d 20 28 76 6f 69 64 20 2a  ..objv = (void *
2d60: 29 20 63 6b 61 6c 6c 6f 63 28 73 69 7a 65 6f 66  ) ckalloc(sizeof
2d70: 28 2a 6f 62 6a 76 29 20 2a 20 6f 62 6a 63 29 3b  (*objv) * objc);
2d80: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
2d90: 62 74 63 6c 28 0a 09 09 6f 62 6a 76 5b 30 5d 20  btcl(...objv[0] 
2da0: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
2db0: 62 6a 28 63 6d 64 2c 20 2d 31 29 3b 0a 0a 09 09  bj(cmd, -1);....
2dc0: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74  Tcl_IncrRefCount
2dd0: 28 6f 62 6a 76 5b 30 5d 29 3b 0a 0a 09 09 76 61  (objv[0]);....va
2de0: 5f 73 74 61 72 74 28 61 72 67 70 2c 20 63 6d 64  _start(argp, cmd
2df0: 29 3b 0a 09 09 66 6f 72 20 28 69 20 3d 20 31 3b  );...for (i = 1;
2e00: 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29 20   i < objc; i++) 
2e10: 7b 0a 09 09 09 61 72 67 20 3d 20 76 61 5f 61 72  {....arg = va_ar
2e20: 67 28 61 72 67 70 2c 20 63 6f 6e 73 74 20 63 68  g(argp, const ch
2e30: 61 72 20 2a 29 3b 0a 0a 09 09 09 6f 62 6a 76 5b  ar *);.....objv[
2e40: 69 5d 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69  i] = Tcl_NewStri
2e50: 6e 67 4f 62 6a 28 61 72 67 2c 20 2d 31 29 3b 0a  ngObj(arg, -1);.
2e60: 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43  ....Tcl_IncrRefC
2e70: 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09  ount(objv[i]);..
2e80: 09 7d 0a 09 09 76 61 5f 65 6e 64 28 61 72 67 70  .}...va_end(argp
2e90: 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61  );..)...appfs_ca
2ea0: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 74  ll_libtcl(...ret
2eb0: 76 61 6c 20 3d 20 54 63 6c 5f 45 76 61 6c 4f 62  val = Tcl_EvalOb
2ec0: 6a 76 28 69 6e 74 65 72 70 2c 20 6f 62 6a 63 2c  jv(interp, objc,
2ed0: 20 6f 62 6a 76 2c 20 30 29 3b 0a 09 29 0a 0a 09   objv, 0);..)...
2ee0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
2ef0: 6c 28 0a 09 09 66 6f 72 20 28 69 20 3d 20 30 3b  l(...for (i = 0;
2f00: 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29 20   i < objc; i++) 
2f10: 7b 0a 09 09 09 54 63 6c 5f 44 65 63 72 52 65 66  {....Tcl_DecrRef
2f20: 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a  Count(objv[i]);.
2f30: 09 09 7d 0a 09 29 0a 0a 09 63 6b 66 72 65 65 28  ..}..)...ckfree(
2f40: 28 76 6f 69 64 20 2a 29 20 6f 62 6a 76 29 3b 0a  (void *) objv);.
2f50: 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20  ..if (retval != 
2f60: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 61 70 70 66  TCL_OK) {...appf
2f70: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09  s_call_libtcl(..
2f80: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
2f90: 63 6c 20 63 6f 6d 6d 61 6e 64 20 66 61 69 6c 65  cl command faile
2fa0: 64 2c 20 3a 3a 65 72 72 6f 72 49 6e 66 6f 20 63  d, ::errorInfo c
2fb0: 6f 6e 74 61 69 6e 73 3a 20 25 73 5c 6e 22 2c 20  ontains: %s\n", 
2fc0: 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72  Tcl_GetVar(inter
2fd0: 70 2c 20 22 3a 3a 65 72 72 6f 72 49 6e 66 6f 22  p, "::errorInfo"
2fe0: 2c 20 30 29 29 3b 0a 09 09 29 0a 09 7d 0a 0a 09  , 0));...)..}...
2ff0: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a  return(retval);.
3000: 7d 0a 0a 2f 2a 0a 20 2a 20 52 65 71 75 65 73 74  }../*. * Request
3010: 20 61 6c 6c 20 54 63 6c 20 69 6e 74 65 72 70 72   all Tcl interpr
3020: 65 74 65 72 73 20 72 65 73 74 61 72 74 0a 20 2a  eters restart. *
3030: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  /.static void ap
3040: 70 66 73 5f 74 63 6c 5f 52 65 73 65 74 49 6e 74  pfs_tcl_ResetInt
3050: 65 72 70 73 28 76 6f 69 64 29 20 7b 0a 09 41 50  erps(void) {..AP
3060: 50 46 53 5f 44 45 42 55 47 28 22 52 65 71 75 65  PFS_DEBUG("Reque
3070: 73 74 69 6e 67 20 72 65 73 65 74 20 6f 66 20 61  sting reset of a
3080: 6c 6c 20 69 6e 74 65 72 70 72 65 74 65 72 73 2e  ll interpreters.
3090: 22 29 3b 0a 0a 09 5f 5f 73 79 6e 63 5f 61 64 64  ");...__sync_add
30a0: 5f 61 6e 64 5f 66 65 74 63 68 28 26 69 6e 74 65  _and_fetch(&inte
30b0: 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 31 29  rp_reset_key, 1)
30c0: 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f  ;...return;.}../
30d0: 2a 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65 20 74  *. * Determine t
30e0: 68 65 20 55 49 44 20 66 6f 72 20 74 68 65 20 75  he UID for the u
30f0: 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 63  ser making the c
3100: 75 72 72 65 6e 74 20 46 55 53 45 20 66 69 6c 65  urrent FUSE file
3110: 73 79 73 74 65 6d 20 72 65 71 75 65 73 74 2e 0a  system request..
3120: 20 2a 20 54 68 69 73 20 77 69 6c 6c 20 62 65 20   * This will be 
3130: 75 73 65 64 20 74 6f 20 6c 6f 6f 6b 75 70 20 74  used to lookup t
3140: 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64  he user's home d
3150: 69 72 65 63 74 6f 72 79 20 73 6f 20 77 65 20 63  irectory so we c
3160: 61 6e 20 73 65 61 72 63 68 20 66 6f 72 0a 20 2a  an search for. *
3170: 20 6c 6f 63 61 6c 6c 79 20 6d 6f 64 69 66 69 65   locally modifie
3180: 64 20 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73 74 61  d files.. */.sta
3190: 74 69 63 20 75 69 64 5f 74 20 61 70 70 66 73 5f  tic uid_t appfs_
31a0: 67 65 74 5f 66 73 75 69 64 28 76 6f 69 64 29 20  get_fsuid(void) 
31b0: 7b 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f 63  {..struct fuse_c
31c0: 6f 6e 74 65 78 74 20 2a 63 74 78 3b 0a 0a 09 69  ontext *ctx;...i
31d0: 66 20 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73  f (!appfs_fuse_s
31e0: 74 61 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75  tarted) {...retu
31f0: 72 6e 28 67 65 74 75 69 64 28 29 29 3b 0a 09 7d  rn(getuid());..}
3200: 0a 0a 09 63 74 78 20 3d 20 66 75 73 65 5f 67 65  ...ctx = fuse_ge
3210: 74 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09 69 66  t_context();..if
3220: 20 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 20 7b   (ctx == NULL) {
3230: 0a 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74 6f 20  .../* Unable to 
3240: 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20  lookup user for 
3250: 73 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f 0a 09  some reason */..
3260: 09 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20 75 6e  ./* Return an un
3270: 70 72 69 76 69 6c 65 67 65 64 20 75 73 65 72 20  privileged user 
3280: 49 44 20 2a 2f 0a 09 09 41 50 50 46 53 5f 44 45  ID */...APPFS_DE
3290: 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c  BUG("Unable to l
32a0: 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20 73  ookup user for s
32b0: 6f 6d 65 20 72 65 61 73 6f 6e 2c 20 72 65 74 75  ome reason, retu
32c0: 72 6e 69 6e 6e 67 20 75 73 65 72 20 49 44 20 6f  rninng user ID o
32d0: 66 20 31 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  f 1");....return
32e0: 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  (1);..}...return
32f0: 28 63 74 78 2d 3e 75 69 64 29 3b 0a 7d 0a 0a 2f  (ctx->uid);.}../
3300: 2a 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65 20 74  *. * Determine t
3310: 68 65 20 47 49 44 20 66 6f 72 20 74 68 65 20 75  he GID for the u
3320: 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 63  ser making the c
3330: 75 72 72 65 6e 74 20 46 55 53 45 20 66 69 6c 65  urrent FUSE file
3340: 73 79 73 74 65 6d 20 72 65 71 75 65 73 74 2e 0a  system request..
3350: 20 2a 2f 0a 73 74 61 74 69 63 20 67 69 64 5f 74   */.static gid_t
3360: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64   appfs_get_fsgid
3370: 28 76 6f 69 64 29 20 7b 0a 09 73 74 72 75 63 74  (void) {..struct
3380: 20 66 75 73 65 5f 63 6f 6e 74 65 78 74 20 2a 63   fuse_context *c
3390: 74 78 3b 0a 0a 09 69 66 20 28 21 61 70 70 66 73  tx;...if (!appfs
33a0: 5f 66 75 73 65 5f 73 74 61 72 74 65 64 29 20 7b  _fuse_started) {
33b0: 0a 09 09 72 65 74 75 72 6e 28 67 65 74 67 69 64  ...return(getgid
33c0: 28 29 29 3b 0a 09 7d 0a 0a 09 63 74 78 20 3d 20  ());..}...ctx = 
33d0: 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74 65 78 74  fuse_get_context
33e0: 28 29 3b 0a 09 69 66 20 28 63 74 78 20 3d 3d 20  ();..if (ctx == 
33f0: 4e 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20 55 6e 61  NULL) {.../* Una
3400: 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 75 73  ble to lookup us
3410: 65 72 20 66 6f 72 20 73 6f 6d 65 20 72 65 61 73  er for some reas
3420: 6f 6e 20 2a 2f 0a 09 09 2f 2a 20 52 65 74 75 72  on */.../* Retur
3430: 6e 20 61 6e 20 75 6e 70 72 69 76 69 6c 65 67 65  n an unprivilege
3440: 64 20 75 73 65 72 20 49 44 20 2a 2f 0a 09 09 41  d user ID */...A
3450: 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62  PPFS_DEBUG("Unab
3460: 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70 20 67 72 6f  le to lookup gro
3470: 75 70 20 66 6f 72 20 73 6f 6d 65 20 72 65 61 73  up for some reas
3480: 6f 6e 2c 20 72 65 74 75 72 6e 69 6e 6e 67 20 67  on, returninng g
3490: 72 6f 75 70 20 49 44 20 6f 66 20 31 22 29 3b 0a  roup ID of 1");.
34a0: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
34b0: 0a 0a 09 72 65 74 75 72 6e 28 63 74 78 2d 3e 67  ...return(ctx->g
34c0: 69 64 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  id);.}..static v
34d0: 6f 69 64 20 61 70 70 66 73 5f 73 69 6d 75 6c 61  oid appfs_simula
34e0: 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72  te_user_fs_enter
34f0: 28 76 6f 69 64 29 20 7b 0a 09 73 65 74 66 73 75  (void) {..setfsu
3500: 69 64 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75  id(appfs_get_fsu
3510: 69 64 28 29 29 3b 0a 09 73 65 74 66 73 67 69 64  id());..setfsgid
3520: 28 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64  (appfs_get_fsgid
3530: 28 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76  ());.}..static v
3540: 6f 69 64 20 61 70 70 66 73 5f 73 69 6d 75 6c 61  oid appfs_simula
3550: 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65  te_user_fs_leave
3560: 28 76 6f 69 64 29 20 7b 0a 09 73 65 74 66 73 75  (void) {..setfsu
3570: 69 64 28 30 29 3b 0a 09 73 65 74 66 73 67 69 64  id(0);..setfsgid
3580: 28 30 29 3b 0a 7d 0a 0a 23 69 66 64 65 66 20 41  (0);.}..#ifdef A
3590: 50 50 46 53 5f 4e 4f 5f 47 45 54 50 57 55 49 44  PPFS_NO_GETPWUID
35a0: 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 61 70  .static char *ap
35b0: 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28  pfs_get_homedir(
35c0: 75 69 64 5f 74 20 66 73 75 69 64 29 20 7b 0a 09  uid_t fsuid) {..
35d0: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 7d 0a  return(NULL);.}.
35e0: 23 65 6c 73 65 0a 2f 2a 0a 20 2a 20 4c 6f 6f 6b  #else./*. * Look
35f0: 20 75 70 20 74 68 65 20 68 6f 6d 65 20 64 69 72   up the home dir
3600: 65 63 74 6f 72 79 20 66 6f 72 20 61 20 67 69 76  ectory for a giv
3610: 65 6e 20 55 49 44 0a 20 2a 20 20 20 20 20 20 20  en UID. *       
3620: 20 52 65 74 75 72 6e 73 20 61 20 43 20 73 74 72   Returns a C str
3630: 69 6e 67 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74  ing containing t
3640: 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64  he user's home d
3650: 69 72 65 63 74 6f 72 79 20 6f 72 20 4e 55 4c 4c  irectory or NULL
3660: 20 69 66 0a 20 2a 20 20 20 20 20 20 20 20 74 68   if. *        th
3670: 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64 69  e user's home di
3680: 72 65 63 74 6f 72 79 20 64 6f 65 73 20 6e 6f 74  rectory does not
3690: 20 65 78 69 73 74 20 6f 72 20 69 73 20 6e 6f 74   exist or is not
36a0: 20 63 6f 72 72 65 63 74 6c 79 0a 20 2a 20 20 20   correctly. *   
36b0: 20 20 20 20 20 63 6f 6e 66 69 67 75 72 65 64 0a       configured.
36c0: 20 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20   */.static char 
36d0: 2a 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64  *appfs_get_homed
36e0: 69 72 28 75 69 64 5f 74 20 66 73 75 69 64 29 20  ir(uid_t fsuid) 
36f0: 7b 0a 09 73 74 72 75 63 74 20 70 61 73 73 77 64  {..struct passwd
3700: 20 65 6e 74 72 79 2c 20 2a 72 65 73 75 6c 74 3b   entry, *result;
3710: 0a 09 73 74 72 75 63 74 20 73 74 61 74 20 73 74  ..struct stat st
3720: 62 75 66 3b 0a 09 63 68 61 72 20 62 75 66 5b 31  buf;..char buf[1
3730: 30 32 34 5d 2c 20 2a 72 65 74 76 61 6c 3b 0a 09  024], *retval;..
3740: 69 6e 74 20 67 70 75 5f 72 65 74 2c 20 73 74 61  int gpu_ret, sta
3750: 74 5f 72 65 74 3b 0a 0a 09 67 70 75 5f 72 65 74  t_ret;...gpu_ret
3760: 20 3d 20 67 65 74 70 77 75 69 64 5f 72 28 66 73   = getpwuid_r(fs
3770: 75 69 64 2c 20 26 65 6e 74 72 79 2c 20 62 75 66  uid, &entry, buf
3780: 2c 20 73 69 7a 65 6f 66 28 62 75 66 29 2c 20 26  , sizeof(buf), &
3790: 72 65 73 75 6c 74 29 3b 0a 09 69 66 20 28 67 70  result);..if (gp
37a0: 75 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  u_ret != 0) {...
37b0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 67 65 74  APPFS_DEBUG("get
37c0: 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e  pwuid_r(%llu, ..
37d0: 2e 29 20 72 65 74 75 72 6e 65 64 20 69 6e 20 66  .) returned in f
37e0: 61 69 6c 75 72 65 22 2c 20 28 75 6e 73 69 67 6e  ailure", (unsign
37f0: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73  ed long long) fs
3800: 75 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  uid);....return(
3810: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28  NULL);..}...if (
3820: 72 65 73 75 6c 74 20 3d 3d 20 4e 55 4c 4c 29 20  result == NULL) 
3830: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
3840: 22 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c 75  "getpwuid_r(%llu
3850: 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64 20  , ...) returned 
3860: 4e 55 4c 4c 20 72 65 73 75 6c 74 22 2c 20 28 75  NULL result", (u
3870: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e  nsigned long lon
3880: 67 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72 65  g) fsuid);....re
3890: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
38a0: 09 69 66 20 28 72 65 73 75 6c 74 2d 3e 70 77 5f  .if (result->pw_
38b0: 64 69 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  dir == NULL) {..
38c0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67 65  .APPFS_DEBUG("ge
38d0: 74 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e  tpwuid_r(%llu, .
38e0: 2e 2e 29 20 72 65 74 75 72 6e 65 64 20 4e 55 4c  ..) returned NUL
38f0: 4c 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79  L home directory
3900: 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e  ", (unsigned lon
3910: 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b 0a  g long) fsuid);.
3920: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
3930: 0a 09 7d 0a 0a 09 73 74 61 74 5f 72 65 74 20 3d  ..}...stat_ret =
3940: 20 73 74 61 74 28 72 65 73 75 6c 74 2d 3e 70 77   stat(result->pw
3950: 5f 64 69 72 2c 20 26 73 74 62 75 66 29 3b 0a 09  _dir, &stbuf);..
3960: 69 66 20 28 73 74 61 74 5f 72 65 74 20 21 3d 20  if (stat_ret != 
3970: 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  0) {...APPFS_DEB
3980: 55 47 28 22 73 74 61 74 28 25 73 29 20 72 65 74  UG("stat(%s) ret
3990: 75 72 6e 65 64 20 69 6e 20 66 61 69 6c 75 72 65  urned in failure
39a0: 22 2c 20 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69  ", result->pw_di
39b0: 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  r);....return(NU
39c0: 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 74  LL);..}...if (st
39d0: 62 75 66 2e 73 74 5f 75 69 64 20 21 3d 20 66 73  buf.st_uid != fs
39e0: 75 69 64 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  uid) {...APPFS_D
39f0: 45 42 55 47 28 22 55 49 44 20 6d 69 73 2d 6d 61  EBUG("UID mis-ma
3a00: 74 63 68 20 6f 6e 20 75 73 65 72 20 25 6c 6c 75  tch on user %llu
3a10: 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  's home director
3a20: 79 20 28 25 73 29 2e 20 20 49 74 27 73 20 6f 77  y (%s).  It's ow
3a30: 6e 65 64 20 62 79 20 25 6c 6c 75 2e 22 2c 0a 09  ned by %llu.",..
3a40: 09 20 20 20 20 28 75 6e 73 69 67 6e 65 64 20 6c  .    (unsigned l
3a50: 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 2c  ong long) fsuid,
3a60: 0a 09 09 20 20 20 20 72 65 73 75 6c 74 2d 3e 70  ...    result->p
3a70: 77 5f 64 69 72 2c 0a 09 09 20 20 20 20 28 75 6e  w_dir,...    (un
3a80: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
3a90: 29 20 73 74 62 75 66 2e 73 74 5f 75 69 64 0a 09  ) stbuf.st_uid..
3aa0: 09 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  .);....return(NU
3ab0: 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 76 61 6c  LL);..}...retval
3ac0: 20 3d 20 73 74 72 64 75 70 28 72 65 73 75 6c 74   = strdup(result
3ad0: 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09 72 65 74  ->pw_dir);...ret
3ae0: 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 23  urn(retval);.}.#
3af0: 65 6e 64 69 66 0a 0a 2f 2a 0a 20 2a 20 47 65 6e  endif../*. * Gen
3b00: 65 72 61 74 65 20 61 6e 20 69 6e 6f 64 65 20 66  erate an inode f
3b10: 6f 72 20 61 20 67 69 76 65 6e 20 70 61 74 68 2e  or a given path.
3b20: 20 20 54 68 65 20 69 6e 6f 64 65 20 73 68 6f 75    The inode shou
3b30: 6c 64 20 62 65 20 63 6f 6d 70 75 74 65 64 20 69  ld be computed i
3b40: 6e 20 73 75 63 68 0a 20 2a 20 61 20 77 61 79 20  n such. * a way 
3b50: 74 68 61 74 20 69 74 20 69 73 20 75 6e 6c 69 6b  that it is unlik
3b60: 65 6c 79 20 74 6f 20 62 65 20 64 75 70 6c 69 63  ely to be duplic
3b70: 61 74 65 64 20 61 6e 64 20 72 65 6d 61 69 6e 73  ated and remains
3b80: 20 74 68 65 20 73 61 6d 65 20 66 6f 72 20 61 20   the same for a 
3b90: 67 69 76 65 6e 0a 20 2a 20 66 69 6c 65 0a 20 2a  given. * file. *
3ba0: 0a 20 2a 20 43 75 72 72 65 6e 74 20 69 6d 70 6c  . * Current impl
3bb0: 65 6d 65 6e 74 61 74 69 6f 6e 20 69 73 20 61 6e  ementation is an
3bc0: 20 46 4e 56 2d 31 61 20 33 32 2d 62 69 74 0a 20   FNV-1a 32-bit. 
3bd0: 2a 2f 0a 23 69 66 20 55 49 4e 54 5f 4d 41 58 20  */.#if UINT_MAX 
3be0: 3c 20 34 32 39 34 39 36 37 32 39 35 0a 23 65 72  < 4294967295.#er
3bf0: 72 6f 72 20 49 6e 74 65 67 65 72 20 73 69 7a 65  ror Integer size
3c00: 20 69 73 20 74 6f 6f 20 73 6d 61 6c 6c 20 0a 23   is too small .#
3c10: 65 6e 64 69 66 0a 73 74 61 74 69 63 20 75 6e 73  endif.static uns
3c20: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 20  igned long long 
3c30: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
3c40: 6e 6f 64 65 28 63 6f 6e 73 74 20 63 68 61 72 20  node(const char 
3c50: 2a 70 61 74 68 2c 20 69 6e 74 20 75 69 64 29 20  *path, int uid) 
3c60: 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  {..unsigned int 
3c70: 72 65 74 76 61 6c 3b 0a 09 63 6f 6e 73 74 20 75  retval;..const u
3c80: 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 70 3b  nsigned char *p;
3c90: 0a 0a 09 72 65 74 76 61 6c 20 3d 20 32 31 36 36  ...retval = 2166
3ca0: 31 33 36 32 36 31 55 3b 20 2f 2a 20 46 4e 56 2d  136261U; /* FNV-
3cb0: 31 61 20 33 32 2d 62 69 74 20 6f 66 66 73 65 74  1a 32-bit offset
3cc0: 5f 62 61 73 69 73 20 2a 2f 0a 0a 09 66 6f 72 20  _basis */...for 
3cd0: 28 70 20 3d 20 28 75 6e 73 69 67 6e 65 64 20 63  (p = (unsigned c
3ce0: 68 61 72 20 2a 29 20 70 61 74 68 3b 20 2a 70 3b  har *) path; *p;
3cf0: 20 70 2b 2b 29 20 7b 0a 09 09 72 65 74 76 61 6c   p++) {...retval
3d00: 20 5e 3d 20 28 69 6e 74 29 20 2a 70 3b 0a 23 69   ^= (int) *p;.#i
3d10: 66 20 30 0a 09 09 72 65 74 76 61 6c 20 2a 3d 20  f 0...retval *= 
3d20: 31 36 37 37 37 36 31 39 3b 20 2f 2a 20 46 4e 56  16777619; /* FNV
3d30: 2d 31 61 20 33 32 2d 62 69 74 20 70 72 69 6d 65  -1a 32-bit prime
3d40: 20 2a 2f 0a 23 65 6c 73 65 0a 09 09 2f 2a 20 47   */.#else.../* G
3d50: 43 43 20 4f 70 74 69 6d 69 7a 65 64 20 72 65 70  CC Optimized rep
3d60: 6c 61 63 65 6d 65 6e 74 20 2a 2f 0a 09 09 72 65  lacement */...re
3d70: 74 76 61 6c 20 2b 3d 20 28 72 65 74 76 61 6c 20  tval += (retval 
3d80: 3c 3c 20 31 29 20 2b 20 28 72 65 74 76 61 6c 20  << 1) + (retval 
3d90: 3c 3c 20 34 29 20 2b 20 28 72 65 74 76 61 6c 20  << 4) + (retval 
3da0: 3c 3c 20 37 29 20 2b 20 28 72 65 74 76 61 6c 20  << 7) + (retval 
3db0: 3c 3c 20 38 29 20 2b 20 28 72 65 74 76 61 6c 20  << 8) + (retval 
3dc0: 3c 3c 20 32 34 29 3b 0a 23 65 6e 64 69 66 0a 09  << 24);.#endif..
3dd0: 7d 0a 0a 09 69 66 20 28 75 69 64 20 3e 3d 20 30  }...if (uid >= 0
3de0: 29 20 7b 0a 09 09 72 65 74 76 61 6c 20 2b 3d 20  ) {...retval += 
3df0: 75 69 64 3b 0a 09 09 72 65 74 76 61 6c 2b 2b 3b  uid;...retval++;
3e00: 0a 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  ..}...APPFS_DEBU
3e10: 47 28 22 4c 6f 6f 6b 65 64 20 75 70 20 69 6e 6f  G("Looked up ino
3e20: 64 65 20 6e 75 6d 62 65 72 20 66 6f 72 20 70 61  de number for pa
3e30: 74 68 3d 25 73 2c 75 69 64 3d 25 69 3a 20 25 75  th=%s,uid=%i: %u
3e40: 22 2c 20 70 61 74 68 2c 20 75 69 64 2c 20 72 65  ", path, uid, re
3e50: 74 76 61 6c 29 3b 0a 0a 09 72 65 74 75 72 6e 28  tval);...return(
3e60: 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20  retval);.}../*. 
3e70: 2a 20 43 61 63 68 65 20 47 65 74 20 50 61 74 68  * Cache Get Path
3e80: 20 49 6e 66 6f 20 6c 6f 6f 6b 75 70 73 20 66 6f   Info lookups fo
3e90: 72 20 73 70 65 65 64 0a 20 2a 2f 0a 73 74 61 74  r speed. */.stat
3ea0: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 67 65 74  ic int appfs_get
3eb0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
3ec0: 5f 67 65 74 28 63 6f 6e 73 74 20 63 68 61 72 20  _get(const char 
3ed0: 2a 70 61 74 68 2c 20 75 69 64 5f 74 20 75 69 64  *path, uid_t uid
3ee0: 2c 20 73 74 72 75 63 74 20 61 70 70 66 73 5f 70  , struct appfs_p
3ef0: 61 74 68 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66  athinfo *pathinf
3f00: 6f 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69  o) {..unsigned i
3f10: 6e 74 20 68 61 73 68 5f 69 64 78 3b 0a 09 69 6e  nt hash_idx;..in
3f20: 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 09  t pthread_ret;..
3f30: 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09 72 65  int retval;...re
3f40: 74 76 61 6c 20 3d 20 31 3b 0a 0a 09 70 74 68 72  tval = 1;...pthr
3f50: 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61  ead_ret = pthrea
3f60: 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70  d_mutex_lock(&ap
3f70: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
3f80: 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20  che_mutex);..if 
3f90: 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20  (pthread_ret != 
3fa0: 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  0) {...APPFS_DEB
3fb0: 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f  UG("Unable to lo
3fc0: 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63  ck path_info cac
3fd0: 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09  he mutex !");...
3fe0: 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a  .return(-1);..}.
3ff0: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 4c  ..APPFS_DEBUG("L
4000: 6f 6f 6b 69 6e 67 20 75 70 20 63 61 63 68 65 20  ooking up cache 
4010: 65 6e 74 72 79 20 66 6f 72 20 70 61 74 68 3d 25  entry for path=%
4020: 73 2c 75 69 64 3d 25 6c 6c 69 2e 2e 2e 22 2c 20  s,uid=%lli...", 
4030: 70 61 74 68 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67  path, (long long
4040: 29 20 75 69 64 29 3b 0a 0a 09 69 66 20 28 61 70  ) uid);...if (ap
4050: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4060: 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  che != NULL) {..
4070: 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61 70 70  .hash_idx = (app
4080: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64  fs_get_path_inod
4090: 65 28 70 61 74 68 2c 20 75 69 64 29 29 20 25 20  e(path, uid)) % 
40a0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
40b0: 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 09 69  cache_size;....i
40c0: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
40d0: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
40e0: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21  x]._cache_path !
40f0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 69 66 20  = NULL) {....if 
4100: 28 73 74 72 63 6d 70 28 61 70 70 66 73 5f 70 61  (strcmp(appfs_pa
4110: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61  th_info_cache[ha
4120: 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70  sh_idx]._cache_p
4130: 61 74 68 2c 20 70 61 74 68 29 20 3d 3d 20 30 20  ath, path) == 0 
4140: 26 26 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  && appfs_path_in
4150: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
4160: 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64 20 3d 3d  x]._cache_uid ==
4170: 20 75 69 64 29 20 7b 0a 09 09 09 09 72 65 74 76   uid) {.....retv
4180: 61 6c 20 3d 20 30 3b 0a 0a 09 09 09 09 6d 65 6d  al = 0;......mem
4190: 63 70 79 28 70 61 74 68 69 6e 66 6f 2c 20 26 61  cpy(pathinfo, &a
41a0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
41b0: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2c 20  ache[hash_idx], 
41c0: 73 69 7a 65 6f 66 28 2a 70 61 74 68 69 6e 66 6f  sizeof(*pathinfo
41d0: 29 29 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f  ));.....pathinfo
41e0: 2d 3e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20  ->_cache_path = 
41f0: 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09  NULL;....}...}..
4200: 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20  }...pthread_ret 
4210: 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  = pthread_mutex_
4220: 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61  unlock(&appfs_pa
4230: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75  th_info_cache_mu
4240: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65  tex);..if (pthre
4250: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
4260: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
4270: 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70  able to unlock p
4280: 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d  ath_info cache m
4290: 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74  utex !");....ret
42a0: 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66  urn(-1);..}...if
42b0: 20 28 72 65 74 76 61 6c 20 3d 3d 20 30 29 20 7b   (retval == 0) {
42c0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
42d0: 43 61 63 68 65 20 68 69 74 20 6f 6e 20 70 61 74  Cache hit on pat
42e0: 68 3d 25 73 2c 75 69 64 3d 25 6c 6c 69 22 2c 20  h=%s,uid=%lli", 
42f0: 70 61 74 68 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67  path, (long long
4300: 29 20 75 69 64 29 3b 0a 09 7d 20 65 6c 73 65 20  ) uid);..} else 
4310: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
4320: 22 43 61 63 68 65 20 6d 69 73 73 20 6f 6e 20 70  "Cache miss on p
4330: 61 74 68 3d 25 73 2c 75 69 64 3d 25 6c 6c 69 22  ath=%s,uid=%lli"
4340: 2c 20 70 61 74 68 2c 20 28 6c 6f 6e 67 20 6c 6f  , path, (long lo
4350: 6e 67 29 20 75 69 64 29 3b 0a 09 7d 0a 0a 09 72  ng) uid);..}...r
4360: 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d  eturn(retval);.}
4370: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  ..static void ap
4380: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
4390: 6f 5f 63 61 63 68 65 5f 61 64 64 28 63 6f 6e 73  o_cache_add(cons
43a0: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 75 69  t char *path, ui
43b0: 64 5f 74 20 75 69 64 2c 20 73 74 72 75 63 74 20  d_t uid, struct 
43c0: 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a  appfs_pathinfo *
43d0: 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 75 6e 73  pathinfo) {..uns
43e0: 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68 5f 69  igned int hash_i
43f0: 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64  dx;..int pthread
4400: 5f 72 65 74 3b 0a 0a 09 70 74 68 72 65 61 64 5f  _ret;...pthread_
4410: 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75  ret = pthread_mu
4420: 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f  tex_lock(&appfs_
4430: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
4440: 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68  mutex);..if (pth
4450: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  read_ret != 0) {
4460: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
4470: 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70  Unable to lock p
4480: 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d  ath_info cache m
4490: 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74  utex !");....ret
44a0: 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70  urn;..}...if (ap
44b0: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
44c0: 63 68 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  che == NULL) {..
44d0: 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  .appfs_path_info
44e0: 5f 63 61 63 68 65 20 3d 20 63 61 6c 6c 6f 63 28  _cache = calloc(
44f0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4500: 63 61 63 68 65 5f 73 69 7a 65 2c 20 73 69 7a 65  cache_size, size
4510: 6f 66 28 2a 61 70 70 66 73 5f 70 61 74 68 5f 69  of(*appfs_path_i
4520: 6e 66 6f 5f 63 61 63 68 65 29 29 3b 0a 09 7d 0a  nfo_cache));..}.
4530: 0a 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61 70  ..hash_idx = (ap
4540: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f  pfs_get_path_ino
4550: 64 65 28 70 61 74 68 2c 20 75 69 64 29 29 20 25  de(path, uid)) %
4560: 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f   appfs_path_info
4570: 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 69  _cache_size;...i
4580: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
4590: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
45a0: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21  x]._cache_path !
45b0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 72 65 65  = NULL) {...free
45c0: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  (appfs_path_info
45d0: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d  _cache[hash_idx]
45e0: 2e 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a 09  ._cache_path);..
45f0: 7d 0a 0a 09 6d 65 6d 63 70 79 28 26 61 70 70 66  }...memcpy(&appf
4600: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4610: 65 5b 68 61 73 68 5f 69 64 78 5d 2c 20 70 61 74  e[hash_idx], pat
4620: 68 69 6e 66 6f 2c 20 73 69 7a 65 6f 66 28 2a 70  hinfo, sizeof(*p
4630: 61 74 68 69 6e 66 6f 29 29 3b 0a 0a 09 61 70 70  athinfo));...app
4640: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4650: 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61  he[hash_idx]._ca
4660: 63 68 65 5f 70 61 74 68 20 3d 20 73 74 72 64 75  che_path = strdu
4670: 70 28 70 61 74 68 29 3b 0a 09 61 70 70 66 73 5f  p(path);..appfs_
4680: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b  path_info_cache[
4690: 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65  hash_idx]._cache
46a0: 5f 75 69 64 20 20 3d 20 75 69 64 3b 0a 0a 09 70  _uid  = uid;...p
46b0: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68  thread_ret = pth
46c0: 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63  read_mutex_unloc
46d0: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  k(&appfs_path_in
46e0: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b  fo_cache_mutex);
46f0: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65  ..if (pthread_re
4700: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46  t != 0) {...APPF
4710: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20  S_DEBUG("Unable 
4720: 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69  to unlock path_i
4730: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20  nfo cache mutex 
4740: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a  !");....return;.
4750: 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a  .}...return;.}..
4760: 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66  static void appf
4770: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
4780: 63 61 63 68 65 5f 72 6d 28 63 6f 6e 73 74 20 63  cache_rm(const c
4790: 68 61 72 20 2a 70 61 74 68 2c 20 75 69 64 5f 74  har *path, uid_t
47a0: 20 75 69 64 29 20 7b 0a 09 75 6e 73 69 67 6e 65   uid) {..unsigne
47b0: 64 20 69 6e 74 20 68 61 73 68 5f 69 64 78 3b 0a  d int hash_idx;.
47c0: 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74  .int pthread_ret
47d0: 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20  ;...pthread_ret 
47e0: 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  = pthread_mutex_
47f0: 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68  lock(&appfs_path
4800: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65  _info_cache_mute
4810: 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64  x);..if (pthread
4820: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41  _ret != 0) {...A
4830: 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62  PPFS_DEBUG("Unab
4840: 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f  le to lock path_
4850: 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78  info cache mutex
4860: 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b   !");....return;
4870: 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73 5f  ..}...if (appfs_
4880: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20  path_info_cache 
4890: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 61 73  != NULL) {...has
48a0: 68 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f 67  h_idx = (appfs_g
48b0: 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61  et_path_inode(pa
48c0: 74 68 2c 20 75 69 64 29 29 20 25 20 61 70 70 66  th, uid)) % appf
48d0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
48e0: 65 5f 73 69 7a 65 3b 0a 0a 09 09 69 66 20 28 61  e_size;....if (a
48f0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
4900: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f  ache[hash_idx]._
4910: 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e 55  cache_path != NU
4920: 4c 4c 29 20 7b 0a 09 09 09 66 72 65 65 28 61 70  LL) {....free(ap
4930: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
4940: 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63  che[hash_idx]._c
4950: 61 63 68 65 5f 70 61 74 68 29 3b 0a 0a 09 09 09  ache_path);.....
4960: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4970: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
4980: 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20 4e 55  _cache_path = NU
4990: 4c 4c 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 70 74 68  LL;...}..}...pth
49a0: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
49b0: 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28  ad_mutex_unlock(
49c0: 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  &appfs_path_info
49d0: 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09  _cache_mutex);..
49e0: 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20  if (pthread_ret 
49f0: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
4a00: 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f  DEBUG("Unable to
4a10: 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66   unlock path_inf
4a20: 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22  o cache mutex !"
4a30: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d  );....return;..}
4a40: 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74  ...return;.}..st
4a50: 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f  atic void appfs_
4a60: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
4a70: 63 68 65 5f 66 6c 75 73 68 28 75 69 64 5f 74 20  che_flush(uid_t 
4a80: 75 69 64 2c 20 69 6e 74 20 6e 65 77 5f 73 69 7a  uid, int new_siz
4a90: 65 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69  e) {..unsigned i
4aa0: 6e 74 20 69 64 78 3b 0a 09 69 6e 74 20 70 74 68  nt idx;..int pth
4ab0: 72 65 61 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46  read_ret;...APPF
4ac0: 53 5f 44 45 42 55 47 28 22 46 6c 75 73 68 69 6e  S_DEBUG("Flushin
4ad0: 67 20 41 70 70 46 53 20 63 61 63 68 65 20 28 75  g AppFS cache (u
4ae0: 69 64 20 3d 20 25 6c 6c 69 2c 20 6e 65 77 5f 73  id = %lli, new_s
4af0: 69 7a 65 20 3d 20 25 69 29 22 2c 20 28 6c 6f 6e  ize = %i)", (lon
4b00: 67 20 6c 6f 6e 67 29 20 75 69 64 2c 20 6e 65 77  g long) uid, new
4b10: 5f 73 69 7a 65 29 3b 0a 0a 09 70 74 68 72 65 61  _size);...pthrea
4b20: 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f  d_ret = pthread_
4b30: 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66  mutex_lock(&appf
4b40: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4b50: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70  e_mutex);..if (p
4b60: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
4b70: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
4b80: 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b  ("Unable to lock
4b90: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65   path_info cache
4ba0: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72   mutex !");....r
4bb0: 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28  eturn;..}...if (
4bc0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
4bd0: 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  cache != NULL) {
4be0: 0a 09 09 66 6f 72 20 28 69 64 78 20 3d 20 30 3b  ...for (idx = 0;
4bf0: 20 69 64 78 20 3c 20 61 70 70 66 73 5f 70 61 74   idx < appfs_pat
4c00: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a  h_info_cache_siz
4c10: 65 3b 20 69 64 78 2b 2b 29 20 7b 0a 09 09 09 69  e; idx++) {....i
4c20: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
4c30: 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f 63  fo_cache[idx]._c
4c40: 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e 55 4c  ache_path != NUL
4c50: 4c 29 20 7b 0a 09 09 09 09 69 66 20 28 75 69 64  L) {.....if (uid
4c60: 20 21 3d 20 28 28 75 69 64 5f 74 29 20 2d 31 29   != ((uid_t) -1)
4c70: 29 20 7b 0a 09 09 09 09 09 69 66 20 28 61 70 70  ) {......if (app
4c80: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
4c90: 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 75  he[idx]._cache_u
4ca0: 69 64 20 21 3d 20 75 69 64 29 20 7b 0a 09 09 09  id != uid) {....
4cb0: 09 09 09 63 6f 6e 74 69 6e 75 65 3b 0a 09 09 09  ...continue;....
4cc0: 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66  ..}.....}......f
4cd0: 72 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69  ree(appfs_path_i
4ce0: 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f  nfo_cache[idx]._
4cf0: 63 61 63 68 65 5f 70 61 74 68 29 3b 0a 0a 09 09  cache_path);....
4d00: 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  ..appfs_path_inf
4d10: 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61  o_cache[idx]._ca
4d20: 63 68 65 5f 70 61 74 68 20 3d 20 4e 55 4c 4c 3b  che_path = NULL;
4d30: 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a 0a 09 69  ....}...}..}...i
4d40: 66 20 28 75 69 64 20 3d 3d 20 28 28 75 69 64 5f  f (uid == ((uid_
4d50: 74 29 20 2d 31 29 29 20 7b 0a 09 09 66 72 65 65  t) -1)) {...free
4d60: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  (appfs_path_info
4d70: 5f 63 61 63 68 65 29 3b 0a 0a 09 09 61 70 70 66  _cache);....appf
4d80: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
4d90: 65 20 3d 20 4e 55 4c 4c 3b 0a 0a 09 09 69 66 20  e = NULL;....if 
4da0: 28 6e 65 77 5f 73 69 7a 65 20 21 3d 20 2d 31 29  (new_size != -1)
4db0: 20 7b 0a 09 09 09 61 70 70 66 73 5f 70 61 74 68   {....appfs_path
4dc0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65  _info_cache_size
4dd0: 20 3d 20 6e 65 77 5f 73 69 7a 65 3b 0a 09 09 7d   = new_size;...}
4de0: 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72 65  ..}...pthread_re
4df0: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65  t = pthread_mute
4e00: 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f  x_unlock(&appfs_
4e10: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
4e20: 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68  mutex);..if (pth
4e30: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  read_ret != 0) {
4e40: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
4e50: 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b  Unable to unlock
4e60: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65   path_info cache
4e70: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72   mutex !");....r
4e80: 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65 74 75  eturn;..}...retu
4e90: 72 6e 3b 0a 7d 0a 0a 2f 2a 20 47 65 74 20 69 6e  rn;.}../* Get in
4ea0: 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20  formation about 
4eb0: 61 20 70 61 74 68 2c 20 61 6e 64 20 6f 70 74 69  a path, and opti
4ec0: 6f 6e 61 6c 6c 79 20 6c 69 73 74 20 63 68 69 6c  onally list chil
4ed0: 64 72 65 6e 20 2a 2f 0a 73 74 61 74 69 63 20 69  dren */.static i
4ee0: 6e 74 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74  nt appfs_get_pat
4ef0: 68 5f 69 6e 66 6f 28 63 6f 6e 73 74 20 63 68 61  h_info(const cha
4f00: 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20  r *path, struct 
4f10: 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a  appfs_pathinfo *
4f20: 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 54 63 6c  pathinfo) {..Tcl
4f30: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b  _Interp *interp;
4f40: 0a 09 54 63 6c 5f 4f 62 6a 20 2a 61 74 74 72 73  ..Tcl_Obj *attrs
4f50: 5f 64 69 63 74 2c 20 2a 61 74 74 72 5f 76 61 6c  _dict, *attr_val
4f60: 75 65 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20  ue;..const char 
4f70: 2a 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 2c  *attr_value_str,
4f80: 20 2a 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72   *attr_value_str
4f90: 5f 69 3b 0a 09 54 63 6c 5f 57 69 64 65 49 6e 74  _i;..Tcl_WideInt
4fa0: 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65   attr_value_wide
4fb0: 3b 0a 09 69 6e 74 20 61 74 74 72 5f 76 61 6c 75  ;..int attr_valu
4fc0: 65 5f 69 6e 74 3b 0a 09 73 74 61 74 69 63 20 5f  e_int;..static _
4fd0: 5f 74 68 72 65 61 64 20 54 63 6c 5f 4f 62 6a 20  _thread Tcl_Obj 
4fe0: 2a 61 74 74 72 5f 6b 65 79 5f 74 79 70 65 20 3d  *attr_key_type =
4ff0: 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79   NULL, *attr_key
5000: 5f 70 65 72 6d 73 20 3d 20 4e 55 4c 4c 2c 20 2a  _perms = NULL, *
5010: 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 20 3d 20  attr_key_size = 
5020: 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f  NULL, *attr_key_
5030: 74 69 6d 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74  time = NULL, *at
5040: 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65 20 3d 20  tr_key_source = 
5050: 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f  NULL, *attr_key_
5060: 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 4e 55 4c  childcount = NUL
5070: 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 70 61 63  L, *attr_key_pac
5080: 6b 61 67 65 64 20 3d 20 4e 55 4c 4c 3b 0a 09 69  kaged = NULL;..i
5090: 6e 74 20 63 61 63 68 65 5f 72 65 74 3b 0a 09 69  nt cache_ret;..i
50a0: 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74  nt tcl_ret;..int
50b0: 20 72 65 74 76 61 6c 3b 0a 09 75 69 64 5f 74 20   retval;..uid_t 
50c0: 66 73 75 69 64 3b 0a 0a 09 72 65 74 76 61 6c 20  fsuid;...retval 
50d0: 3d 20 30 3b 0a 0a 09 66 73 75 69 64 20 3d 20 61  = 0;...fsuid = a
50e0: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
50f0: 3b 0a 0a 09 63 61 63 68 65 5f 72 65 74 20 3d 20  ;...cache_ret = 
5100: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
5110: 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28 70 61  nfo_cache_get(pa
5120: 74 68 2c 20 66 73 75 69 64 2c 20 70 61 74 68 69  th, fsuid, pathi
5130: 6e 66 6f 29 3b 0a 09 69 66 20 28 63 61 63 68 65  nfo);..if (cache
5140: 5f 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09 09 69  _ret == 0) {...i
5150: 66 20 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  f (pathinfo->typ
5160: 65 20 3d 3d 20 41 50 50 46 53 5f 50 41 54 48 54  e == APPFS_PATHT
5170: 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49  YPE_DOES_NOT_EXI
5180: 53 54 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44  ST) {....APPFS_D
5190: 45 42 55 47 28 22 52 65 74 75 72 6e 69 6e 67 20  EBUG("Returning 
51a0: 66 72 6f 6d 20 63 61 63 68 65 3a 20 64 6f 65 73  from cache: does
51b0: 20 6e 6f 74 20 65 78 69 73 74 20 5c 22 25 73 5c   not exist \"%s\
51c0: 22 22 2c 20 70 61 74 68 29 3b 0a 0a 09 09 09 72  "", path);.....r
51d0: 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a  eturn(-ENOENT);.
51e0: 09 09 7d 0a 0a 09 09 69 66 20 28 70 61 74 68 69  ..}....if (pathi
51f0: 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d 20 41 50 50  nfo->type == APP
5200: 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41  FS_PATHTYPE_INVA
5210: 4c 49 44 29 20 7b 0a 09 09 09 41 50 50 46 53 5f  LID) {....APPFS_
5220: 44 45 42 55 47 28 22 52 65 74 75 72 6e 69 6e 67  DEBUG("Returning
5230: 20 66 72 6f 6d 20 63 61 63 68 65 3a 20 69 6e 76   from cache: inv
5240: 61 6c 69 64 20 6f 62 6a 65 63 74 20 5c 22 25 73  alid object \"%s
5250: 5c 22 22 2c 20 70 61 74 68 29 3b 0a 0a 09 09 09  \"", path);.....
5260: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 09  return(-EIO);...
5270: 7d 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a  }....return(0);.
5280: 09 7d 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  .}...interp = ap
5290: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  pfs_TclInterp();
52a0: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
52b0: 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f  NULL) {...APPFS_
52c0: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 55 6e  DEBUG("error: Un
52d0: 61 62 6c 65 20 74 6f 20 67 65 74 20 61 6e 20 69  able to get an i
52e0: 6e 74 65 72 70 72 65 74 65 72 22 29 3b 0a 0a 09  nterpreter");...
52f0: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
5300: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
5310: 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72  ibtcl(Tcl_Preser
5320: 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74  ve(interp);)...t
5330: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
5340: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
5350: 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74  2, "::appfs::get
5360: 61 74 74 72 22 2c 20 70 61 74 68 29 3b 0a 09 69  attr", path);..i
5370: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
5380: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
5390: 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a  DEBUG("::appfs::
53a0: 67 65 74 61 74 74 72 28 25 73 29 20 66 61 69 6c  getattr(%s) fail
53b0: 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61  ed.", path);...a
53c0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
53d0: 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  (....APPFS_DEBUG
53e0: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20  ("Tcl Error is: 
53f0: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  %s", Tcl_GetStri
5400: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
5410: 29 3b 0a 09 09 29 0a 0a 09 09 70 61 74 68 69 6e  );...)....pathin
5420: 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53  fo->type = APPFS
5430: 5f 50 41 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e  _PATHTYPE_DOES_N
5440: 4f 54 5f 45 58 49 53 54 3b 0a 0a 09 09 61 70 70  OT_EXIST;....app
5450: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
5460: 5f 63 61 63 68 65 5f 61 64 64 28 70 61 74 68 2c  _cache_add(path,
5470: 20 66 73 75 69 64 2c 20 70 61 74 68 69 6e 66 6f   fsuid, pathinfo
5480: 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  );....appfs_call
5490: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
54a0: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
54b0: 09 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29  .return(-ENOENT)
54c0: 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f  ;..}...if (attr_
54d0: 6b 65 79 5f 74 79 70 65 20 3d 3d 20 4e 55 4c 4c  key_type == NULL
54e0: 29 20 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  ) {...appfs_call
54f0: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 61 74 74 72  _libtcl(....attr
5500: 5f 6b 65 79 5f 74 79 70 65 20 20 20 20 20 20 20  _key_type       
5510: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
5520: 62 6a 28 22 74 79 70 65 22 2c 20 2d 31 29 3b 0a  bj("type", -1);.
5530: 09 09 09 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d  ...attr_key_perm
5540: 73 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77  s      = Tcl_New
5550: 53 74 72 69 6e 67 4f 62 6a 28 22 70 65 72 6d 73  StringObj("perms
5560: 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f  ", -1);....attr_
5570: 6b 65 79 5f 73 69 7a 65 20 20 20 20 20 20 20 3d  key_size       =
5580: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
5590: 6a 28 22 73 69 7a 65 22 2c 20 2d 31 29 3b 0a 09  j("size", -1);..
55a0: 09 09 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 20  ..attr_key_time 
55b0: 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53        = Tcl_NewS
55c0: 74 72 69 6e 67 4f 62 6a 28 22 74 69 6d 65 22 2c  tringObj("time",
55d0: 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65   -1);....attr_ke
55e0: 79 5f 73 6f 75 72 63 65 20 20 20 20 20 3d 20 54  y_source     = T
55f0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
5600: 22 73 6f 75 72 63 65 22 2c 20 2d 31 29 3b 0a 09  "source", -1);..
5610: 09 09 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64  ..attr_key_child
5620: 63 6f 75 6e 74 20 3d 20 54 63 6c 5f 4e 65 77 53  count = Tcl_NewS
5630: 74 72 69 6e 67 4f 62 6a 28 22 63 68 69 6c 64 63  tringObj("childc
5640: 6f 75 6e 74 22 2c 20 2d 31 29 3b 0a 09 09 09 61  ount", -1);....a
5650: 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64  ttr_key_packaged
5660: 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69     = Tcl_NewStri
5670: 6e 67 4f 62 6a 28 22 70 61 63 6b 61 67 65 64 22  ngObj("packaged"
5680: 2c 20 2d 31 29 3b 0a 0a 09 09 09 54 63 6c 5f 49  , -1);.....Tcl_I
5690: 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72  ncrRefCount(attr
56a0: 5f 6b 65 79 5f 74 79 70 65 29 3b 0a 09 09 09 54  _key_type);....T
56b0: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
56c0: 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 29 3b  attr_key_perms);
56d0: 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43  ....Tcl_IncrRefC
56e0: 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 73 69  ount(attr_key_si
56f0: 7a 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72  ze);....Tcl_Incr
5700: 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65  RefCount(attr_ke
5710: 79 5f 74 69 6d 65 29 3b 0a 09 09 09 54 63 6c 5f  y_time);....Tcl_
5720: 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74  IncrRefCount(att
5730: 72 5f 6b 65 79 5f 73 6f 75 72 63 65 29 3b 0a 09  r_key_source);..
5740: 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75  ..Tcl_IncrRefCou
5750: 6e 74 28 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c  nt(attr_key_chil
5760: 64 63 6f 75 6e 74 29 3b 0a 09 09 09 54 63 6c 5f  dcount);....Tcl_
5770: 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74  IncrRefCount(att
5780: 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 29 3b  r_key_packaged);
5790: 0a 09 09 29 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  ...)..}...appfs_
57a0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 61  call_libtcl(...a
57b0: 74 74 72 73 5f 64 69 63 74 20 3d 20 54 63 6c 5f  ttrs_dict = Tcl_
57c0: 47 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  GetObjResult(int
57d0: 65 72 70 29 3b 0a 09 09 74 63 6c 5f 72 65 74 20  erp);...tcl_ret 
57e0: 3d 20 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74  = Tcl_DictObjGet
57f0: 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64  (interp, attrs_d
5800: 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74 79  ict, attr_key_ty
5810: 70 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29  pe, &attr_value)
5820: 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65  ;..)..if (tcl_re
5830: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
5840: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 5b 64  .APPFS_DEBUG("[d
5850: 69 63 74 20 67 65 74 20 5c 22 74 79 70 65 5c 22  ict get \"type\"
5860: 5d 20 66 61 69 6c 65 64 22 29 3b 0a 09 09 61 70  ] failed");...ap
5870: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
5880: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ....APPFS_DEBUG(
5890: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
58a0: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
58b0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
58c0: 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63  ;...)....appfs_c
58d0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52  all_libtcl(Tcl_R
58e0: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29  elease(interp);)
58f0: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  ....return(-EIO)
5900: 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f  ;..}...if (attr_
5910: 76 61 6c 75 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b  value == NULL) {
5920: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
5930: 65 72 72 6f 72 3a 20 55 6e 61 62 6c 65 20 74 6f  error: Unable to
5940: 20 67 65 74 20 74 79 70 65 20 66 6f 72 20 5c 22   get type for \"
5950: 25 73 5c 22 20 66 72 6f 6d 20 54 63 6c 22 2c 20  %s\" from Tcl", 
5960: 70 61 74 68 29 3b 0a 0a 09 09 61 70 70 66 73 5f  path);....appfs_
5970: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
5980: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
5990: 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f  )....return(-EIO
59a0: 29 3b 0a 09 7d 0a 0a 09 70 61 74 68 69 6e 66 6f  );..}...pathinfo
59b0: 2d 3e 70 61 63 6b 61 67 65 64 20 3d 20 30 3b 0a  ->packaged = 0;.
59c0: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62  ..appfs_call_lib
59d0: 74 63 6c 28 0a 09 09 61 74 74 72 5f 76 61 6c 75  tcl(...attr_valu
59e0: 65 5f 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53  e_str = Tcl_GetS
59f0: 74 72 69 6e 67 28 61 74 74 72 5f 76 61 6c 75 65  tring(attr_value
5a00: 29 3b 0a 0a 09 09 73 77 69 74 63 68 20 28 61 74  );....switch (at
5a10: 74 72 5f 76 61 6c 75 65 5f 73 74 72 5b 30 5d 29  tr_value_str[0])
5a20: 20 7b 0a 09 09 09 63 61 73 65 20 27 64 27 3a 20   {....case 'd': 
5a30: 2f 2a 20 64 69 72 65 63 74 6f 72 79 20 2a 2f 0a  /* directory */.
5a40: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
5a50: 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54  pe = APPFS_PATHT
5a60: 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3b 0a 09  YPE_DIRECTORY;..
5a70: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
5a80: 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63  einfo.dir.childc
5a90: 6f 75 6e 74 20 3d 20 30 3b 0a 0a 09 09 09 09 54  ount = 0;......T
5aa0: 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e  cl_DictObjGet(in
5ab0: 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74  terp, attrs_dict
5ac0: 2c 20 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64  , attr_key_child
5ad0: 63 6f 75 6e 74 2c 20 26 61 74 74 72 5f 76 61 6c  count, &attr_val
5ae0: 75 65 29 3b 0a 09 09 09 09 69 66 20 28 61 74 74  ue);.....if (att
5af0: 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29  r_value != NULL)
5b00: 20 7b 0a 09 09 09 09 09 74 63 6c 5f 72 65 74 20   {......tcl_ret 
5b10: 3d 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74  = Tcl_GetWideInt
5b20: 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74  FromObj(NULL, at
5b30: 74 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f  tr_value, &attr_
5b40: 76 61 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 09  value_wide);....
5b50: 09 09 69 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d  ..if (tcl_ret ==
5b60: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 09   TCL_OK) {......
5b70: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  .pathinfo->typei
5b80: 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75  nfo.dir.childcou
5b90: 6e 74 20 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f  nt = attr_value_
5ba0: 77 69 64 65 3b 0a 09 09 09 09 09 7d 0a 09 09 09  wide;......}....
5bb0: 09 7d 0a 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09  .}......break;..
5bc0: 09 09 63 61 73 65 20 27 66 27 3a 20 2f 2a 20 66  ..case 'f': /* f
5bd0: 69 6c 65 20 2a 2f 0a 09 09 09 09 70 61 74 68 69  ile */.....pathi
5be0: 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46  nfo->type = APPF
5bf0: 53 5f 50 41 54 48 54 59 50 45 5f 46 49 4c 45 3b  S_PATHTYPE_FILE;
5c00: 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
5c10: 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a  ypeinfo.file.siz
5c20: 65 20 3d 20 30 3b 0a 09 09 09 09 70 61 74 68 69  e = 0;.....pathi
5c30: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69  nfo->typeinfo.fi
5c40: 6c 65 2e 65 78 65 63 75 74 61 62 6c 65 20 3d 20  le.executable = 
5c50: 30 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d  0;.....pathinfo-
5c60: 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73  >typeinfo.file.s
5c70: 75 69 64 52 6f 6f 74 20 3d 20 30 3b 0a 09 09 09  uidRoot = 0;....
5c80: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  .pathinfo->typei
5c90: 6e 66 6f 2e 66 69 6c 65 2e 77 6f 72 6c 64 61 63  nfo.file.worldac
5ca0: 63 65 73 73 69 62 6c 65 20 3d 20 30 3b 0a 0a 09  cessible = 0;...
5cb0: 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65  ...Tcl_DictObjGe
5cc0: 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f  t(interp, attrs_
5cd0: 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 73  dict, attr_key_s
5ce0: 69 7a 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  ize, &attr_value
5cf0: 29 3b 0a 09 09 09 09 69 66 20 28 61 74 74 72 5f  );.....if (attr_
5d00: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  value != NULL) {
5d10: 0a 09 09 09 09 09 74 63 6c 5f 72 65 74 20 3d 20  ......tcl_ret = 
5d20: 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72  Tcl_GetWideIntFr
5d30: 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72  omObj(NULL, attr
5d40: 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61  _value, &attr_va
5d50: 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 09 09  lue_wide);......
5d60: 69 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54  if (tcl_ret == T
5d70: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 09 70  CL_OK) {.......p
5d80: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
5d90: 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 3d 20 61 74  o.file.size = at
5da0: 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09  tr_value_wide;..
5db0: 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09  ....}.....}.....
5dc0: 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28  .Tcl_DictObjGet(
5dd0: 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69  interp, attrs_di
5de0: 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 70 65 72  ct, attr_key_per
5df0: 6d 73 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29  ms, &attr_value)
5e00: 3b 0a 09 09 09 09 69 66 20 28 61 74 74 72 5f 76  ;.....if (attr_v
5e10: 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  alue != NULL) {.
5e20: 09 09 09 09 09 61 74 74 72 5f 76 61 6c 75 65 5f  .....attr_value_
5e30: 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  str = Tcl_GetStr
5e40: 69 6e 67 28 61 74 74 72 5f 76 61 6c 75 65 29 3b  ing(attr_value);
5e50: 0a 09 09 09 09 09 66 6f 72 20 28 61 74 74 72 5f  ......for (attr_
5e60: 76 61 6c 75 65 5f 73 74 72 5f 69 20 3d 20 26 61  value_str_i = &a
5e70: 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5b 30 5d  ttr_value_str[0]
5e80: 3b 20 2a 61 74 74 72 5f 76 61 6c 75 65 5f 73 74  ; *attr_value_st
5e90: 72 5f 69 20 21 3d 20 27 5c 30 27 3b 20 61 74 74  r_i != '\0'; att
5ea0: 72 5f 76 61 6c 75 65 5f 73 74 72 5f 69 2b 2b 29  r_value_str_i++)
5eb0: 20 7b 0a 09 09 09 09 09 09 73 77 69 74 63 68 20   {.......switch 
5ec0: 28 2a 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72  (*attr_value_str
5ed0: 5f 69 29 20 7b 0a 09 09 09 09 09 09 09 63 61 73  _i) {........cas
5ee0: 65 20 27 78 27 3a 0a 09 09 09 09 09 09 09 09 70  e 'x':.........p
5ef0: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
5f00: 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74 61 62 6c  o.file.executabl
5f10: 65 20 3d 20 31 3b 0a 0a 09 09 09 09 09 09 09 09  e = 1;..........
5f20: 62 72 65 61 6b 3b 0a 09 09 09 09 09 09 09 63 61  break;........ca
5f30: 73 65 20 27 55 27 3a 0a 09 09 09 09 09 09 09 09  se 'U':.........
5f40: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
5f50: 66 6f 2e 66 69 6c 65 2e 73 75 69 64 52 6f 6f 74  fo.file.suidRoot
5f60: 20 3d 20 31 3b 0a 0a 09 09 09 09 09 09 09 09 62   = 1;..........b
5f70: 72 65 61 6b 3b 0a 09 09 09 09 09 09 09 63 61 73  reak;........cas
5f80: 65 20 27 2d 27 3a 0a 09 09 09 09 09 09 09 09 70  e '-':.........p
5f90: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66  athinfo->typeinf
5fa0: 6f 2e 66 69 6c 65 2e 77 6f 72 6c 64 61 63 63 65  o.file.worldacce
5fb0: 73 73 69 62 6c 65 20 3d 20 31 3b 0a 0a 09 09 09  ssible = 1;.....
5fc0: 09 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 09  .....break;.....
5fd0: 09 09 7d 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d  ..}......}.....}
5fe0: 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63  .....break;....c
5ff0: 61 73 65 20 27 73 27 3a 20 2f 2a 20 73 79 6d 6c  ase 's': /* syml
6000: 69 6e 6b 20 2a 2f 0a 09 09 09 09 70 61 74 68 69  ink */.....pathi
6010: 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46  nfo->type = APPF
6020: 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49  S_PATHTYPE_SYMLI
6030: 4e 4b 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f  NK;.....pathinfo
6040: 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69  ->typeinfo.symli
6050: 6e 6b 2e 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09  nk.size = 0;....
6060: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  .pathinfo->typei
6070: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72  nfo.symlink.sour
6080: 63 65 5b 30 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09  ce[0] = '\0';...
6090: 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65  ...Tcl_DictObjGe
60a0: 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f  t(interp, attrs_
60b0: 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 73  dict, attr_key_s
60c0: 6f 75 72 63 65 2c 20 26 61 74 74 72 5f 76 61 6c  ource, &attr_val
60d0: 75 65 29 3b 0a 09 09 09 09 69 66 20 28 61 74 74  ue);.....if (att
60e0: 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29  r_value != NULL)
60f0: 20 7b 0a 09 09 09 09 09 61 74 74 72 5f 76 61 6c   {......attr_val
6100: 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f 47 65 74  ue_str = Tcl_Get
6110: 53 74 72 69 6e 67 46 72 6f 6d 4f 62 6a 28 61 74  StringFromObj(at
6120: 74 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f  tr_value, &attr_
6130: 76 61 6c 75 65 5f 69 6e 74 29 3b 20 0a 0a 09 09  value_int); ....
6140: 09 09 09 69 66 20 28 28 61 74 74 72 5f 76 61 6c  ...if ((attr_val
6150: 75 65 5f 69 6e 74 20 2b 20 31 29 20 3c 3d 20 73  ue_int + 1) <= s
6160: 69 7a 65 6f 66 28 70 61 74 68 69 6e 66 6f 2d 3e  izeof(pathinfo->
6170: 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b  typeinfo.symlink
6180: 2e 73 6f 75 72 63 65 29 29 20 7b 0a 09 09 09 09  .source)) {.....
6190: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
61a0: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a  info.symlink.siz
61b0: 65 20 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 69  e = attr_value_i
61c0: 6e 74 3b 0a 09 09 09 09 09 09 70 61 74 68 69 6e  nt;.......pathin
61d0: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  fo->typeinfo.sym
61e0: 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b 61 74 74 72  link.source[attr
61f0: 5f 76 61 6c 75 65 5f 69 6e 74 5d 20 3d 20 27 5c  _value_int] = '\
6200: 30 27 3b 0a 0a 09 09 09 09 09 09 6d 65 6d 63 70  0';........memcp
6210: 79 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  y(pathinfo->type
6220: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75  info.symlink.sou
6230: 72 63 65 2c 20 61 74 74 72 5f 76 61 6c 75 65 5f  rce, attr_value_
6240: 73 74 72 2c 20 61 74 74 72 5f 76 61 6c 75 65 5f  str, attr_value_
6250: 69 6e 74 29 3b 0a 09 09 09 09 09 7d 0a 09 09 09  int);......}....
6260: 09 7d 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09  .}.....break;...
6270: 09 63 61 73 65 20 27 46 27 3a 20 2f 2a 20 70 69  .case 'F': /* pi
6280: 70 65 2f 66 69 66 6f 20 2a 2f 0a 09 09 09 09 70  pe/fifo */.....p
6290: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20  athinfo->type = 
62a0: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46  APPFS_PATHTYPE_F
62b0: 49 46 4f 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a  IFO;.....break;.
62c0: 09 09 09 63 61 73 65 20 27 53 27 3a 20 2f 2a 20  ...case 'S': /* 
62d0: 55 4e 49 58 20 64 6f 6d 61 69 6e 20 73 6f 63 6b  UNIX domain sock
62e0: 65 74 20 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e  et */.....pathin
62f0: 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53  fo->type = APPFS
6300: 5f 50 41 54 48 54 59 50 45 5f 53 4f 43 4b 45 54  _PATHTYPE_SOCKET
6310: 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09  ;.....break;....
6320: 64 65 66 61 75 6c 74 3a 0a 09 09 09 09 72 65 74  default:.....ret
6330: 76 61 6c 20 3d 20 2d 45 49 4f 3b 0a 09 09 7d 0a  val = -EIO;...}.
6340: 0a 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65  ...Tcl_DictObjGe
6350: 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f  t(interp, attrs_
6360: 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 70  dict, attr_key_p
6370: 61 63 6b 61 67 65 64 2c 20 26 61 74 74 72 5f 76  ackaged, &attr_v
6380: 61 6c 75 65 29 3b 0a 09 09 69 66 20 28 61 74 74  alue);...if (att
6390: 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29  r_value != NULL)
63a0: 20 7b 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e   {....pathinfo->
63b0: 70 61 63 6b 61 67 65 64 20 3d 20 31 3b 0a 09 09  packaged = 1;...
63c0: 7d 0a 0a 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a  }....Tcl_DictObj
63d0: 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72  Get(interp, attr
63e0: 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79  s_dict, attr_key
63f0: 5f 74 69 6d 65 2c 20 26 61 74 74 72 5f 76 61 6c  _time, &attr_val
6400: 75 65 29 3b 0a 09 09 69 66 20 28 61 74 74 72 5f  ue);...if (attr_
6410: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  value != NULL) {
6420: 0a 09 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63  ....tcl_ret = Tc
6430: 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d  l_GetWideIntFrom
6440: 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76  Obj(NULL, attr_v
6450: 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  alue, &attr_valu
6460: 65 5f 77 69 64 65 29 3b 0a 09 09 09 69 66 20 28  e_wide);....if (
6470: 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f  tcl_ret == TCL_O
6480: 4b 29 20 7b 0a 09 09 09 09 70 61 74 68 69 6e 66  K) {.....pathinf
6490: 6f 2d 3e 74 69 6d 65 20 3d 20 61 74 74 72 5f 76  o->time = attr_v
64a0: 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09 7d 0a  alue_wide;....}.
64b0: 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 70 61  ..} else {....pa
64c0: 74 68 69 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20 61  thinfo->time = a
64d0: 70 70 66 73 5f 62 6f 6f 74 74 69 6d 65 3b 0a 09  ppfs_boottime;..
64e0: 09 7d 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73  .}....Tcl_Releas
64f0: 65 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09  e(interp);..)...
6500: 69 66 20 28 70 61 74 68 69 6e 66 6f 2d 3e 70 61  if (pathinfo->pa
6510: 63 6b 61 67 65 64 29 20 7b 0a 09 09 70 61 74 68  ckaged) {...path
6520: 69 6e 66 6f 2d 3e 69 6e 6f 64 65 20 3d 20 61 70  info->inode = ap
6530: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f  pfs_get_path_ino
6540: 64 65 28 70 61 74 68 2c 20 2d 31 29 3b 0a 09 7d  de(path, -1);..}
6550: 20 65 6c 73 65 20 7b 0a 09 09 70 61 74 68 69 6e   else {...pathin
6560: 66 6f 2d 3e 69 6e 6f 64 65 20 3d 20 61 70 70 66  fo->inode = appf
6570: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65  s_get_path_inode
6580: 28 70 61 74 68 2c 20 66 73 75 69 64 29 3b 0a 09  (path, fsuid);..
6590: 7d 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  }...APPFS_DEBUG(
65a0: 22 43 61 63 68 69 6e 67 20 69 6e 6f 64 65 20 66  "Caching inode f
65b0: 6f 72 20 70 61 74 68 3d 25 73 2c 75 69 64 3d 25  or path=%s,uid=%
65c0: 6c 6c 69 20 61 73 20 25 6c 6c 75 20 28 70 61 63  lli as %llu (pac
65d0: 6b 61 67 65 64 20 3d 20 25 69 29 22 2c 20 70 61  kaged = %i)", pa
65e0: 74 68 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20  th, (long long) 
65f0: 66 73 75 69 64 2c 20 70 61 74 68 69 6e 66 6f 2d  fsuid, pathinfo-
6600: 3e 69 6e 6f 64 65 2c 20 70 61 74 68 69 6e 66 6f  >inode, pathinfo
6610: 2d 3e 70 61 63 6b 61 67 65 64 29 3b 0a 0a 09 69  ->packaged);...i
6620: 66 20 28 72 65 74 76 61 6c 20 3d 3d 20 30 29 20  f (retval == 0) 
6630: 7b 0a 09 09 61 70 70 66 73 5f 67 65 74 5f 70 61  {...appfs_get_pa
6640: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64  th_info_cache_ad
6650: 64 28 70 61 74 68 2c 20 66 73 75 69 64 2c 20 70  d(path, fsuid, p
6660: 61 74 68 69 6e 66 6f 29 3b 0a 09 7d 20 65 6c 73  athinfo);..} els
6670: 65 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  e {...APPFS_DEBU
6680: 47 28 22 65 72 72 6f 72 3a 20 49 6e 76 61 6c 69  G("error: Invali
6690: 64 20 74 79 70 65 20 66 6f 72 20 5c 22 25 73 5c  d type for \"%s\
66a0: 22 20 66 72 6f 6d 20 54 63 6c 22 2c 20 70 61 74  " from Tcl", pat
66b0: 68 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  h);..}...return(
66c0: 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74  retval);.}..stat
66d0: 69 63 20 63 68 61 72 20 2a 61 70 70 66 73 5f 70  ic char *appfs_p
66e0: 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65  repare_to_create
66f0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
6700: 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  h) {..Tcl_Interp
6710: 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74   *interp;..const
6720: 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68   char *real_path
6730: 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a  ;..int tcl_ret;.
6740: 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  ..appfs_get_path
6750: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73  _info_cache_flus
6760: 68 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  h(appfs_get_fsui
6770: 64 28 29 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74 65  d(), -1);...inte
6780: 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e  rp = appfs_TclIn
6790: 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74  terp();..if (int
67a0: 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  erp == NULL) {..
67b0: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
67c0: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
67d0: 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72  ibtcl(Tcl_Preser
67e0: 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 61  ve(interp);)...a
67f0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
6800: 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 61 70  (...tcl_ret = ap
6810: 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74  pfs_Tcl_Eval(int
6820: 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73  erp, 2, "::appfs
6830: 3a 3a 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65  ::prepare_to_cre
6840: 61 74 65 22 2c 20 70 61 74 68 29 3b 0a 09 29 0a  ate", path);..).
6850: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
6860: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
6870: 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73  S_DEBUG("::appfs
6880: 3a 3a 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65  ::prepare_to_cre
6890: 61 74 65 28 25 73 29 20 66 61 69 6c 65 64 2e 22  ate(%s) failed."
68a0: 2c 20 70 61 74 68 29 3b 0a 09 09 61 70 70 66 73  , path);...appfs
68b0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
68c0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63  .APPFS_DEBUG("Tc
68d0: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c  l Error is: %s",
68e0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
68f0: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09  sult(interp));..
6900: 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  .)....appfs_call
6910: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
6920: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
6930: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
6940: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
6950: 69 62 74 63 6c 28 0a 09 09 72 65 61 6c 5f 70 61  ibtcl(...real_pa
6960: 74 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  th = Tcl_GetStri
6970: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
6980: 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..)...appfs_cal
6990: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
69a0: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
69b0: 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d  .if (real_path =
69c0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
69d0: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72  rn(NULL);..}...r
69e0: 65 74 75 72 6e 28 73 74 72 64 75 70 28 72 65 61  eturn(strdup(rea
69f0: 6c 5f 70 61 74 68 29 29 3b 0a 7d 0a 0a 73 74 61  l_path));.}..sta
6a00: 74 69 63 20 63 68 61 72 20 2a 61 70 70 66 73 5f  tic char *appfs_
6a10: 6c 6f 63 61 6c 70 61 74 68 28 63 6f 6e 73 74 20  localpath(const 
6a20: 63 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54  char *path) {..T
6a30: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
6a40: 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a  p;..const char *
6a50: 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20  real_path;..int 
6a60: 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72  tcl_ret;...inter
6a70: 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74  p = appfs_TclInt
6a80: 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65  erp();..if (inte
6a90: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
6aa0: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
6ab0: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
6ac0: 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76  btcl(Tcl_Preserv
6ad0: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 61 70  e(interp);)...ap
6ae0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
6af0: 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70  ...tcl_ret = app
6b00: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65  fs_Tcl_Eval(inte
6b10: 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a  rp, 2, "::appfs:
6b20: 3a 6c 6f 63 61 6c 70 61 74 68 22 2c 20 70 61 74  :localpath", pat
6b30: 68 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f  h);..)..if (tcl_
6b40: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
6b50: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
6b60: 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63 61 6c 70 61  ::appfs::localpa
6b70: 74 68 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c  th(%s) failed.",
6b80: 20 70 61 74 68 29 3b 0a 09 09 61 70 70 66 73 5f   path);...appfs_
6b90: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09  call_libtcl(....
6ba0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c  APPFS_DEBUG("Tcl
6bb0: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20   Error is: %s", 
6bc0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
6bd0: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
6be0: 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c  )....return(NULL
6bf0: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61  );..}...appfs_ca
6c00: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 61  ll_libtcl(...rea
6c10: 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74  l_path = Tcl_Get
6c20: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
6c30: 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73  erp);..)...appfs
6c40: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
6c50: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
6c60: 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61  ;)...if (real_pa
6c70: 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th == NULL) {...
6c80: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
6c90: 0a 0a 09 72 65 74 75 72 6e 28 73 74 72 64 75 70  ...return(strdup
6ca0: 28 72 65 61 6c 5f 70 61 74 68 29 29 3b 0a 7d 0a  (real_path));.}.
6cb0: 0a 23 69 66 20 28 64 65 66 69 6e 65 64 28 44 45  .#if (defined(DE
6cc0: 42 55 47 29 20 26 26 20 64 65 66 69 6e 65 64 28  BUG) && defined(
6cd0: 41 50 50 46 53 5f 45 58 49 54 5f 50 41 54 48 29  APPFS_EXIT_PATH)
6ce0: 29 20 7c 7c 20 64 65 66 69 6e 65 64 28 41 50 50  ) || defined(APP
6cf0: 46 53 5f 45 58 49 54 5f 50 41 54 48 5f 45 4e 41  FS_EXIT_PATH_ENA
6d00: 42 4c 45 5f 4d 41 4a 4f 52 5f 53 45 43 55 52 49  BLE_MAJOR_SECURI
6d10: 54 59 5f 48 4f 4c 45 29 0a 73 74 61 74 69 63 20  TY_HOLE).static 
6d20: 76 6f 69 64 20 61 70 70 66 73 5f 65 78 69 74 28  void appfs_exit(
6d30: 76 6f 69 64 29 20 7b 0a 09 69 6e 74 20 67 6c 6f  void) {..int glo
6d40: 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74  bal_interp_reset
6d50: 5f 6b 65 79 3b 0a 0a 09 67 6c 6f 62 61 6c 5f 69  _key;...global_i
6d60: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20  nterp_reset_key 
6d70: 3d 20 5f 5f 73 79 6e 63 5f 66 65 74 63 68 5f 61  = __sync_fetch_a
6d80: 6e 64 5f 61 64 64 28 26 69 6e 74 65 72 70 5f 72  nd_add(&interp_r
6d90: 65 73 65 74 5f 6b 65 79 2c 20 30 29 3b 0a 09 5f  eset_key, 0);.._
6da0: 5f 73 79 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f  _sync_fetch_and_
6db0: 73 75 62 28 26 69 6e 74 65 72 70 5f 72 65 73 65  sub(&interp_rese
6dc0: 74 5f 6b 65 79 2c 20 67 6c 6f 62 61 6c 5f 69 6e  t_key, global_in
6dd0: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 29 3b  terp_reset_key);
6de0: 0a 0a 09 77 68 69 6c 65 20 28 5f 5f 73 79 6e 63  ...while (__sync
6df0: 5f 73 75 62 5f 61 6e 64 5f 66 65 74 63 68 28 26  _sub_and_fetch(&
6e00: 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79  interp_reset_key
6e10: 2c 20 31 29 20 3e 3d 20 30 29 20 7b 0a 09 09 2f  , 1) >= 0) {.../
6e20: 2a 20 42 75 73 79 20 4c 6f 6f 70 20 2a 2f 0a 09  * Busy Loop */..
6e30: 7d 0a 0a 09 67 6c 6f 62 61 6c 5f 69 6e 74 65 72  }...global_inter
6e40: 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 5f 5f  p_reset_key = __
6e50: 73 79 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 61  sync_fetch_and_a
6e60: 64 64 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74  dd(&interp_reset
6e70: 5f 6b 65 79 2c 20 30 29 3b 0a 09 69 66 20 28 67  _key, 0);..if (g
6e80: 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73  lobal_interp_res
6e90: 65 74 5f 6b 65 79 20 21 3d 20 2d 31 29 20 7b 0a  et_key != -1) {.
6ea0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45  ..APPFS_DEBUG("E
6eb0: 72 72 6f 72 20 73 65 6e 64 69 6e 67 20 6b 69 6c  rror sending kil
6ec0: 6c 20 73 69 67 6e 61 6c 20 74 6f 20 61 6c 6c 20  l signal to all 
6ed0: 74 68 72 65 61 64 73 2c 20 61 62 6f 72 74 69 6e  threads, abortin
6ee0: 67 20 61 6e 79 77 61 79 2e 22 29 3b 0a 09 7d 0a  g anyway.");..}.
6ef0: 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  ..appfs_get_path
6f00: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73  _info_cache_flus
6f10: 68 28 2d 31 2c 20 2d 31 29 3b 0a 0a 09 66 75 73  h(-1, -1);...fus
6f20: 65 5f 65 78 69 74 28 66 75 73 65 5f 67 65 74 5f  e_exit(fuse_get_
6f30: 63 6f 6e 74 65 78 74 28 29 2d 3e 66 75 73 65 29  context()->fuse)
6f40: 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 23  ;...return;.}..#
6f50: 65 6e 64 69 66 0a 0a 23 69 66 20 64 65 66 69 6e  endif..#if defin
6f60: 65 64 28 41 50 50 46 53 5f 45 58 45 43 5f 50 41  ed(APPFS_EXEC_PA
6f70: 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f  TH_ENABLE_MAJOR_
6f80: 53 45 43 55 52 49 54 59 5f 48 4f 4c 45 29 0a 73  SECURITY_HOLE).s
6f90: 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73  tatic void appfs
6fa0: 5f 72 75 6e 54 63 6c 28 63 6f 6e 73 74 20 63 68  _runTcl(const ch
6fb0: 61 72 20 2a 73 63 72 69 70 74 2c 20 73 69 7a 65  ar *script, size
6fc0: 5f 74 20 73 63 72 69 70 74 4c 65 6e 29 20 7b 0a  _t scriptLen) {.
6fd0: 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  .Tcl_Interp *int
6fe0: 65 72 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 73  erp;..Tcl_Obj *s
6ff0: 63 72 69 70 74 4f 62 6a 3b 0a 09 69 6e 74 20 74  criptObj;..int t
7000: 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70  cl_ret;...interp
7010: 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65   = appfs_TclInte
7020: 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72  rp();..if (inter
7030: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41  p == NULL) {...A
7040: 50 50 46 53 5f 44 45 42 55 47 28 22 45 72 72 6f  PPFS_DEBUG("Erro
7050: 72 20 63 72 65 61 74 69 6e 67 20 61 6e 20 69 6e  r creating an in
7060: 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a 09  terpreter.");...
7070: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 61 70  .return;..}...ap
7080: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28  pfs_call_libtcl(
7090: 0a 09 09 73 63 72 69 70 74 4f 62 6a 20 3d 20 54  ...scriptObj = T
70a0: 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28  cl_NewStringObj(
70b0: 73 63 72 69 70 74 2c 20 73 63 72 69 70 74 4c 65  script, scriptLe
70c0: 6e 29 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52  n);....Tcl_IncrR
70d0: 65 66 43 6f 75 6e 74 28 73 63 72 69 70 74 4f 62  efCount(scriptOb
70e0: 6a 29 3b 0a 09 29 0a 0a 09 69 66 20 28 73 63 72  j);..)...if (scr
70f0: 69 70 74 4f 62 6a 20 3d 3d 20 4e 55 4c 4c 29 20  iptObj == NULL) 
7100: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
7110: 22 45 72 72 6f 72 20 63 72 65 61 74 69 6e 67 20  "Error creating 
7120: 61 20 73 63 72 69 70 74 20 6f 62 6a 65 63 74 2e  a script object.
7130: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09  ");....return;..
7140: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
7150: 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74  ibtcl(...tcl_ret
7160: 20 3d 20 54 63 6c 5f 45 76 61 6c 4f 62 6a 45 78   = Tcl_EvalObjEx
7170: 28 69 6e 74 65 72 70 2c 20 73 63 72 69 70 74 4f  (interp, scriptO
7180: 62 6a 2c 20 54 43 4c 5f 45 56 41 4c 5f 44 49 52  bj, TCL_EVAL_DIR
7190: 45 43 54 29 3b 0a 09 09 54 63 6c 5f 44 65 63 72  ECT);...Tcl_Decr
71a0: 52 65 66 43 6f 75 6e 74 28 73 63 72 69 70 74 4f  RefCount(scriptO
71b0: 62 6a 29 3b 0a 09 29 0a 0a 09 69 66 20 28 74 63  bj);..)...if (tc
71c0: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
71d0: 20 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f   {...appfs_call_
71e0: 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53  libtcl(....APPFS
71f0: 5f 44 45 42 55 47 28 22 53 63 72 69 70 74 20 72  _DEBUG("Script r
7200: 65 74 75 72 6e 65 64 20 65 72 72 6f 72 20 25 69  eturned error %i
7210: 3a 20 25 73 22 2c 20 74 63 6c 5f 72 65 74 2c 20  : %s", tcl_ret, 
7220: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
7230: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
7240: 29 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d  )..}...return;.}
7250: 0a 23 65 6e 64 69 66 0a 0a 73 74 61 74 69 63 20  .#endif..static 
7260: 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72  int appfs_fuse_r
7270: 65 61 64 6c 69 6e 6b 28 63 6f 6e 73 74 20 63 68  eadlink(const ch
7280: 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72 20 2a  ar *path, char *
7290: 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65  buf, size_t size
72a0: 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70 70 66  ) {..struct appf
72b0: 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74 68 69  s_pathinfo pathi
72c0: 6e 66 6f 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c  nfo;..int retval
72d0: 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45   = 0;...APPFS_DE
72e0: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
72f0: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
7300: 74 68 29 3b 0a 0a 09 70 61 74 68 69 6e 66 6f 2e  th);...pathinfo.
7310: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54  type = APPFS_PAT
7320: 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a  HTYPE_INVALID;..
7330: 09 72 65 74 76 61 6c 20 3d 20 61 70 70 66 73 5f  .retval = appfs_
7340: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61  get_path_info(pa
7350: 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a  th, &pathinfo);.
7360: 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20 30  .if (retval != 0
7370: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 72 65 74  ) {...return(ret
7380: 76 61 6c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 70  val);..}...if (p
7390: 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 21 3d 20  athinfo.type != 
73a0: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53  APPFS_PATHTYPE_S
73b0: 59 4d 4c 49 4e 4b 29 20 7b 0a 09 09 72 65 74 75  YMLINK) {...retu
73c0: 72 6e 28 2d 45 49 4e 56 41 4c 29 3b 0a 09 7d 0a  rn(-EINVAL);..}.
73d0: 0a 09 69 66 20 28 28 73 74 72 6c 65 6e 28 70 61  ..if ((strlen(pa
73e0: 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e  thinfo.typeinfo.
73f0: 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 20  symlink.source) 
7400: 2b 20 31 29 20 3e 20 73 69 7a 65 29 20 7b 0a 09  + 1) > size) {..
7410: 09 72 65 74 75 72 6e 28 2d 45 4e 41 4d 45 54 4f  .return(-ENAMETO
7420: 4f 4c 4f 4e 47 29 3b 0a 09 7d 0a 0a 09 6d 65 6d  OLONG);..}...mem
7430: 63 70 79 28 62 75 66 2c 20 70 61 74 68 69 6e 66  cpy(buf, pathinf
7440: 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69  o.typeinfo.symli
7450: 6e 6b 2e 73 6f 75 72 63 65 2c 20 73 74 72 6c 65  nk.source, strle
7460: 6e 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69  n(pathinfo.typei
7470: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72  nfo.symlink.sour
7480: 63 65 29 20 2b 20 31 29 3b 0a 0a 09 72 65 74 75  ce) + 1);...retu
7490: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn(0);.}..static
74a0: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
74b0: 67 65 74 61 74 74 72 28 63 6f 6e 73 74 20 63 68  getattr(const ch
74c0: 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74  ar *path, struct
74d0: 20 73 74 61 74 20 2a 73 74 62 75 66 29 20 7b 0a   stat *stbuf) {.
74e0: 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61  .struct appfs_pa
74f0: 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b  thinfo pathinfo;
7500: 0a 09 69 6e 74 20 63 68 61 6e 67 65 4f 77 6e 65  ..int changeOwne
7510: 72 54 6f 55 73 65 72 49 66 50 61 63 6b 61 67 65  rToUserIfPackage
7520: 64 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a  d;..int retval;.
7530: 0a 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09  ..retval = 0;...
7540: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
7550: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
7560: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 23 69  ..)", path);..#i
7570: 66 20 28 64 65 66 69 6e 65 64 28 44 45 42 55 47  f (defined(DEBUG
7580: 29 20 26 26 20 64 65 66 69 6e 65 64 28 41 50 50  ) && defined(APP
7590: 46 53 5f 45 58 49 54 5f 50 41 54 48 29 29 20 7c  FS_EXIT_PATH)) |
75a0: 7c 20 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f  | defined(APPFS_
75b0: 45 58 49 54 5f 50 41 54 48 5f 45 4e 41 42 4c 45  EXIT_PATH_ENABLE
75c0: 5f 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f  _MAJOR_SECURITY_
75d0: 48 4f 4c 45 29 0a 09 2f 2a 0a 09 20 2a 20 54 68  HOLE)../*.. * Th
75e0: 69 73 20 69 73 20 61 20 6d 61 6a 6f 72 20 73 65  is is a major se
75f0: 63 75 72 69 74 79 20 69 73 73 75 65 20 73 6f 20  curity issue so 
7600: 77 65 20 63 61 6e 6e 6f 74 20 6c 65 74 20 69 74  we cannot let it
7610: 20 62 65 20 63 6f 6d 70 69 6c 65 64 20 69 6e 74   be compiled int
7620: 6f 0a 09 20 2a 20 61 6e 79 20 72 65 6c 65 61 73  o.. * any releas
7630: 65 0a 09 20 2a 2f 0a 09 69 66 20 28 73 74 72 63  e.. */..if (strc
7640: 6d 70 28 70 61 74 68 2c 20 22 2f 65 78 69 74 22  mp(path, "/exit"
7650: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 61 70 70 66  ) == 0) {...appf
7660: 73 5f 65 78 69 74 28 29 3b 0a 09 7d 0a 23 65 6e  s_exit();..}.#en
7670: 64 69 66 0a 23 69 66 20 64 65 66 69 6e 65 64 28  dif.#if defined(
7680: 41 50 50 46 53 5f 45 58 45 43 5f 50 41 54 48 5f  APPFS_EXEC_PATH_
7690: 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f 53 45 43  ENABLE_MAJOR_SEC
76a0: 55 52 49 54 59 5f 48 4f 4c 45 29 0a 09 69 66 20  URITY_HOLE)..if 
76b0: 28 73 74 72 63 6d 70 28 70 61 74 68 2c 20 22 2f  (strcmp(path, "/
76c0: 65 78 65 63 22 29 20 3d 3d 20 30 29 20 7b 0a 09  exec") == 0) {..
76d0: 09 6d 65 6d 73 65 74 28 73 74 62 75 66 2c 20 30  .memset(stbuf, 0
76e0: 2c 20 73 69 7a 65 6f 66 28 73 74 72 75 63 74 20  , sizeof(struct 
76f0: 73 74 61 74 29 29 3b 0a 0a 09 09 73 74 62 75 66  stat));....stbuf
7700: 2d 3e 73 74 5f 6d 74 69 6d 65 20 3d 20 30 3b 0a  ->st_mtime = 0;.
7710: 09 09 73 74 62 75 66 2d 3e 73 74 5f 63 74 69 6d  ..stbuf->st_ctim
7720: 65 20 3d 20 30 3b 0a 09 09 73 74 62 75 66 2d 3e  e = 0;...stbuf->
7730: 73 74 5f 61 74 69 6d 65 20 3d 20 30 3b 0a 09 09  st_atime = 0;...
7740: 73 74 62 75 66 2d 3e 73 74 5f 69 6e 6f 20 20 20  stbuf->st_ino   
7750: 3d 20 33 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74  = 3;...stbuf->st
7760: 5f 6d 6f 64 65 20 20 3d 20 30 3b 0a 09 09 73 74  _mode  = 0;...st
7770: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 20 3d 20  buf->st_mode  = 
7780: 53 5f 49 46 52 45 47 20 7c 20 30 36 30 30 3b 0a  S_IFREG | 0600;.
7790: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e  ..stbuf->st_nlin
77a0: 6b 20 3d 20 31 3b 0a 09 09 73 74 62 75 66 2d 3e  k = 1;...stbuf->
77b0: 73 74 5f 73 69 7a 65 20 20 3d 20 30 3b 0a 0a 09  st_size  = 0;...
77c0: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
77d0: 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 70 61 74  ..}.#endif...pat
77e0: 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41 50 50  hinfo.type = APP
77f0: 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41  FS_PATHTYPE_INVA
7800: 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  LID;...retval = 
7810: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
7820: 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69  nfo(path, &pathi
7830: 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65 74 76 61  nfo);..if (retva
7840: 6c 20 21 3d 20 30 29 20 7b 0a 09 09 69 66 20 28  l != 0) {...if (
7850: 72 65 74 76 61 6c 20 3d 3d 20 2d 45 4e 4f 45 4e  retval == -ENOEN
7860: 54 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45  T) {....APPFS_DE
7870: 42 55 47 28 22 67 65 74 5f 70 61 74 68 5f 69 6e  BUG("get_path_in
7880: 66 6f 20 72 65 74 75 72 6e 65 64 20 45 4e 4f 45  fo returned ENOE
7890: 4e 54 2c 20 72 65 74 75 72 6e 69 6e 67 20 69 74  NT, returning it
78a0: 20 61 73 20 77 65 6c 6c 2e 22 29 3b 0a 09 09 7d   as well.");...}
78b0: 20 65 6c 73 65 20 7b 0a 09 09 09 41 50 50 46 53   else {....APPFS
78c0: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 67  _DEBUG("error: g
78d0: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20 66 61 69  et_path_info fai
78e0: 6c 65 64 22 29 3b 0a 09 09 7d 0a 0a 09 09 72 65  led");...}....re
78f0: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d  turn(retval);..}
7900: 0a 0a 09 6d 65 6d 73 65 74 28 73 74 62 75 66 2c  ...memset(stbuf,
7910: 20 30 2c 20 73 69 7a 65 6f 66 28 73 74 72 75 63   0, sizeof(struc
7920: 74 20 73 74 61 74 29 29 3b 0a 0a 09 73 74 62 75  t stat));...stbu
7930: 66 2d 3e 73 74 5f 6d 74 69 6d 65 20 3d 20 70 61  f->st_mtime = pa
7940: 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74  thinfo.time;..st
7950: 62 75 66 2d 3e 73 74 5f 63 74 69 6d 65 20 3d 20  buf->st_ctime = 
7960: 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09  pathinfo.time;..
7970: 73 74 62 75 66 2d 3e 73 74 5f 61 74 69 6d 65 20  stbuf->st_atime 
7980: 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b  = pathinfo.time;
7990: 0a 09 73 74 62 75 66 2d 3e 73 74 5f 69 6e 6f 20  ..stbuf->st_ino 
79a0: 20 20 3d 20 70 61 74 68 69 6e 66 6f 2e 69 6e 6f    = pathinfo.ino
79b0: 64 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 6d  de;..stbuf->st_m
79c0: 6f 64 65 20 20 3d 20 30 3b 0a 0a 09 63 68 61 6e  ode  = 0;...chan
79d0: 67 65 4f 77 6e 65 72 54 6f 55 73 65 72 49 66 50  geOwnerToUserIfP
79e0: 61 63 6b 61 67 65 64 20 3d 20 31 3b 0a 0a 09 73  ackaged = 1;...s
79f0: 77 69 74 63 68 20 28 70 61 74 68 69 6e 66 6f 2e  witch (pathinfo.
7a00: 74 79 70 65 29 20 7b 0a 09 09 63 61 73 65 20 41  type) {...case A
7a10: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49  PPFS_PATHTYPE_DI
7a20: 52 45 43 54 4f 52 59 3a 0a 09 09 09 73 74 62 75  RECTORY:....stbu
7a30: 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49  f->st_mode = S_I
7a40: 46 44 49 52 20 7c 20 30 35 35 35 3b 0a 09 09 09  FDIR | 0555;....
7a50: 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20  stbuf->st_nlink 
7a60: 3d 20 32 20 2b 20 70 61 74 68 69 6e 66 6f 2e 74  = 2 + pathinfo.t
7a70: 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c  ypeinfo.dir.chil
7a80: 64 63 6f 75 6e 74 3b 0a 09 09 09 62 72 65 61 6b  dcount;....break
7a90: 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50  ;...case APPFS_P
7aa0: 41 54 48 54 59 50 45 5f 46 49 4c 45 3a 0a 09 09  ATHTYPE_FILE:...
7ab0: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
7ac0: 3d 20 53 5f 49 46 52 45 47 20 7c 20 30 34 34 34  = S_IFREG | 0444
7ad0: 3b 0a 0a 09 09 09 69 66 20 28 70 61 74 68 69 6e  ;.....if (pathin
7ae0: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  fo.typeinfo.file
7af0: 2e 65 78 65 63 75 74 61 62 6c 65 29 20 7b 0a 09  .executable) {..
7b00: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ...stbuf->st_mod
7b10: 65 20 7c 3d 20 30 31 31 31 3b 0a 09 09 09 7d 0a  e |= 0111;....}.
7b20: 0a 09 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f  ....if (pathinfo
7b30: 2e 70 61 63 6b 61 67 65 64 29 20 7b 0a 09 09 09  .packaged) {....
7b40: 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 74 79  .if (pathinfo.ty
7b50: 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 75 69 64  peinfo.file.suid
7b60: 52 6f 6f 74 29 20 7b 0a 09 09 09 09 09 63 68 61  Root) {......cha
7b70: 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65 72 49 66  ngeOwnerToUserIf
7b80: 50 61 63 6b 61 67 65 64 20 3d 20 30 3b 0a 0a 09  Packaged = 0;...
7b90: 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
7ba0: 64 65 20 7c 3d 20 30 34 30 30 30 3b 0a 09 09 09  de |= 04000;....
7bb0: 09 7d 0a 09 09 09 7d 0a 0a 09 09 09 69 66 20 28  .}....}.....if (
7bc0: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66  pathinfo.typeinf
7bd0: 6f 2e 66 69 6c 65 2e 77 6f 72 6c 64 61 63 63 65  o.file.worldacce
7be0: 73 73 69 62 6c 65 29 20 7b 0a 09 09 09 09 73 74  ssible) {.....st
7bf0: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 26 3d 20  buf->st_mode &= 
7c00: 7e 30 37 37 3b 0a 09 09 09 7d 0a 0a 09 09 09 73  ~077;....}.....s
7c10: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d  tbuf->st_nlink =
7c20: 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74   1;....stbuf->st
7c30: 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e 66 6f  _size = pathinfo
7c40: 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73  .typeinfo.file.s
7c50: 69 7a 65 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a  ize;.....break;.
7c60: 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54  ..case APPFS_PAT
7c70: 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3a 0a 09  HTYPE_SYMLINK:..
7c80: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65  ..stbuf->st_mode
7c90: 20 3d 20 53 5f 49 46 4c 4e 4b 20 7c 20 30 35 35   = S_IFLNK | 055
7ca0: 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  5;....stbuf->st_
7cb0: 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74  nlink = 1;....st
7cc0: 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 70  buf->st_size = p
7cd0: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
7ce0: 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 3b 0a 09  .symlink.size;..
7cf0: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20  ..break;...case 
7d00: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53  APPFS_PATHTYPE_S
7d10: 4f 43 4b 45 54 3a 0a 09 09 09 73 74 62 75 66 2d  OCKET:....stbuf-
7d20: 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 53  >st_mode = S_IFS
7d30: 4f 43 4b 20 7c 20 30 35 35 35 3b 0a 09 09 09 73  OCK | 0555;....s
7d40: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d  tbuf->st_nlink =
7d50: 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74   1;....stbuf->st
7d60: 5f 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 62 72  _size = 0;....br
7d70: 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46  eak;...case APPF
7d80: 53 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3a  S_PATHTYPE_FIFO:
7d90: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
7da0: 64 65 20 3d 20 53 5f 49 46 49 46 4f 20 7c 20 30  de = S_IFIFO | 0
7db0: 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  555;....stbuf->s
7dc0: 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09  t_nlink = 1;....
7dd0: 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d  stbuf->st_size =
7de0: 20 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09   0;....break;...
7df0: 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54  case APPFS_PATHT
7e00: 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49  YPE_DOES_NOT_EXI
7e10: 53 54 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20  ST:....retval = 
7e20: 2d 45 4e 4f 45 4e 54 3b 0a 0a 09 09 09 62 72 65  -ENOENT;.....bre
7e30: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53  ak;...case APPFS
7e40: 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49  _PATHTYPE_INVALI
7e50: 44 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20 2d  D:....retval = -
7e60: 45 49 4f 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a  EIO;.....break;.
7e70: 09 7d 0a 0a 09 69 66 20 28 28 70 61 74 68 69 6e  .}...if ((pathin
7e80: 66 6f 2e 70 61 63 6b 61 67 65 64 20 26 26 20 63  fo.packaged && c
7e90: 68 61 6e 67 65 4f 77 6e 65 72 54 6f 55 73 65 72  hangeOwnerToUser
7ea0: 49 66 50 61 63 6b 61 67 65 64 29 20 7c 7c 20 28  IfPackaged) || (
7eb0: 21 70 61 74 68 69 6e 66 6f 2e 70 61 63 6b 61 67  !pathinfo.packag
7ec0: 65 64 29 29 20 7b 0a 09 09 73 74 62 75 66 2d 3e  ed)) {...stbuf->
7ed0: 73 74 5f 75 69 64 20 20 20 3d 20 61 70 70 66 73  st_uid   = appfs
7ee0: 5f 67 65 74 5f 66 73 75 69 64 28 29 3b 0a 09 09  _get_fsuid();...
7ef0: 73 74 62 75 66 2d 3e 73 74 5f 67 69 64 20 20 20  stbuf->st_gid   
7f00: 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69  = appfs_get_fsgi
7f10: 64 28 29 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74  d();...stbuf->st
7f20: 5f 6d 6f 64 65 20 7c 3d 20 30 32 30 30 3b 0a 09  _mode |= 0200;..
7f30: 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61  }...return(retva
7f40: 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  l);.}..static in
7f50: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61  t appfs_fuse_rea
7f60: 64 64 69 72 28 63 6f 6e 73 74 20 63 68 61 72 20  ddir(const char 
7f70: 2a 70 61 74 68 2c 20 76 6f 69 64 20 2a 62 75 66  *path, void *buf
7f80: 2c 20 66 75 73 65 5f 66 69 6c 6c 5f 64 69 72 5f  , fuse_fill_dir_
7f90: 74 20 66 69 6c 6c 65 72 2c 20 6f 66 66 5f 74 20  t filler, off_t 
7fa0: 6f 66 66 73 65 74 2c 20 73 74 72 75 63 74 20 66  offset, struct f
7fb0: 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66  use_file_info *f
7fc0: 69 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  i) {..Tcl_Interp
7fd0: 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c 5f 4f   *interp;..Tcl_O
7fe0: 62 6a 20 2a 2a 63 68 69 6c 64 72 65 6e 3b 0a 09  bj **children;..
7ff0: 69 6e 74 20 63 68 69 6c 64 72 65 6e 5f 63 6f 75  int children_cou
8000: 6e 74 2c 20 69 64 78 3b 0a 09 69 6e 74 20 74 63  nt, idx;..int tc
8010: 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  l_ret;...APPFS_D
8020: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
8030: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
8040: 61 74 68 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d  ath);...interp =
8050: 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70   appfs_TclInterp
8060: 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  ();..if (interp 
8070: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50  == NULL) {...APP
8080: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
8090: 20 55 6e 61 62 6c 65 20 74 6f 20 67 65 74 20 61   Unable to get a
80a0: 6e 20 69 6e 74 65 72 70 72 65 74 65 72 22 29 3b  n interpreter");
80b0: 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09  ....return(0);..
80c0: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
80d0: 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72  ibtcl(Tcl_Preser
80e0: 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 66  ve(interp);)...f
80f0: 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e 22 2c 20  iller(buf, ".", 
8100: 4e 55 4c 4c 2c 20 30 29 3b 0a 09 66 69 6c 6c 65  NULL, 0);..fille
8110: 72 28 62 75 66 2c 20 22 2e 2e 22 2c 20 4e 55 4c  r(buf, "..", NUL
8120: 4c 2c 20 30 29 3b 0a 0a 09 74 63 6c 5f 72 65 74  L, 0);...tcl_ret
8130: 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61   = appfs_Tcl_Eva
8140: 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a  l(interp, 2, "::
8150: 61 70 70 66 73 3a 3a 67 65 74 63 68 69 6c 64 72  appfs::getchildr
8160: 65 6e 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20  en", path);..if 
8170: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
8180: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
8190: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65  BUG("::appfs::ge
81a0: 74 63 68 69 6c 64 72 65 6e 28 25 73 29 20 66 61  tchildren(%s) fa
81b0: 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09  iled.", path);..
81c0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
81d0: 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42  cl(....APPFS_DEB
81e0: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
81f0: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
8200: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
8210: 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66  p));...)....appf
8220: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
8230: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
8240: 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 30 29  );)....return(0)
8250: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
8260: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f  l_libtcl(...tcl_
8270: 72 65 74 20 3d 20 54 63 6c 5f 4c 69 73 74 4f 62  ret = Tcl_ListOb
8280: 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e 74  jGetElements(int
8290: 65 72 70 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52  erp, Tcl_GetObjR
82a0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 26  esult(interp), &
82b0: 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c 20  children_count, 
82c0: 26 63 68 69 6c 64 72 65 6e 29 3b 0a 09 29 0a 09  &children);..)..
82d0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
82e0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
82f0: 5f 44 45 42 55 47 28 22 50 61 72 73 69 6e 67 20  _DEBUG("Parsing 
8300: 6c 69 73 74 20 6f 66 20 63 68 69 6c 64 72 65 6e  list of children
8310: 20 6f 6e 20 70 61 74 68 20 25 73 20 66 61 69 6c   on path %s fail
8320: 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61  ed.", path);...a
8330: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c  ppfs_call_libtcl
8340: 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  (....APPFS_DEBUG
8350: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20  ("Tcl Error is: 
8360: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  %s", Tcl_GetStri
8370: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
8380: 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f  );...)....appfs_
8390: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
83a0: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
83b0: 29 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a  )....return(0);.
83c0: 09 7d 0a 0a 09 66 6f 72 20 28 69 64 78 20 3d 20  .}...for (idx = 
83d0: 30 3b 20 69 64 78 20 3c 20 63 68 69 6c 64 72 65  0; idx < childre
83e0: 6e 5f 63 6f 75 6e 74 3b 20 69 64 78 2b 2b 29 20  n_count; idx++) 
83f0: 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  {...appfs_call_l
8400: 69 62 74 63 6c 28 0a 09 09 09 66 69 6c 6c 65 72  ibtcl(....filler
8410: 28 62 75 66 2c 20 54 63 6c 5f 47 65 74 53 74 72  (buf, Tcl_GetStr
8420: 69 6e 67 28 63 68 69 6c 64 72 65 6e 5b 69 64 78  ing(children[idx
8430: 5d 29 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 09  ]), NULL, 0);...
8440: 29 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  )..}...appfs_cal
8450: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c  l_libtcl(Tcl_Rel
8460: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a  ease(interp);)..
8470: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
8480: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
8490: 66 75 73 65 5f 6f 70 65 6e 28 63 6f 6e 73 74 20  fuse_open(const 
84a0: 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75  char *path, stru
84b0: 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66  ct fuse_file_inf
84c0: 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c 5f 49 6e  o *fi) {..Tcl_In
84d0: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 73  terp *interp;..s
84e0: 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68  truct appfs_path
84f0: 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09  info pathinfo;..
8500: 63 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c  const char *real
8510: 5f 70 61 74 68 2c 20 2a 6d 6f 64 65 3b 0a 09 69  _path, *mode;..i
8520: 6e 74 20 67 70 69 5f 72 65 74 2c 20 74 63 6c 5f  nt gpi_ret, tcl_
8530: 72 65 74 3b 0a 09 69 6e 74 20 66 68 3b 0a 0a 09  ret;..int fh;...
8540: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
8550: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
8560: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 23 69  ..)", path);..#i
8570: 66 20 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f  f defined(APPFS_
8580: 45 58 45 43 5f 50 41 54 48 5f 45 4e 41 42 4c 45  EXEC_PATH_ENABLE
8590: 5f 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f  _MAJOR_SECURITY_
85a0: 48 4f 4c 45 29 0a 09 69 66 20 28 73 74 72 63 6d  HOLE)..if (strcm
85b0: 70 28 70 61 74 68 2c 20 22 2f 65 78 65 63 22 29  p(path, "/exec")
85c0: 20 3d 3d 20 30 29 20 7b 0a 09 09 66 69 2d 3e 66   == 0) {...fi->f
85d0: 68 20 3d 20 30 3b 0a 0a 09 09 72 65 74 75 72 6e  h = 0;....return
85e0: 28 30 29 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a  (0);..}.#endif..
85f0: 09 67 70 69 5f 72 65 74 20 3d 20 61 70 70 66 73  .gpi_ret = appfs
8600: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70  _get_path_info(p
8610: 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b  ath, &pathinfo);
8620: 0a 0a 09 69 66 20 28 28 66 69 2d 3e 66 6c 61 67  ...if ((fi->flag
8630: 73 20 26 20 28 4f 5f 57 52 4f 4e 4c 59 7c 4f 5f  s & (O_WRONLY|O_
8640: 43 52 45 41 54 29 29 20 3d 3d 20 28 4f 5f 43 52  CREAT)) == (O_CR
8650: 45 41 54 7c 4f 5f 57 52 4f 4e 4c 59 29 29 20 7b  EAT|O_WRONLY)) {
8660: 0a 09 09 2f 2a 20 54 68 65 20 66 69 6c 65 20 77  .../* The file w
8670: 69 6c 6c 20 62 65 20 63 72 65 61 74 65 64 20 69  ill be created i
8680: 66 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 65 78  f it does not ex
8690: 69 73 74 20 2a 2f 0a 09 09 69 66 20 28 67 70 69  ist */...if (gpi
86a0: 5f 72 65 74 20 21 3d 20 30 20 26 26 20 67 70 69  _ret != 0 && gpi
86b0: 5f 72 65 74 20 21 3d 20 2d 45 4e 4f 45 4e 54 29  _ret != -ENOENT)
86c0: 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55   {....APPFS_DEBU
86d0: 47 28 22 65 72 72 6f 72 3a 20 67 65 74 5f 70 61  G("error: get_pa
86e0: 74 68 5f 69 6e 66 6f 20 66 61 69 6c 65 64 22 29  th_info failed")
86f0: 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 67 70 69  ;.....return(gpi
8700: 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d 6f  _ret);...}....mo
8710: 64 65 20 3d 20 22 63 72 65 61 74 65 22 3b 0a 0a  de = "create";..
8720: 09 09 2f 2a 0a 09 09 20 2a 20 57 65 20 68 61 76  ../*... * We hav
8730: 65 20 74 6f 20 63 6c 65 61 72 20 74 68 65 20 63  e to clear the c
8740: 61 63 68 65 20 68 65 72 65 20 73 6f 20 74 68 61  ache here so tha
8750: 74 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 0a  t the number of.
8760: 09 09 20 2a 20 6c 69 6e 6b 73 20 67 65 74 73 20  .. * links gets 
8770: 6d 61 69 6e 74 61 69 6e 65 64 20 6f 6e 20 74 68  maintained on th
8780: 65 20 70 61 72 65 6e 74 20 64 69 72 65 63 74 6f  e parent directo
8790: 72 79 0a 09 09 20 2a 2f 0a 09 09 61 70 70 66 73  ry... */...appfs
87a0: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  _get_path_info_c
87b0: 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73  ache_flush(appfs
87c0: 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31  _get_fsuid(), -1
87d0: 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 2f  );..} else {.../
87e0: 2a 20 54 68 65 20 66 69 6c 65 20 6d 75 73 74 20  * The file must 
87f0: 61 6c 72 65 61 64 79 20 65 78 69 73 74 20 2a 2f  already exist */
8800: 0a 09 09 69 66 20 28 67 70 69 5f 72 65 74 20 21  ...if (gpi_ret !
8810: 3d 20 30 29 20 7b 0a 09 09 09 41 50 50 46 53 5f  = 0) {....APPFS_
8820: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 67 65  DEBUG("error: ge
8830: 74 5f 70 61 74 68 5f 69 6e 66 6f 20 66 61 69 6c  t_path_info fail
8840: 65 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e  ed");.....return
8850: 28 67 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a  (gpi_ret);...}..
8860: 09 09 6d 6f 64 65 20 3d 20 22 22 3b 0a 0a 09 09  ..mode = "";....
8870: 69 66 20 28 28 66 69 2d 3e 66 6c 61 67 73 20 26  if ((fi->flags &
8880: 20 4f 5f 57 52 4f 4e 4c 59 29 20 3d 3d 20 4f 5f   O_WRONLY) == O_
8890: 57 52 4f 4e 4c 59 29 20 7b 0a 09 09 09 6d 6f 64  WRONLY) {....mod
88a0: 65 20 3d 20 22 77 72 69 74 65 22 3b 0a 09 09 7d  e = "write";...}
88b0: 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e  ..}...if (pathin
88c0: 66 6f 2e 74 79 70 65 20 3d 3d 20 41 50 50 46 53  fo.type == APPFS
88d0: 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45 43 54  _PATHTYPE_DIRECT
88e0: 4f 52 59 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  ORY) {...APPFS_D
88f0: 45 42 55 47 28 22 65 72 72 6f 72 3a 20 41 73 6b  EBUG("error: Ask
8900: 65 64 20 74 6f 20 6f 70 65 6e 20 61 20 64 69 72  ed to open a dir
8910: 65 63 74 6f 72 79 2e 22 29 3b 0a 0a 09 09 72 65  ectory.");....re
8920: 74 75 72 6e 28 2d 45 49 53 44 49 52 29 3b 0a 09  turn(-EISDIR);..
8930: 7d 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  }...interp = app
8940: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a  fs_TclInterp();.
8950: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
8960: 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  ULL) {...APPFS_D
8970: 45 42 55 47 28 22 65 72 72 6f 72 3a 20 55 6e 61  EBUG("error: Una
8980: 62 6c 65 20 74 6f 20 67 65 74 20 61 6e 20 69 6e  ble to get an in
8990: 74 65 72 70 72 65 74 65 72 22 29 3b 0a 0a 09 09  terpreter");....
89a0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
89b0: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
89c0: 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76  btcl(Tcl_Preserv
89d0: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63  e(interp);)...tc
89e0: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
89f0: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 33  l_Eval(interp, 3
8a00: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e  , "::appfs::open
8a10: 70 61 74 68 22 2c 20 70 61 74 68 2c 20 6d 6f 64  path", path, mod
8a20: 65 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  e);..if (tcl_ret
8a30: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
8a40: 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61  APPFS_DEBUG("::a
8a50: 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28 25  ppfs::openpath(%
8a60: 73 2c 20 25 73 29 20 66 61 69 6c 65 64 2e 22 2c  s, %s) failed.",
8a70: 20 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 09 09   path, mode);...
8a80: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63  appfs_call_libtc
8a90: 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55  l(....APPFS_DEBU
8aa0: 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  G("Tcl Error is:
8ab0: 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72   %s", Tcl_GetStr
8ac0: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
8ad0: 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73  ));...)....appfs
8ae0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c  _call_libtcl(Tcl
8af0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
8b00: 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ;)....return(-EI
8b10: 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63  O);..}...appfs_c
8b20: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65  all_libtcl(...re
8b30: 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65  al_path = Tcl_Ge
8b40: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
8b50: 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66  terp);..)...appf
8b60: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63  s_call_libtcl(Tc
8b70: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
8b80: 29 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70  );)...if (real_p
8b90: 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ath == NULL) {..
8ba0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72  .APPFS_DEBUG("er
8bb0: 72 6f 72 3a 20 72 65 61 6c 5f 70 61 74 68 20 77  ror: real_path w
8bc0: 61 73 20 4e 55 4c 4c 2e 22 29 0a 0a 09 09 72 65  as NULL.")....re
8bd0: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
8be0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 72  .APPFS_DEBUG("Tr
8bf0: 61 6e 73 6c 61 74 65 64 20 72 65 71 75 65 73 74  anslated request
8c00: 20 74 6f 20 6f 70 65 6e 20 25 73 20 74 6f 20 6f   to open %s to o
8c10: 70 65 6e 69 6e 67 20 25 73 20 28 6d 6f 64 65 20  pening %s (mode 
8c20: 3d 20 5c 22 25 73 5c 22 29 22 2c 20 70 61 74 68  = \"%s\")", path
8c30: 2c 20 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64  , real_path, mod
8c40: 65 29 3b 0a 0a 09 66 68 20 3d 20 6f 70 65 6e 28  e);...fh = open(
8c50: 72 65 61 6c 5f 70 61 74 68 2c 20 66 69 2d 3e 66  real_path, fi->f
8c60: 6c 61 67 73 2c 20 30 36 30 30 29 3b 0a 0a 09 69  lags, 0600);...i
8c70: 66 20 28 66 68 20 3c 20 30 29 20 7b 0a 09 09 41  f (fh < 0) {...A
8c80: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
8c90: 72 3a 20 6f 70 65 6e 20 66 61 69 6c 65 64 22 29  r: open failed")
8ca0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e  ;....return(errn
8cb0: 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66 69  o * -1);..}...fi
8cc0: 2d 3e 66 68 20 3d 20 66 68 3b 0a 0a 09 41 50 50  ->fh = fh;...APP
8cd0: 46 53 5f 44 45 42 55 47 28 22 4f 70 65 6e 65 64  FS_DEBUG("Opened
8ce0: 20 5c 22 25 73 5c 22 20 28 66 6f 72 20 5c 22 25   \"%s\" (for \"%
8cf0: 73 5c 22 29 20 77 69 74 68 20 66 69 6c 65 20 64  s\") with file d
8d00: 65 73 63 72 69 70 74 6f 72 20 25 69 22 2c 20 72  escriptor %i", r
8d10: 65 61 6c 5f 70 61 74 68 2c 20 70 61 74 68 2c 20  eal_path, path, 
8d20: 66 68 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29  fh);...return(0)
8d30: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
8d40: 61 70 70 66 73 5f 66 75 73 65 5f 63 6c 6f 73 65  appfs_fuse_close
8d50: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
8d60: 68 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66  h, struct fuse_f
8d70: 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a  ile_info *fi) {.
8d80: 09 69 6e 74 20 63 6c 6f 73 65 5f 72 65 74 3b 0a  .int close_ret;.
8d90: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45  ..APPFS_DEBUG("E
8da0: 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c  nter (path = %s,
8db0: 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a   ...)", path);..
8dc0: 23 69 66 20 64 65 66 69 6e 65 64 28 41 50 50 46  #if defined(APPF
8dd0: 53 5f 45 58 45 43 5f 50 41 54 48 5f 45 4e 41 42  S_EXEC_PATH_ENAB
8de0: 4c 45 5f 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54  LE_MAJOR_SECURIT
8df0: 59 5f 48 4f 4c 45 29 0a 09 69 66 20 28 73 74 72  Y_HOLE)..if (str
8e00: 63 6d 70 28 70 61 74 68 2c 20 22 2f 65 78 65 63  cmp(path, "/exec
8e10: 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74  ") == 0) {...ret
8e20: 75 72 6e 28 30 29 3b 0a 09 7d 0a 23 65 6e 64 69  urn(0);..}.#endi
8e30: 66 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61  f...appfs_get_pa
8e40: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d  th_info_cache_rm
8e50: 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74  (path, appfs_get
8e60: 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 63 6c 6f  _fsuid());...clo
8e70: 73 65 5f 72 65 74 20 3d 20 63 6c 6f 73 65 28 66  se_ret = close(f
8e80: 69 2d 3e 66 68 29 3b 0a 09 69 66 20 28 63 6c 6f  i->fh);..if (clo
8e90: 73 65 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  se_ret != 0) {..
8ea0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 72  .APPFS_DEBUG("er
8eb0: 72 6f 72 3a 20 63 6c 6f 73 65 20 66 61 69 6c 65  ror: close faile
8ec0: 64 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 65  d");....return(e
8ed0: 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a  rrno * -1);..}..
8ee0: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73  .return(0);.}..s
8ef0: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
8f00: 66 75 73 65 5f 72 65 61 64 28 63 6f 6e 73 74 20  fuse_read(const 
8f10: 63 68 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72  char *path, char
8f20: 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69   *buf, size_t si
8f30: 7a 65 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74  ze, off_t offset
8f40: 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69  , struct fuse_fi
8f50: 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09  le_info *fi) {..
8f60: 73 73 69 7a 65 5f 74 20 72 65 61 64 5f 72 65 74  ssize_t read_ret
8f70: 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a  ;..int retval;..
8f80: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
8f90: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
8fa0: 62 75 66 2c 20 73 69 7a 65 20 3d 20 25 6c 6c 69  buf, size = %lli
8fb0: 2c 20 6f 66 66 73 65 74 20 3d 20 25 6c 6c 69 2c  , offset = %lli,
8fc0: 20 66 64 20 3d 20 25 6c 6c 69 29 22 2c 20 70 61   fd = %lli)", pa
8fd0: 74 68 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20  th, (long long) 
8fe0: 73 69 7a 65 2c 20 28 6c 6f 6e 67 20 6c 6f 6e 67  size, (long long
8ff0: 29 20 6f 66 66 73 65 74 2c 20 28 6c 6f 6e 67 20  ) offset, (long 
9000: 6c 6f 6e 67 29 20 66 69 2d 3e 66 68 29 3b 0a 0a  long) fi->fh);..
9010: 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 77  .retval = 0;...w
9020: 68 69 6c 65 20 28 73 69 7a 65 20 21 3d 20 30 29  hile (size != 0)
9030: 20 7b 0a 23 69 66 64 65 66 20 41 50 50 46 53 5f   {.#ifdef APPFS_
9040: 4e 4f 5f 50 52 45 41 44 20 2f 2a 20 58 58 58 3a  NO_PREAD /* XXX:
9050: 54 4f 44 4f 3a 20 57 72 69 74 65 20 61 20 77 72  TODO: Write a wr
9060: 61 70 70 65 72 20 66 75 6e 63 74 69 6f 6e 20 2a  apper function *
9070: 2f 0a 09 09 6f 66 66 5f 74 20 73 65 65 6b 5f 72  /...off_t seek_r
9080: 65 74 3b 0a 0a 09 09 73 65 65 6b 5f 72 65 74 20  et;....seek_ret 
9090: 3d 20 6c 73 65 65 6b 28 66 69 2d 3e 66 68 2c 20  = lseek(fi->fh, 
90a0: 6f 66 66 73 65 74 2c 20 53 45 45 4b 5f 53 45 54  offset, SEEK_SET
90b0: 29 3b 0a 09 09 69 66 20 28 73 65 65 6b 5f 72 65  );...if (seek_re
90c0: 74 20 3d 3d 20 6f 66 66 73 65 74 29 20 7b 0a 09  t == offset) {..
90d0: 09 09 72 65 61 64 5f 72 65 74 20 3d 20 72 65 61  ..read_ret = rea
90e0: 64 28 66 69 2d 3e 66 68 2c 20 62 75 66 2c 20 73  d(fi->fh, buf, s
90f0: 69 7a 65 29 3b 0a 09 09 7d 20 65 6c 73 65 20 7b  ize);...} else {
9100: 0a 09 09 09 72 65 61 64 5f 72 65 74 20 3d 20 2d  ....read_ret = -
9110: 31 3b 0a 09 09 7d 0a 23 65 6c 73 65 0a 09 09 72  1;...}.#else...r
9120: 65 61 64 5f 72 65 74 20 3d 20 70 72 65 61 64 28  ead_ret = pread(
9130: 66 69 2d 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a  fi->fh, buf, siz
9140: 65 2c 20 6f 66 66 73 65 74 29 3b 0a 23 65 6e 64  e, offset);.#end
9150: 69 66 0a 0a 09 09 69 66 20 28 72 65 61 64 5f 72  if....if (read_r
9160: 65 74 20 3c 20 30 29 20 7b 0a 09 09 09 41 50 50  et < 0) {....APP
9170: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a  FS_DEBUG("error:
9180: 20 72 65 61 64 20 66 61 69 6c 65 64 22 29 3b 0a   read failed");.
9190: 0a 09 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f  ....return(errno
91a0: 20 2a 20 2d 31 29 3b 0a 09 09 7d 0a 0a 09 09 69   * -1);...}....i
91b0: 66 20 28 72 65 61 64 5f 72 65 74 20 3d 3d 20 30  f (read_ret == 0
91c0: 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09  ) {....break;...
91d0: 7d 0a 0a 09 09 73 69 7a 65 20 2d 3d 20 72 65 61  }....size -= rea
91e0: 64 5f 72 65 74 3b 0a 09 09 62 75 66 20 20 2b 3d  d_ret;...buf  +=
91f0: 20 72 65 61 64 5f 72 65 74 3b 0a 09 09 6f 66 66   read_ret;...off
9200: 73 65 74 20 2b 3d 20 72 65 61 64 5f 72 65 74 3b  set += read_ret;
9210: 0a 09 09 72 65 74 76 61 6c 20 2b 3d 20 72 65 61  ...retval += rea
9220: 64 5f 72 65 74 3b 0a 09 7d 0a 0a 09 69 66 20 28  d_ret;..}...if (
9230: 73 69 7a 65 20 21 3d 20 30 29 20 7b 0a 09 09 41  size != 0) {...A
9240: 50 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f  PPFS_DEBUG("erro
9250: 72 3a 20 69 6e 63 6f 6d 70 6c 65 74 65 20 72 65  r: incomplete re
9260: 61 64 20 28 74 68 69 73 20 6d 69 67 68 74 20 62  ad (this might b
9270: 65 20 61 6e 20 65 72 72 6f 72 20 62 65 63 61 75  e an error becau
9280: 73 65 20 46 55 53 45 20 77 69 6c 6c 20 72 65 71  se FUSE will req
9290: 75 65 73 74 20 74 68 65 20 65 78 61 63 74 20 6c  uest the exact l
92a0: 65 6e 67 74 68 20 6f 66 20 74 68 65 20 66 69 6c  ength of the fil
92b0: 65 29 22 29 3b 0a 09 7d 0a 0a 09 41 50 50 46 53  e)");..}...APPFS
92c0: 5f 44 45 42 55 47 28 22 52 65 74 75 72 6e 69 6e  _DEBUG("Returnin
92d0: 67 3a 20 25 69 22 2c 20 72 65 74 76 61 6c 29 3b  g: %i", retval);
92e0: 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
92f0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
9300: 20 61 70 70 66 73 5f 66 75 73 65 5f 77 72 69 74   appfs_fuse_writ
9310: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  e(const char *pa
9320: 74 68 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  th, const char *
9330: 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65  buf, size_t size
9340: 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20  , off_t offset, 
9350: 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65  struct fuse_file
9360: 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 73 73  _info *fi) {..ss
9370: 69 7a 65 5f 74 20 77 72 69 74 65 5f 72 65 74 3b  ize_t write_ret;
9380: 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09  ..int retval;...
9390: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
93a0: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
93b0: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 23 69  ..)", path);..#i
93c0: 66 20 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f  f defined(APPFS_
93d0: 45 58 45 43 5f 50 41 54 48 5f 45 4e 41 42 4c 45  EXEC_PATH_ENABLE
93e0: 5f 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f  _MAJOR_SECURITY_
93f0: 48 4f 4c 45 29 0a 09 69 66 20 28 73 74 72 63 6d  HOLE)..if (strcm
9400: 70 28 70 61 74 68 2c 20 22 2f 65 78 65 63 22 29  p(path, "/exec")
9410: 20 3d 3d 20 30 29 20 7b 0a 09 09 61 70 70 66 73   == 0) {...appfs
9420: 5f 72 75 6e 54 63 6c 28 62 75 66 2c 20 73 69 7a  _runTcl(buf, siz
9430: 65 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 73 69  e);....return(si
9440: 7a 65 29 3b 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a  ze);..}.#endif..
9450: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  .appfs_get_path_
9460: 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61  info_cache_rm(pa
9470: 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73  th, appfs_get_fs
9480: 75 69 64 28 29 29 3b 0a 0a 09 72 65 74 76 61 6c  uid());...retval
9490: 20 3d 20 30 3b 0a 0a 09 77 68 69 6c 65 20 28 73   = 0;...while (s
94a0: 69 7a 65 20 21 3d 20 30 29 20 7b 0a 23 69 66 64  ize != 0) {.#ifd
94b0: 65 66 20 41 50 50 46 53 5f 4e 4f 5f 50 57 52 49  ef APPFS_NO_PWRI
94c0: 54 45 20 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a 20  TE /* XXX:TODO: 
94d0: 57 72 69 74 65 20 61 20 77 72 61 70 70 65 72 20  Write a wrapper 
94e0: 66 75 6e 63 74 69 6f 6e 20 2a 2f 0a 23 20 20 69  function */.#  i
94f0: 66 20 31 0a 09 09 2f 2a 20 58 58 58 3a 54 4f 44  f 1.../* XXX:TOD
9500: 4f 3a 20 53 74 69 6c 6c 20 66 61 69 6c 73 20 6f  O: Still fails o
9510: 6e 20 77 69 6e 33 32 20 2a 2f 0a 09 09 77 72 69  n win32 */...wri
9520: 74 65 5f 72 65 74 20 3d 20 2d 31 3b 0a 23 65 6c  te_ret = -1;.#el
9530: 73 65 0a 09 09 6f 66 66 5f 74 20 73 65 65 6b 5f  se...off_t seek_
9540: 72 65 74 3b 0a 0a 09 09 73 65 65 6b 5f 72 65 74  ret;....seek_ret
9550: 20 3d 20 6c 73 65 65 6b 28 66 69 2d 3e 66 68 2c   = lseek(fi->fh,
9560: 20 6f 66 66 73 65 74 2c 20 53 45 45 4b 5f 53 45   offset, SEEK_SE
9570: 54 29 3b 0a 09 09 69 66 20 28 73 65 65 6b 5f 72  T);...if (seek_r
9580: 65 74 20 3d 3d 20 6f 66 66 73 65 74 29 20 7b 0a  et == offset) {.
9590: 09 09 09 77 72 69 74 65 5f 72 65 74 20 3d 20 77  ...write_ret = w
95a0: 72 69 74 65 28 66 69 2d 3e 66 68 2c 20 62 75 66  rite(fi->fh, buf
95b0: 2c 20 73 69 7a 65 29 3b 20 0a 09 09 7d 20 65 6c  , size); ...} el
95c0: 73 65 20 7b 0a 09 09 09 77 72 69 74 65 5f 72 65  se {....write_re
95d0: 74 20 3d 20 2d 31 3b 0a 09 09 7d 0a 23 20 20 65  t = -1;...}.#  e
95e0: 6e 64 69 66 0a 23 65 6c 73 65 0a 09 09 77 72 69  ndif.#else...wri
95f0: 74 65 5f 72 65 74 20 3d 20 70 77 72 69 74 65 28  te_ret = pwrite(
9600: 66 69 2d 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a  fi->fh, buf, siz
9610: 65 2c 20 6f 66 66 73 65 74 29 3b 0a 23 65 6e 64  e, offset);.#end
9620: 69 66 0a 0a 09 09 69 66 20 28 77 72 69 74 65 5f  if....if (write_
9630: 72 65 74 20 3c 20 30 29 20 7b 0a 09 09 09 41 50  ret < 0) {....AP
9640: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72  PFS_DEBUG("error
9650: 3a 20 77 72 69 74 65 20 66 61 69 6c 65 64 22 29  : write failed")
9660: 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 65 72 72  ;.....return(err
9670: 6e 6f 20 2a 20 2d 31 29 3b 0a 09 09 7d 0a 0a 09  no * -1);...}...
9680: 09 69 66 20 28 77 72 69 74 65 5f 72 65 74 20 3d  .if (write_ret =
9690: 3d 20 30 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b  = 0) {....break;
96a0: 0a 09 09 7d 0a 0a 09 09 73 69 7a 65 20 2d 3d 20  ...}....size -= 
96b0: 77 72 69 74 65 5f 72 65 74 3b 0a 09 09 62 75 66  write_ret;...buf
96c0: 20 20 2b 3d 20 77 72 69 74 65 5f 72 65 74 3b 0a    += write_ret;.
96d0: 09 09 6f 66 66 73 65 74 20 2b 3d 20 77 72 69 74  ..offset += writ
96e0: 65 5f 72 65 74 3b 0a 09 09 72 65 74 76 61 6c 20  e_ret;...retval 
96f0: 2b 3d 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 7d  += write_ret;..}
9700: 0a 0a 09 69 66 20 28 73 69 7a 65 20 21 3d 20 30  ...if (size != 0
9710: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
9720: 47 28 22 65 72 72 6f 72 3a 20 69 6e 63 6f 6d 70  G("error: incomp
9730: 6c 65 74 65 20 77 72 69 74 65 22 29 3b 0a 09 7d  lete write");..}
9740: 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
9750: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
9760: 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b 6e 6f   appfs_fuse_mkno
9770: 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  d(const char *pa
9780: 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c  th, mode_t mode,
9790: 20 64 65 76 5f 74 20 64 65 76 69 63 65 29 20 7b   dev_t device) {
97a0: 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74  ..char *real_pat
97b0: 68 3b 0a 09 69 6e 74 20 6d 6b 6e 6f 64 5f 72 65  h;..int mknod_re
97c0: 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  t;...APPFS_DEBUG
97d0: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
97e0: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
97f0: 3b 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20  ;...if ((mode & 
9800: 53 5f 49 46 43 48 52 29 20 3d 3d 20 53 5f 49 46  S_IFCHR) == S_IF
9810: 43 48 52 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  CHR) {...return(
9820: 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69 66  -EPERM);..}...if
9830: 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 42 4c   ((mode & S_IFBL
9840: 4b 29 20 3d 3d 20 53 5f 49 46 42 4c 4b 29 20 7b  K) == S_IFBLK) {
9850: 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45 52 4d  ...return(-EPERM
9860: 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74  );..}...real_pat
9870: 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72  h = appfs_prepar
9880: 65 5f 74 6f 5f 63 72 65 61 74 65 28 70 61 74 68  e_to_create(path
9890: 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74  );..if (real_pat
98a0: 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  h == NULL) {...r
98b0: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a  eturn(-EIO);..}.
98c0: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  ..appfs_simulate
98d0: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29  _user_fs_enter()
98e0: 3b 0a 0a 09 6d 6b 6e 6f 64 5f 72 65 74 20 3d 20  ;...mknod_ret = 
98f0: 6d 6b 6e 6f 64 28 72 65 61 6c 5f 70 61 74 68 2c  mknod(real_path,
9900: 20 6d 6f 64 65 2c 20 64 65 76 69 63 65 29 3b 0a   mode, device);.
9910: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  ..appfs_simulate
9920: 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29  _user_fs_leave()
9930: 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61  ;...free(real_pa
9940: 74 68 29 3b 0a 0a 09 69 66 20 28 6d 6b 6e 6f 64  th);...if (mknod
9950: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72  _ret != 0) {...r
9960: 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31  eturn(errno * -1
9970: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30  );..}...return(0
9980: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
9990: 20 61 70 70 66 73 5f 66 75 73 65 5f 63 72 65 61   appfs_fuse_crea
99a0: 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  te(const char *p
99b0: 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65  ath, mode_t mode
99c0: 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69  , struct fuse_fi
99d0: 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09  le_info *fi) {..
99e0: 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b  char *real_path;
99f0: 0a 09 69 6e 74 20 66 64 3b 0a 0a 09 41 50 50 46  ..int fd;...APPF
9a00: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
9a10: 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22  path = %s, ...)"
9a20: 2c 20 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 28  , path);...if ((
9a30: 6d 6f 64 65 20 26 20 53 5f 49 46 43 48 52 29 20  mode & S_IFCHR) 
9a40: 3d 3d 20 53 5f 49 46 43 48 52 29 20 7b 0a 09 09  == S_IFCHR) {...
9a50: 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a  return(-EPERM);.
9a60: 09 7d 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26  .}...if ((mode &
9a70: 20 53 5f 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49   S_IFBLK) == S_I
9a80: 46 42 4c 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e  FBLK) {...return
9a90: 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72  (-EPERM);..}...r
9aa0: 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73  eal_path = appfs
9ab0: 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61  _prepare_to_crea
9ac0: 74 65 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72  te(path);..if (r
9ad0: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
9ae0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
9af0: 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73  O);..}...appfs_s
9b00: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
9b10: 65 6e 74 65 72 28 29 3b 0a 0a 09 66 64 20 3d 20  enter();...fd = 
9b20: 63 72 65 61 74 28 72 65 61 6c 5f 70 61 74 68 2c  creat(real_path,
9b30: 20 6d 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f   mode);...appfs_
9b40: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73  simulate_user_fs
9b50: 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65  _leave();...free
9b60: 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69  (real_path);...i
9b70: 66 20 28 66 64 20 3c 20 30 29 20 7b 0a 09 09 72  f (fd < 0) {...r
9b80: 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31  eturn(errno * -1
9b90: 29 3b 0a 09 7d 0a 0a 09 66 69 2d 3e 66 68 20 3d  );..}...fi->fh =
9ba0: 20 66 64 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29   fd;...return(0)
9bb0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
9bc0: 61 70 70 66 73 5f 66 75 73 65 5f 74 72 75 6e 63  appfs_fuse_trunc
9bd0: 61 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ate(const char *
9be0: 70 61 74 68 2c 20 6f 66 66 5f 74 20 73 69 7a 65  path, off_t size
9bf0: 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f  ) {..char *real_
9c00: 70 61 74 68 3b 0a 09 69 6e 74 20 74 72 75 6e 63  path;..int trunc
9c10: 61 74 65 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53  ate_ret;...APPFS
9c20: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
9c30: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c  ath = %s, ...)",
9c40: 20 70 61 74 68 29 3b 0a 0a 23 69 66 20 64 65 66   path);..#if def
9c50: 69 6e 65 64 28 41 50 50 46 53 5f 45 58 45 43 5f  ined(APPFS_EXEC_
9c60: 50 41 54 48 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f  PATH_ENABLE_MAJO
9c70: 52 5f 53 45 43 55 52 49 54 59 5f 48 4f 4c 45 29  R_SECURITY_HOLE)
9c80: 0a 09 69 66 20 28 73 74 72 63 6d 70 28 70 61 74  ..if (strcmp(pat
9c90: 68 2c 20 22 2f 65 78 65 63 22 29 20 3d 3d 20 30  h, "/exec") == 0
9ca0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 30 29 3b  ) {...return(0);
9cb0: 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 72 65 61  ..}.#endif...rea
9cc0: 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 6c  l_path = appfs_l
9cd0: 6f 63 61 6c 70 61 74 68 28 70 61 74 68 29 3b 0a  ocalpath(path);.
9ce0: 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d  .if (real_path =
9cf0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
9d00: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61  rn(-EIO);..}...a
9d10: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
9d20: 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68  fo_cache_rm(path
9d30: 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  , appfs_get_fsui
9d40: 64 28 29 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69  d());...appfs_si
9d50: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65  mulate_user_fs_e
9d60: 6e 74 65 72 28 29 3b 0a 0a 09 74 72 75 6e 63 61  nter();...trunca
9d70: 74 65 5f 72 65 74 20 3d 20 74 72 75 6e 63 61 74  te_ret = truncat
9d80: 65 28 72 65 61 6c 5f 70 61 74 68 2c 20 73 69 7a  e(real_path, siz
9d90: 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  e);...appfs_simu
9da0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
9db0: 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61  ve();...free(rea
9dc0: 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 74  l_path);...if (t
9dd0: 72 75 6e 63 61 74 65 5f 72 65 74 20 21 3d 20 30  runcate_ret != 0
9de0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72 72  ) {...return(err
9df0: 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72  no * -1);..}...r
9e00: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61  eturn(0);.}..sta
9e10: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
9e20: 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72 28  se_unlink_rmdir(
9e30: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68  const char *path
9e40: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
9e50: 2a 69 6e 74 65 72 70 3b 0a 09 69 6e 74 20 74 63  *interp;..int tc
9e60: 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  l_ret;...APPFS_D
9e70: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
9e80: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
9e90: 61 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65  ath);...appfs_ge
9ea0: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  t_path_info_cach
9eb0: 65 5f 66 6c 75 73 68 28 61 70 70 66 73 5f 67 65  e_flush(appfs_ge
9ec0: 74 5f 66 73 75 69 64 28 29 2c 20 2d 31 29 3b 0a  t_fsuid(), -1);.
9ed0: 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
9ee0: 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69  _TclInterp();..i
9ef0: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
9f00: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  L) {...return(-E
9f10: 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f  IO);..}...appfs_
9f20: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f  call_libtcl(Tcl_
9f30: 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29  Preserve(interp)
9f40: 3b 29 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61  ;)...tcl_ret = a
9f50: 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e  ppfs_Tcl_Eval(in
9f60: 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66  terp, 2, "::appf
9f70: 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68 22 2c 20  s::unlinkpath", 
9f80: 70 61 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f  path);..if (tcl_
9f90: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
9fa0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
9fb0: 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c 69 6e 6b 70  ::appfs::unlinkp
9fc0: 61 74 68 28 25 73 29 20 66 61 69 6c 65 64 2e 22  ath(%s) failed."
9fd0: 2c 20 70 61 74 68 29 3b 0a 09 09 61 70 70 66 73  , path);...appfs
9fe0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
9ff0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63  .APPFS_DEBUG("Tc
a000: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c  l Error is: %s",
a010: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
a020: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09  sult(interp));..
a030: 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c  .)....appfs_call
a040: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65  _libtcl(Tcl_Rele
a050: 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  ase(interp);)...
a060: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
a070: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  }...appfs_call_l
a080: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
a090: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 72 65  e(interp);)...re
a0a0: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
a0b0: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
a0c0: 65 5f 6d 6b 64 69 72 28 63 6f 6e 73 74 20 63 68  e_mkdir(const ch
a0d0: 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74  ar *path, mode_t
a0e0: 20 6d 6f 64 65 29 20 7b 0a 09 63 68 61 72 20 2a   mode) {..char *
a0f0: 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20  real_path;..int 
a100: 6d 6b 64 69 72 5f 72 65 74 3b 0a 0a 09 41 50 50  mkdir_ret;...APP
a110: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
a120: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
a130: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 72 65 61 6c  ", path);...real
a140: 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72  _path = appfs_pr
a150: 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28  epare_to_create(
a160: 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c  path);..if (real
a170: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
a180: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
a190: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  ..}...appfs_simu
a1a0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
a1b0: 65 72 28 29 3b 0a 0a 09 6d 6b 64 69 72 5f 72 65  er();...mkdir_re
a1c0: 74 20 3d 20 6d 6b 64 69 72 28 72 65 61 6c 5f 70  t = mkdir(real_p
a1d0: 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61 70  ath, mode);...ap
a1e0: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
a1f0: 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09  r_fs_leave();...
a200: 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b  free(real_path);
a210: 0a 0a 09 69 66 20 28 6d 6b 64 69 72 5f 72 65 74  ...if (mkdir_ret
a220: 20 21 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 65   != 0) {...if (e
a230: 72 72 6e 6f 20 21 3d 20 45 45 58 49 53 54 29 20  rrno != EEXIST) 
a240: 7b 0a 09 09 09 72 65 74 75 72 6e 28 65 72 72 6e  {....return(errn
a250: 6f 20 2a 20 2d 31 29 3b 0a 09 09 7d 0a 09 7d 0a  o * -1);...}..}.
a260: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
a270: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
a280: 5f 66 75 73 65 5f 63 68 6d 6f 64 28 63 6f 6e 73  _fuse_chmod(cons
a290: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f  t char *path, mo
a2a0: 64 65 5f 74 20 6d 6f 64 65 29 20 7b 0a 09 54 63  de_t mode) {..Tc
a2b0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
a2c0: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72  ;..const char *r
a2d0: 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74  eal_path;..int t
a2e0: 63 6c 5f 72 65 74 2c 20 63 68 6d 6f 64 5f 72 65  cl_ret, chmod_re
a2f0: 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  t;...APPFS_DEBUG
a300: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
a310: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
a320: 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61  ;...appfs_get_pa
a330: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d  th_info_cache_rm
a340: 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74  (path, appfs_get
a350: 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 69 6e 74  _fsuid());...int
a360: 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49  erp = appfs_TclI
a370: 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e  nterp();..if (in
a380: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
a390: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
a3a0: 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f  .}...appfs_call_
a3b0: 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65  libtcl(Tcl_Prese
a3c0: 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09  rve(interp);)...
a3d0: 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f  tcl_ret = appfs_
a3e0: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
a3f0: 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6f 70   3, "::appfs::op
a400: 65 6e 70 61 74 68 22 2c 20 70 61 74 68 2c 20 22  enpath", path, "
a410: 77 72 69 74 65 22 29 3b 0a 09 69 66 20 28 74 63  write");..if (tc
a420: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
a430: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
a440: 28 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70  ("::appfs::openp
a450: 61 74 68 28 25 73 2c 20 25 73 29 20 66 61 69 6c  ath(%s, %s) fail
a460: 65 64 2e 22 2c 20 70 61 74 68 2c 20 22 77 72 69  ed.", path, "wri
a470: 74 65 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61  te");...appfs_ca
a480: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50  ll_libtcl(....AP
a490: 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45  PFS_DEBUG("Tcl E
a4a0: 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63  rror is: %s", Tc
a4b0: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
a4c0: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a  t(interp));...).
a4d0: 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69  ...appfs_call_li
a4e0: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65  btcl(Tcl_Release
a4f0: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65  (interp);)....re
a500: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
a510: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74  .appfs_call_libt
a520: 63 6c 28 0a 09 09 72 65 61 6c 5f 70 61 74 68 20  cl(...real_path 
a530: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  = Tcl_GetStringR
a540: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09  esult(interp);..
a550: 29 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c  )...appfs_call_l
a560: 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73  ibtcl(Tcl_Releas
a570: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 69 66  e(interp);)...if
a580: 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e   (real_path == N
a590: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
a5a0: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  -EIO);..}...appf
a5b0: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
a5c0: 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 63 68  fs_enter();...ch
a5d0: 6d 6f 64 5f 72 65 74 20 3d 20 63 68 6d 6f 64 28  mod_ret = chmod(
a5e0: 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29  real_path, mode)
a5f0: 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61  ;...appfs_simula
a600: 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65  te_user_fs_leave
a610: 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 63 68 6d  ();...return(chm
a620: 6f 64 5f 72 65 74 29 3b 0a 7d 0a 0a 73 74 61 74  od_ret);.}..stat
a630: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
a640: 65 5f 73 79 6d 6c 69 6e 6b 28 63 6f 6e 73 74 20  e_symlink(const 
a650: 63 68 61 72 20 2a 6f 6c 64 70 61 74 68 2c 20 63  char *oldpath, c
a660: 6f 6e 73 74 20 63 68 61 72 20 2a 6e 65 77 70 61  onst char *newpa
a670: 74 68 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61  th) {..char *rea
a680: 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 73 79 6d  l_path;..int sym
a690: 6c 69 6e 6b 5f 72 65 74 3b 0a 0a 09 41 50 50 46  link_ret;...APPF
a6a0: 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28  S_DEBUG("Enter (
a6b0: 70 61 74 68 20 3d 20 25 73 2c 20 25 73 29 22 2c  path = %s, %s)",
a6c0: 20 6f 6c 64 70 61 74 68 2c 20 6e 65 77 70 61 74   oldpath, newpat
a6d0: 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20  h);...real_path 
a6e0: 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f  = appfs_prepare_
a6f0: 74 6f 5f 63 72 65 61 74 65 28 6e 65 77 70 61 74  to_create(newpat
a700: 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61  h);..if (real_pa
a710: 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th == NULL) {...
a720: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
a730: 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74  ...appfs_simulat
a740: 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28  e_user_fs_enter(
a750: 29 3b 0a 0a 09 73 79 6d 6c 69 6e 6b 5f 72 65 74  );...symlink_ret
a760: 20 3d 20 73 79 6d 6c 69 6e 6b 28 6f 6c 64 70 61   = symlink(oldpa
a770: 74 68 2c 20 72 65 61 6c 5f 70 61 74 68 29 3b 0a  th, real_path);.
a780: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65  ..appfs_simulate
a790: 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29  _user_fs_leave()
a7a0: 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61  ;...free(real_pa
a7b0: 74 68 29 3b 0a 0a 09 69 66 20 28 73 79 6d 6c 69  th);...if (symli
a7c0: 6e 6b 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  nk_ret != 0) {..
a7d0: 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20  .return(errno * 
a7e0: 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  -1);..}...return
a7f0: 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 53 51  (0);.}../*. * SQ
a800: 4c 69 74 65 33 20 6d 6f 64 65 3a 20 45 78 65 63  Lite3 mode: Exec
a810: 75 74 65 20 72 61 77 20 53 51 4c 20 61 6e 64 20  ute raw SQL and 
a820: 72 65 74 75 72 6e 20 73 75 63 63 65 73 73 20 6f  return success o
a830: 72 20 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74  r failure. */.st
a840: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 73  atic int appfs_s
a850: 71 6c 69 74 65 33 28 63 6f 6e 73 74 20 63 68 61  qlite3(const cha
a860: 72 20 2a 73 71 6c 29 20 7b 0a 09 54 63 6c 5f 49  r *sql) {..Tcl_I
a870: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09  nterp *interp;..
a880: 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 5f  const char *sql_
a890: 72 65 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65  ret;..int tcl_re
a8a0: 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  t;...interp = ap
a8b0: 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e  pfs_create_TclIn
a8c0: 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 09 69 66 20  terp(NULL);..if 
a8d0: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
a8e0: 20 7b 0a 09 09 41 50 50 46 53 5f 45 52 52 4f 52   {...APPFS_ERROR
a8f0: 28 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61  ("Unable to crea
a900: 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72  te a Tcl interpr
a910: 65 74 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e  eter.  Aborting.
a920: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29  ");....return(1)
a930: 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d  ;..}...tcl_ret =
a940: 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28   appfs_Tcl_Eval(
a950: 69 6e 74 65 72 70 2c 20 35 2c 20 22 3a 3a 61 70  interp, 5, "::ap
a960: 70 66 73 3a 3a 64 62 22 2c 20 22 65 76 61 6c 22  pfs::db", "eval"
a970: 2c 20 73 71 6c 2c 20 22 72 6f 77 22 2c 20 22 75  , sql, "row", "u
a980: 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e  nset -nocomplain
a990: 20 72 6f 77 28 2a 29 3b 20 70 61 72 72 61 79 20   row(*); parray 
a9a0: 72 6f 77 3b 20 70 75 74 73 20 5c 22 2d 2d 2d 2d  row; puts \"----
a9b0: 5c 22 22 29 3b 0a 09 73 71 6c 5f 72 65 74 20 3d  \"");..sql_ret =
a9c0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
a9d0: 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09  sult(interp);...
a9e0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
a9f0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
aa00: 5f 45 52 52 4f 52 28 22 5b 65 72 72 6f 72 5d 20  _ERROR("[error] 
aa10: 25 73 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a 0a  %s", sql_ret);..
aa20: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
aa30: 0a 09 69 66 20 28 73 71 6c 5f 72 65 74 20 26 26  ..if (sql_ret &&
aa40: 20 73 71 6c 5f 72 65 74 5b 30 5d 20 21 3d 20 27   sql_ret[0] != '
aa50: 5c 30 27 29 20 7b 0a 09 09 70 72 69 6e 74 66 28  \0') {...printf(
aa60: 22 25 73 5c 6e 22 2c 20 73 71 6c 5f 72 65 74 29  "%s\n", sql_ret)
aa70: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29  ;..}...return(0)
aa80: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 63 6c 20 6d  ;.}../*. * Tcl m
aa90: 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72 61 77  ode: Execute raw
aaa0: 20 54 63 6c 20 61 6e 64 20 72 65 74 75 72 6e 20   Tcl and return 
aab0: 73 75 63 63 65 73 73 20 6f 72 20 66 61 69 6c 75  success or failu
aac0: 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  re. */.static in
aad0: 74 20 61 70 70 66 73 5f 74 63 6c 28 63 6f 6e 73  t appfs_tcl(cons
aae0: 74 20 63 68 61 72 20 2a 74 63 6c 29 20 7b 0a 09  t char *tcl) {..
aaf0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
ab00: 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20  rp;..const char 
ab10: 2a 74 63 6c 5f 72 65 73 75 6c 74 3b 0a 09 69 6e  *tcl_result;..in
ab20: 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74  t tcl_ret;...int
ab30: 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61  erp = appfs_crea
ab40: 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c  te_TclInterp(NUL
ab50: 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  L);..if (interp 
ab60: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50  == NULL) {...APP
ab70: 46 53 5f 45 52 52 4f 52 28 22 55 6e 61 62 6c 65  FS_ERROR("Unable
ab80: 20 74 6f 20 63 72 65 61 74 65 20 61 20 54 63 6c   to create a Tcl
ab90: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41   interpreter.  A
aba0: 62 6f 72 74 69 6e 67 2e 22 29 3b 0a 0a 09 09 72  borting.");....r
abb0: 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 74  eturn(1);..}...t
abc0: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61  cl_ret = Tcl_Eva
abd0: 6c 28 69 6e 74 65 72 70 2c 20 74 63 6c 29 3b 0a  l(interp, tcl);.
abe0: 09 74 63 6c 5f 72 65 73 75 6c 74 20 3d 20 54 63  .tcl_result = Tc
abf0: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
ac00: 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20  t(interp);...if 
ac10: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
ac20: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 45 52  OK) {...APPFS_ER
ac30: 52 4f 52 28 22 5b 65 72 72 6f 72 5d 20 25 73 22  ROR("[error] %s"
ac40: 2c 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74  , Tcl_GetVar(int
ac50: 65 72 70 2c 20 22 65 72 72 6f 72 49 6e 66 6f 22  erp, "errorInfo"
ac60: 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c  , TCL_GLOBAL_ONL
ac70: 59 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31  Y));....return(1
ac80: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 74 63 6c 5f  );..}...if (tcl_
ac90: 72 65 73 75 6c 74 20 26 26 20 74 63 6c 5f 72 65  result && tcl_re
aca0: 73 75 6c 74 5b 30 5d 20 21 3d 20 27 5c 30 27 29  sult[0] != '\0')
acb0: 20 7b 0a 09 09 70 72 69 6e 74 66 28 22 25 73 5c   {...printf("%s\
acc0: 6e 22 2c 20 74 63 6c 5f 72 65 73 75 6c 74 29 3b  n", tcl_result);
acd0: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  ..}...return(0);
ace0: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 64  .}../*. * AppFSd
acf0: 20 50 61 63 6b 61 67 65 20 66 6f 72 20 54 63 6c   Package for Tcl
ad00: 3a 0a 20 2a 20 20 20 20 20 20 20 20 20 42 72 69  :. *         Bri
ad10: 64 67 65 20 66 6f 72 20 49 2f 4f 20 6f 70 65 72  dge for I/O oper
ad20: 61 74 69 6f 6e 73 20 74 6f 20 72 65 71 75 65 73  ations to reques
ad30: 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62  t information ab
ad40: 6f 75 74 20 74 68 65 20 63 75 72 72 65 6e 74 0a  out the current.
ad50: 20 2a 20 20 20 20 20 20 20 20 20 74 72 61 6e 73   *         trans
ad60: 61 63 74 69 6f 6e 0a 20 2a 2f 0a 2f 2a 0a 20 2a  action. */./*. *
ad70: 20 54 63 6c 20 69 6e 74 65 72 66 61 63 65 20 74   Tcl interface t
ad80: 6f 20 67 65 74 20 74 68 65 20 68 6f 6d 65 20 64  o get the home d
ad90: 69 72 65 63 74 6f 72 79 20 66 6f 72 20 74 68 65  irectory for the
ada0: 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65   user making the
adb0: 20 22 63 75 72 72 65 6e 74 22 0a 20 2a 20 46 55   "current". * FU
adc0: 53 45 20 49 2f 4f 20 72 65 71 75 65 73 74 0a 20  SE I/O request. 
add0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  */.static int tc
ade0: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65  l_appfs_get_home
adf0: 64 69 72 28 43 6c 69 65 6e 74 44 61 74 61 20 63  dir(ClientData c
ae00: 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  d, Tcl_Interp *i
ae10: 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c  nterp, int objc,
ae20: 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20   Tcl_Obj *CONST 
ae30: 6f 62 6a 76 5b 5d 29 20 7b 0a 09 63 68 61 72 20  objv[]) {..char 
ae40: 2a 68 6f 6d 65 64 69 72 3b 0a 09 54 63 6c 5f 4f  *homedir;..Tcl_O
ae50: 62 6a 20 2a 68 6f 6d 65 64 69 72 5f 6f 62 6a 3b  bj *homedir_obj;
ae60: 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a 09  ..uid_t fsuid;..
ae70: 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64 20  static __thread 
ae80: 54 63 6c 5f 4f 62 6a 20 2a 6c 61 73 74 5f 68 6f  Tcl_Obj *last_ho
ae90: 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 4e 55 4c 4c  medir_obj = NULL
aea0: 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65  ;..static __thre
aeb0: 61 64 20 75 69 64 5f 74 20 6c 61 73 74 5f 66 73  ad uid_t last_fs
aec0: 75 69 64 20 3d 20 2d 31 3b 0a 0a 20 20 20 20 20  uid = -1;..     
aed0: 20 20 20 69 66 20 28 6f 62 6a 63 20 21 3d 20 31     if (objc != 1
aee0: 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20  ) {.            
aef0: 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d      Tcl_WrongNum
af00: 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20  Args(interp, 1, 
af10: 6f 62 6a 76 2c 20 4e 55 4c 4c 29 3b 0a 20 20 20  objv, NULL);.   
af20: 20 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74               ret
af30: 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a  urn(TCL_ERROR);.
af40: 20 20 20 20 20 20 20 20 7d 0a 0a 09 66 73 75 69          }...fsui
af50: 64 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73  d = appfs_get_fs
af60: 75 69 64 28 29 3b 0a 0a 09 69 66 20 28 66 73 75  uid();...if (fsu
af70: 69 64 20 3d 3d 20 6c 61 73 74 5f 66 73 75 69 64  id == last_fsuid
af80: 20 26 26 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72   && last_homedir
af90: 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  _obj != NULL) {.
afa0: 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20  ..homedir_obj = 
afb0: 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a  last_homedir_obj
afc0: 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66  ;....Tcl_IncrRef
afd0: 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62  Count(homedir_ob
afe0: 6a 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09  j);..} else {...
aff0: 68 6f 6d 65 64 69 72 20 3d 20 61 70 70 66 73 5f  homedir = appfs_
b000: 67 65 74 5f 68 6f 6d 65 64 69 72 28 61 70 70 66  get_homedir(appf
b010: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a  s_get_fsuid());.
b020: 0a 09 09 69 66 20 28 68 6f 6d 65 64 69 72 20 3d  ...if (homedir =
b030: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74  = NULL) {....ret
b040: 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a  urn(TCL_ERROR);.
b050: 09 09 7d 0a 0a 09 09 68 6f 6d 65 64 69 72 5f 6f  ..}....homedir_o
b060: 62 6a 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69  bj = Tcl_NewStri
b070: 6e 67 4f 62 6a 28 68 6f 6d 65 64 69 72 2c 20 2d  ngObj(homedir, -
b080: 31 29 3b 0a 0a 09 09 66 72 65 65 28 68 6f 6d 65  1);....free(home
b090: 64 69 72 29 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63  dir);....Tcl_Inc
b0a0: 72 52 65 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69  rRefCount(homedi
b0b0: 72 5f 6f 62 6a 29 3b 0a 0a 09 09 69 66 20 28 6c  r_obj);....if (l
b0c0: 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20  ast_homedir_obj 
b0d0: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 54 63  != NULL) {....Tc
b0e0: 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 6c  l_DecrRefCount(l
b0f0: 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 29  ast_homedir_obj)
b100: 3b 0a 09 09 7d 0a 0a 09 09 6c 61 73 74 5f 68 6f  ;...}....last_ho
b110: 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 68 6f 6d 65  medir_obj = home
b120: 64 69 72 5f 6f 62 6a 3b 0a 09 09 6c 61 73 74 5f  dir_obj;...last_
b130: 66 73 75 69 64 20 3d 20 66 73 75 69 64 3b 0a 0a  fsuid = fsuid;..
b140: 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75  ..Tcl_IncrRefCou
b150: 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b  nt(homedir_obj);
b160: 0a 09 7d 0a 0a 20 20 20 20 20 20 20 09 54 63 6c  ..}..       .Tcl
b170: 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e  _SetObjResult(in
b180: 74 65 72 70 2c 20 68 6f 6d 65 64 69 72 5f 6f 62  terp, homedir_ob
b190: 6a 29 3b 0a 0a 09 54 63 6c 5f 44 65 63 72 52 65  j);...Tcl_DecrRe
b1a0: 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f  fCount(homedir_o
b1b0: 62 6a 29 3b 0a 0a 20 20 20 20 20 20 20 20 72 65  bj);..        re
b1c0: 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a  turn(TCL_OK);.}.
b1d0: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f  .static int tcl_
b1e0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
b1f0: 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 43 6c 69  ser_fs_enter(Cli
b200: 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c 5f  entData cd, Tcl_
b210: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20  Interp *interp, 
b220: 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62  int objc, Tcl_Ob
b230: 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29  j *CONST objv[])
b240: 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61   {..appfs_simula
b250: 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72  te_user_fs_enter
b260: 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c  ();...return(TCL
b270: 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  _OK);.}..static 
b280: 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f 73 69  int tcl_appfs_si
b290: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c  mulate_user_fs_l
b2a0: 65 61 76 65 28 43 6c 69 65 6e 74 44 61 74 61 20  eave(ClientData 
b2b0: 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  cd, Tcl_Interp *
b2c0: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63  interp, int objc
b2d0: 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54  , Tcl_Obj *CONST
b2e0: 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70 70 66   objv[]) {..appf
b2f0: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
b300: 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 72 65  fs_leave();...re
b310: 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a  turn(TCL_OK);.}.
b320: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f  .static int tcl_
b330: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28  appfs_get_fsuid(
b340: 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54  ClientData cd, T
b350: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
b360: 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c  p, int objc, Tcl
b370: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
b380: 5b 5d 29 20 7b 0a 09 75 69 64 5f 74 20 66 73 75  []) {..uid_t fsu
b390: 69 64 3b 0a 0a 09 66 73 75 69 64 20 3d 20 61 70  id;...fsuid = ap
b3a0: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b  pfs_get_fsuid();
b3b0: 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53 65  ..       .Tcl_Se
b3c0: 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72  tObjResult(inter
b3d0: 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e  p, Tcl_NewWideIn
b3e0: 74 4f 62 6a 28 66 73 75 69 64 29 29 3b 0a 0a 09  tObj(fsuid));...
b3f0: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a  return(TCL_OK);.
b400: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63  }..static int tc
b410: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69  l_appfs_get_fsgi
b420: 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c  d(ClientData cd,
b430: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
b440: 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54  erp, int objc, T
b450: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
b460: 6a 76 5b 5d 29 20 7b 0a 09 67 69 64 5f 74 20 66  jv[]) {..gid_t f
b470: 73 67 69 64 3b 0a 0a 09 66 73 67 69 64 20 3d 20  sgid;...fsgid = 
b480: 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28  appfs_get_fsgid(
b490: 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f  );..       .Tcl_
b4a0: 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  SetObjResult(int
b4b0: 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65  erp, Tcl_NewWide
b4c0: 49 6e 74 4f 62 6a 28 66 73 67 69 64 29 29 3b 0a  IntObj(fsgid));.
b4d0: 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29  ..return(TCL_OK)
b4e0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
b4f0: 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 70 61  tcl_appfs_get_pa
b500: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c  th_info_cache_fl
b510: 75 73 68 28 43 6c 69 65 6e 74 44 61 74 61 20 63  ush(ClientData c
b520: 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  d, Tcl_Interp *i
b530: 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c  nterp, int objc,
b540: 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20   Tcl_Obj *CONST 
b550: 6f 62 6a 76 5b 5d 29 20 7b 0a 09 69 6e 74 20 74  objv[]) {..int t
b560: 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 6e 65 77  cl_ret;..int new
b570: 5f 73 69 7a 65 3b 0a 0a 09 6e 65 77 5f 73 69 7a  _size;...new_siz
b580: 65 20 3d 20 2d 31 3b 0a 0a 09 69 66 20 28 6f 62  e = -1;...if (ob
b590: 6a 63 20 3d 3d 20 32 29 20 7b 0a 09 09 74 63 6c  jc == 2) {...tcl
b5a0: 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 49 6e  _ret = Tcl_GetIn
b5b0: 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c  tFromObj(interp,
b5c0: 20 6f 62 6a 76 5b 31 5d 2c 20 26 6e 65 77 5f 73   objv[1], &new_s
b5d0: 69 7a 65 29 3b 0a 09 09 69 66 20 28 74 63 6c 5f  ize);...if (tcl_
b5e0: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
b5f0: 0a 09 09 09 72 65 74 75 72 6e 28 74 63 6c 5f 72  ....return(tcl_r
b600: 65 74 29 3b 0a 09 09 7d 0a 09 7d 20 65 6c 73 65  et);...}..} else
b610: 20 69 66 20 28 6f 62 6a 63 20 3e 20 32 20 7c 7c   if (objc > 2 ||
b620: 20 6f 62 6a 63 20 3c 20 31 29 20 7b 0a 20 20 20   objc < 1) {.   
b630: 20 20 20 20 20 20 20 20 20 20 20 20 20 54 63 6c               Tcl
b640: 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e  _WrongNumArgs(in
b650: 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22  terp, 1, objv, "
b660: 3f 6e 65 77 5f 63 61 63 68 65 5f 73 69 7a 65 3f  ?new_cache_size?
b670: 22 29 3b 0a 09 09 72 65 74 75 72 6e 28 54 43 4c  ");...return(TCL
b680: 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09 61 70  _ERROR);..}...ap
b690: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
b6a0: 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31  o_cache_flush(-1
b6b0: 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a 09 72  , new_size);...r
b6c0: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d  eturn(TCL_OK);.}
b6d0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 41 70 70  ..static int App
b6e0: 66 73 64 5f 49 6e 69 74 28 54 63 6c 5f 49 6e 74  fsd_Init(Tcl_Int
b6f0: 65 72 70 20 2a 69 6e 74 65 72 70 29 20 7b 0a 23  erp *interp) {.#
b700: 69 66 64 65 66 20 55 53 45 5f 54 43 4c 5f 53 54  ifdef USE_TCL_ST
b710: 55 42 53 0a 09 69 66 20 28 54 63 6c 5f 49 6e 69  UBS..if (Tcl_Ini
b720: 74 53 74 75 62 73 28 69 6e 74 65 72 70 2c 20 54  tStubs(interp, T
b730: 43 4c 5f 56 45 52 53 49 4f 4e 2c 20 30 29 20 3d  CL_VERSION, 0) =
b740: 3d 20 30 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  = 0L) {...return
b750: 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a  (TCL_ERROR);..}.
b760: 23 65 6e 64 69 66 0a 0a 09 54 63 6c 5f 43 72 65  #endif...Tcl_Cre
b770: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
b780: 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67  terp, "appfsd::g
b790: 65 74 5f 68 6f 6d 65 64 69 72 22 2c 20 74 63 6c  et_homedir", tcl
b7a0: 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64  _appfs_get_homed
b7b0: 69 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b  ir, NULL, NULL);
b7c0: 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43  ..Tcl_CreateObjC
b7d0: 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 22  ommand(interp, "
b7e0: 61 70 70 66 73 64 3a 3a 67 65 74 5f 66 73 75 69  appfsd::get_fsui
b7f0: 64 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67 65  d", tcl_appfs_ge
b800: 74 5f 66 73 75 69 64 2c 20 4e 55 4c 4c 2c 20 4e  t_fsuid, NULL, N
b810: 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74  ULL);..Tcl_Creat
b820: 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  eObjCommand(inte
b830: 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74  rp, "appfsd::get
b840: 5f 66 73 67 69 64 22 2c 20 74 63 6c 5f 61 70 70  _fsgid", tcl_app
b850: 66 73 5f 67 65 74 5f 66 73 67 69 64 2c 20 4e 55  fs_get_fsgid, NU
b860: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f  LL, NULL);..Tcl_
b870: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64  CreateObjCommand
b880: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
b890: 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  ::simulate_user_
b8a0: 66 73 5f 65 6e 74 65 72 22 2c 20 74 63 6c 5f 61  fs_enter", tcl_a
b8b0: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
b8c0: 65 72 5f 66 73 5f 65 6e 74 65 72 2c 20 4e 55 4c  er_fs_enter, NUL
b8d0: 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43  L, NULL);..Tcl_C
b8e0: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
b8f0: 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a  interp, "appfsd:
b900: 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66  :simulate_user_f
b910: 73 5f 6c 65 61 76 65 22 2c 20 74 63 6c 5f 61 70  s_leave", tcl_ap
b920: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
b930: 72 5f 66 73 5f 6c 65 61 76 65 2c 20 4e 55 4c 4c  r_fs_leave, NULL
b940: 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72  , NULL);..Tcl_Cr
b950: 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69  eateObjCommand(i
b960: 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a  nterp, "appfsd::
b970: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
b980: 63 68 65 5f 66 6c 75 73 68 22 2c 20 74 63 6c 5f  che_flush", tcl_
b990: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
b9a0: 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 2c  nfo_cache_flush,
b9b0: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 0a 09   NULL, NULL);...
b9c0: 54 63 6c 5f 50 6b 67 50 72 6f 76 69 64 65 28 69  Tcl_PkgProvide(i
b9d0: 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 22 2c  nterp, "appfsd",
b9e0: 20 22 31 2e 30 22 29 3b 0a 0a 09 72 65 74 75 72   "1.0");...retur
b9f0: 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 23 69  n(TCL_OK);.}..#i
ba00: 66 64 65 66 20 41 50 50 46 53 5f 4e 4f 5f 53 49  fdef APPFS_NO_SI
ba10: 47 4e 41 4c 53 0a 73 74 61 74 69 63 20 76 6f 69  GNALS.static voi
ba20: 64 20 61 70 70 66 73 5f 73 65 74 5f 73 69 67 68  d appfs_set_sigh
ba30: 61 6e 64 6c 65 72 28 76 6f 69 64 29 20 7b 0a 09  andler(void) {..
ba40: 72 65 74 75 72 6e 3b 0a 7d 0a 23 65 6c 73 65 0a  return;.}.#else.
ba50: 23 69 6e 63 6c 75 64 65 20 3c 73 69 67 6e 61 6c  #include <signal
ba60: 2e 68 3e 0a 0a 2f 2a 0a 20 2a 20 48 6f 74 2d 72  .h>../*. * Hot-r
ba70: 65 73 74 61 72 74 20 73 75 70 70 6f 72 74 0a 20  estart support. 
ba80: 2a 2f 0a 2f 2a 20 49 6e 69 74 69 61 74 65 20 61  */./* Initiate a
ba90: 20 68 6f 74 2d 72 65 73 74 61 72 74 20 2a 2f 0a   hot-restart */.
baa0: 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66  static void appf
bab0: 73 5f 68 6f 74 5f 72 65 73 74 61 72 74 28 76 6f  s_hot_restart(vo
bac0: 69 64 29 20 7b 0a 09 41 50 50 46 53 5f 44 45 42  id) {..APPFS_DEB
bad0: 55 47 28 22 41 73 6b 65 64 20 74 6f 20 69 6e 69  UG("Asked to ini
bae0: 74 69 61 74 65 20 68 6f 74 20 72 65 73 74 61 72  tiate hot restar
baf0: 74 22 29 3b 0a 0a 09 61 70 70 66 73 5f 74 63 6c  t");...appfs_tcl
bb00: 5f 52 65 73 65 74 49 6e 74 65 72 70 73 28 29 3b  _ResetInterps();
bb10: 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74  ...appfs_get_pat
bb20: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75  h_info_cache_flu
bb30: 73 68 28 2d 31 2c 20 2d 31 29 3b 0a 0a 09 72 65  sh(-1, -1);...re
bb40: 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 53  turn;.}../*. * S
bb50: 69 67 6e 61 6c 20 68 61 6e 64 6c 65 72 0a 20 2a  ignal handler. *
bb60: 20 20 20 20 20 20 20 20 20 53 49 47 48 55 50 20           SIGHUP 
bb70: 69 6e 69 74 69 61 74 65 73 20 61 20 68 6f 74 20  initiates a hot 
bb80: 72 65 73 74 61 72 74 0a 20 2a 2f 0a 73 74 61 74  restart. */.stat
bb90: 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 73 69  ic void appfs_si
bba0: 67 6e 61 6c 5f 68 61 6e 64 6c 65 72 28 69 6e 74  gnal_handler(int
bbb0: 20 73 69 67 29 20 7b 0a 09 2f 2a 20 44 6f 20 6e   sig) {../* Do n
bbc0: 6f 74 20 68 61 6e 64 6c 65 20 73 69 67 6e 61 6c  ot handle signal
bbd0: 73 20 75 6e 74 69 6c 20 46 55 53 45 20 68 61 73  s until FUSE has
bbe0: 20 62 65 65 6e 20 73 74 61 72 74 65 64 20 2a 2f   been started */
bbf0: 0a 09 69 66 20 28 21 61 70 70 66 73 5f 66 75 73  ..if (!appfs_fus
bc00: 65 5f 73 74 61 72 74 65 64 29 20 7b 0a 09 09 72  e_started) {...r
bc10: 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 2f 2a 20 52  eturn;..}.../* R
bc20: 65 71 75 65 73 74 20 74 6f 20 70 65 72 66 6f 72  equest to perfor
bc30: 6d 20 61 20 22 68 6f 74 22 20 72 65 73 74 61 72  m a "hot" restar
bc40: 74 20 2a 2f 0a 09 69 66 20 28 73 69 67 20 3d 3d  t */..if (sig ==
bc50: 20 53 49 47 48 55 50 29 20 7b 0a 09 09 61 70 70   SIGHUP) {...app
bc60: 66 73 5f 68 6f 74 5f 72 65 73 74 61 72 74 28 29  fs_hot_restart()
bc70: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d  ;..}...return;.}
bc80: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  ..static void ap
bc90: 70 66 73 5f 73 65 74 5f 73 69 67 68 61 6e 64 6c  pfs_set_sighandl
bca0: 65 72 28 76 6f 69 64 29 20 7b 0a 09 76 6f 69 64  er(void) {..void
bcb0: 20 2a 73 69 67 6e 61 6c 5f 72 65 74 3b 0a 0a 09   *signal_ret;...
bcc0: 2f 2a 0a 09 20 2a 20 52 65 67 69 73 74 65 72 20  /*.. * Register 
bcd0: 61 20 73 69 67 6e 61 6c 20 68 61 6e 64 6c 65 72  a signal handler
bce0: 20 66 6f 72 20 68 6f 74 2d 72 65 73 74 61 72 74   for hot-restart
bcf0: 20 72 65 71 75 65 73 74 73 0a 09 20 2a 2f 0a 09   requests.. */..
bd00: 73 69 67 6e 61 6c 5f 72 65 74 20 3d 20 73 69 67  signal_ret = sig
bd10: 6e 61 6c 28 53 49 47 48 55 50 2c 20 61 70 70 66  nal(SIGHUP, appf
bd20: 73 5f 73 69 67 6e 61 6c 5f 68 61 6e 64 6c 65 72  s_signal_handler
bd30: 29 3b 0a 09 69 66 20 28 73 69 67 6e 61 6c 5f 72  );..if (signal_r
bd40: 65 74 20 3d 3d 20 53 49 47 5f 45 52 52 29 20 7b  et == SIG_ERR) {
bd50: 0a 09 09 41 50 50 46 53 5f 45 52 52 4f 52 28 22  ...APPFS_ERROR("
bd60: 55 6e 61 62 6c 65 20 74 6f 20 69 6e 73 74 61 6c  Unable to instal
bd70: 6c 20 73 69 67 6e 61 6c 20 68 61 6e 64 6c 65 72  l signal handler
bd80: 20 66 6f 72 20 68 6f 74 2d 72 65 73 74 61 72 74   for hot-restart
bd90: 22 29 3b 0a 09 09 41 50 50 46 53 5f 45 52 52 4f  ");...APPFS_ERRO
bda0: 52 28 22 48 6f 74 2d 72 65 73 74 61 72 74 20 77  R("Hot-restart w
bdb0: 69 6c 6c 20 6e 6f 74 20 62 65 20 61 76 61 69 6c  ill not be avail
bdc0: 61 62 6c 65 2e 22 29 3b 0a 09 7d 0a 7d 0a 23 65  able.");..}.}.#e
bdd0: 6e 64 69 66 0a 2f 2a 0a 20 2a 20 54 65 72 6d 69  ndif./*. * Termi
bde0: 6e 61 74 65 20 61 20 74 68 72 65 61 64 0a 20 2a  nate a thread. *
bdf0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  /.static void ap
be00: 70 66 73 5f 74 65 72 6d 69 6e 61 74 65 5f 69 6e  pfs_terminate_in
be10: 74 65 72 70 5f 61 6e 64 5f 74 68 72 65 61 64 28  terp_and_thread(
be20: 76 6f 69 64 20 2a 5f 69 6e 74 65 72 70 29 20 7b  void *_interp) {
be30: 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  ..Tcl_Interp *in
be40: 74 65 72 70 3b 0a 0a 09 41 50 50 46 53 5f 44 45  terp;...APPFS_DE
be50: 42 55 47 28 22 43 61 6c 6c 65 64 3a 20 5f 69 6e  BUG("Called: _in
be60: 74 65 72 70 20 3d 20 25 70 22 2c 20 5f 69 6e 74  terp = %p", _int
be70: 65 72 70 29 3b 0a 0a 09 69 66 20 28 5f 69 6e 74  erp);...if (_int
be80: 65 72 70 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  erp != NULL) {..
be90: 09 69 6e 74 65 72 70 20 3d 20 5f 69 6e 74 65 72  .interp = _inter
bea0: 70 3b 0a 0a 09 09 41 50 50 46 53 5f 44 45 42 55  p;....APPFS_DEBU
beb0: 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 69  G("Terminating i
bec0: 6e 74 65 72 70 72 65 74 65 72 20 64 75 65 20 74  nterpreter due t
bed0: 6f 20 74 68 72 65 61 64 20 74 65 72 6d 69 6e 61  o thread termina
bee0: 74 69 6f 6e 22 29 3b 0a 0a 09 09 61 70 70 66 73  tion");....appfs
bef0: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09  _call_libtcl(...
bf00: 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72  .Tcl_DeleteInter
bf10: 70 28 69 6e 74 65 72 70 29 3b 0a 09 09 29 0a 09  p(interp);...)..
bf20: 7d 20 65 6c 73 65 20 7b 0a 09 09 41 50 50 46 53  } else {...APPFS
bf30: 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74  _DEBUG("Terminat
bf40: 69 6e 67 20 74 68 72 65 61 64 20 77 69 74 68 20  ing thread with 
bf50: 6e 6f 20 69 6e 74 65 72 70 72 65 74 65 72 22 29  no interpreter")
bf60: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c  ;..}...appfs_cal
bf70: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 54 63 6c 5f  l_libtcl(...Tcl_
bf80: 46 69 6e 61 6c 69 7a 65 54 68 72 65 61 64 28 29  FinalizeThread()
bf90: 3b 0a 09 29 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d  ;..)...return;.}
bfa0: 0a 0a 2f 2a 0a 20 2a 20 43 6f 6d 6d 61 6e 64 2d  ../*. * Command-
bfb0: 6c 69 6e 65 20 70 61 72 73 69 6e 67 20 74 6f 6f  line parsing too
bfc0: 6c 73 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ls. */.static vo
bfd0: 69 64 20 61 70 70 66 73 5f 70 72 69 6e 74 5f 68  id appfs_print_h
bfe0: 65 6c 70 28 46 49 4c 45 20 2a 63 68 61 6e 6e 65  elp(FILE *channe
bff0: 6c 29 20 7b 0a 09 66 70 72 69 6e 74 66 28 63 68  l) {..fprintf(ch
c000: 61 6e 6e 65 6c 2c 20 22 55 73 61 67 65 3a 20 7b  annel, "Usage: {
c010: 61 70 70 66 73 64 7c 6d 6f 75 6e 74 2e 61 70 70  appfsd|mount.app
c020: 66 73 7d 20 5b 2d 6f 20 3c 6f 70 74 69 6f 6e 3e  fs} [-o <option>
c030: 5d 20 5b 2d 64 66 73 68 5d 20 3c 63 61 63 68 65  ] [-dfsh] <cache
c040: 64 69 72 3e 20 3c 6d 6f 75 6e 74 70 6f 69 6e 74  dir> <mountpoint
c050: 3e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28  >\n");..fprintf(
c060: 63 68 61 6e 6e 65 6c 2c 20 22 5c 6e 22 29 3b 0a  channel, "\n");.
c070: 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c  .fprintf(channel
c080: 2c 20 22 4f 70 74 69 6f 6e 73 3a 5c 6e 22 29 3b  , "Options:\n");
c090: 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65  ..fprintf(channe
c0a0: 6c 2c 20 22 20 20 2d 64 20 20 20 20 20 20 20 20  l, "  -d        
c0b0: 20 20 20 20 20 20 45 6e 61 62 6c 65 20 46 55 53        Enable FUS
c0c0: 45 20 64 65 62 75 67 20 6d 6f 64 65 2e 5c 6e 22  E debug mode.\n"
c0d0: 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e  );..fprintf(chan
c0e0: 6e 65 6c 2c 20 22 20 20 2d 66 20 20 20 20 20 20  nel, "  -f      
c0f0: 20 20 20 20 20 20 20 20 52 75 6e 20 69 6e 20 66          Run in f
c100: 6f 72 65 67 72 6f 75 6e 64 2e 5c 6e 22 29 3b 0a  oreground.\n");.
c110: 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c  .fprintf(channel
c120: 2c 20 22 20 20 2d 73 20 20 20 20 20 20 20 20 20  , "  -s         
c130: 20 20 20 20 20 45 6e 61 62 6c 65 20 73 69 6e 67       Enable sing
c140: 6c 65 20 74 68 72 65 61 64 65 64 20 6d 6f 64 65  le threaded mode
c150: 2e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28  .\n");..fprintf(
c160: 63 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 68 20 20  channel, "  -h  
c170: 20 20 20 20 20 20 20 20 20 20 20 20 47 69 76 65              Give
c180: 20 74 68 69 73 20 68 65 6c 70 2e 5c 6e 22 29 3b   this help.\n");
c190: 0a 09 66 70 72 69 6e 74 66 28 63 68 61 6e 6e 65  ..fprintf(channe
c1a0: 6c 2c 20 22 20 20 2d 6f 20 6e 6f 74 68 72 65 61  l, "  -o nothrea
c1b0: 64 73 20 20 20 20 45 6e 61 62 6c 65 20 73 69 6e  ds    Enable sin
c1c0: 67 6c 65 20 74 68 72 65 61 64 65 64 20 6d 6f 64  gle threaded mod
c1d0: 65 2e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66  e.\n");..fprintf
c1e0: 28 63 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 6f 20  (channel, "  -o 
c1f0: 61 6c 6c 6f 77 5f 6f 74 68 65 72 20 20 41 6c 6c  allow_other  All
c200: 6f 77 20 6f 74 68 65 72 20 75 73 65 72 73 20 74  ow other users t
c210: 6f 20 61 63 63 65 73 73 20 74 68 69 73 20 6d 6f  o access this mo
c220: 75 6e 74 70 6f 69 6e 74 20 28 64 65 66 61 75 6c  untpoint (defaul
c230: 74 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28  t\n");..fprintf(
c240: 63 68 61 6e 6e 65 6c 2c 20 22 20 20 20 20 20 20  channel, "      
c250: 20 20 20 20 20 20 20 20 20 20 20 20 69 66 20 72              if r
c260: 6f 6f 74 29 2e 5c 6e 22 29 3b 0a 0a 09 72 65 74  oot).\n");...ret
c270: 75 72 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  urn;.}..static i
c280: 6e 74 20 61 70 70 66 73 5f 6f 70 74 5f 70 61 72  nt appfs_opt_par
c290: 73 65 28 69 6e 74 20 61 72 67 63 2c 20 63 68 61  se(int argc, cha
c2a0: 72 20 2a 2a 61 72 67 76 2c 20 20 73 74 72 75 63  r **argv,  struc
c2b0: 74 20 66 75 73 65 5f 61 72 67 73 20 2a 61 72 67  t fuse_args *arg
c2c0: 73 29 20 7b 0a 09 69 6e 74 20 63 68 3b 0a 09 63  s) {..int ch;..c
c2d0: 68 61 72 20 2a 6f 70 74 73 74 72 2c 20 2a 6f 70  har *optstr, *op
c2e0: 74 73 74 72 5f 6e 65 78 74 2c 20 2a 6f 70 74 73  tstr_next, *opts
c2f0: 74 72 5f 73 3b 0a 09 63 68 61 72 20 66 61 6b 65  tr_s;..char fake
c300: 5f 61 72 67 5b 33 5d 20 3d 20 7b 27 2d 27 2c 20  _arg[3] = {'-', 
c310: 30 2c 20 30 7d 3b 0a 0a 09 2f 2a 0a 09 20 2a 20  0, 0};.../*.. * 
c320: 44 65 66 61 75 6c 74 20 76 61 6c 75 65 73 0a 09  Default values..
c330: 20 2a 2f 0a 23 69 66 20 64 65 66 69 6e 65 64 28   */.#if defined(
c340: 54 43 4c 5f 54 48 52 45 41 44 53 29 20 26 26 20  TCL_THREADS) && 
c350: 54 43 4c 5f 54 48 52 45 41 44 53 20 3d 3d 20 31  TCL_THREADS == 1
c360: 0a 09 61 70 70 66 73 5f 74 68 72 65 61 64 65 64  ..appfs_threaded
c370: 5f 74 63 6c 20 3d 20 31 3b 0a 23 65 6c 73 65 0a  _tcl = 1;.#else.
c380: 09 61 70 70 66 73 5f 74 68 72 65 61 64 65 64 5f  .appfs_threaded_
c390: 74 63 6c 20 3d 20 30 3b 0a 23 65 6e 64 69 66 0a  tcl = 0;.#endif.
c3a0: 0a 09 2f 2a 2a 0a 09 20 2a 2a 20 41 64 64 20 46  ../**.. ** Add F
c3b0: 55 53 45 20 61 72 67 75 6d 65 6e 74 73 20 77 68  USE arguments wh
c3c0: 69 63 68 20 77 65 20 61 6c 77 61 79 73 20 73 75  ich we always su
c3d0: 70 70 6c 79 0a 09 20 2a 2a 2f 0a 09 66 75 73 65  pply.. **/..fuse
c3e0: 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72 67  _opt_add_arg(arg
c3f0: 73 2c 20 22 2d 6f 64 65 66 61 75 6c 74 5f 70 65  s, "-odefault_pe
c400: 72 6d 69 73 73 69 6f 6e 73 2c 66 73 6e 61 6d 65  rmissions,fsname
c410: 3d 61 70 70 66 73 2c 73 75 62 74 79 70 65 3d 61  =appfs,subtype=a
c420: 70 70 66 73 64 2c 75 73 65 5f 69 6e 6f 2c 65 6e  ppfsd,use_ino,en
c430: 74 72 79 5f 74 69 6d 65 6f 75 74 3d 30 2c 61 74  try_timeout=0,at
c440: 74 72 5f 74 69 6d 65 6f 75 74 3d 30 2c 62 69 67  tr_timeout=0,big
c450: 5f 77 72 69 74 65 73 2c 69 6e 74 72 2c 68 61 72  _writes,intr,har
c460: 64 5f 72 65 6d 6f 76 65 22 29 3b 0a 0a 09 69 66  d_remove");...if
c470: 20 28 67 65 74 75 69 64 28 29 20 3d 3d 20 30 29   (getuid() == 0)
c480: 20 7b 0a 09 09 66 75 73 65 5f 6f 70 74 5f 70 61   {...fuse_opt_pa
c490: 72 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20  rse(args, NULL, 
c4a0: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09 66  NULL, NULL);...f
c4b0: 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28  use_opt_add_arg(
c4c0: 61 72 67 73 2c 20 22 2d 6f 61 6c 6c 6f 77 5f 6f  args, "-oallow_o
c4d0: 74 68 65 72 22 29 3b 0a 0a 09 09 2f 2a 0a 09 09  ther");..../*...
c4e0: 20 2a 20 54 68 69 73 20 73 68 6f 75 6c 64 20 67   * This should g
c4f0: 65 6e 65 72 61 6c 6c 79 20 62 65 20 61 76 6f 69  enerally be avoi
c500: 64 65 64 2c 20 62 75 74 20 69 66 20 74 68 65 72  ded, but if ther
c510: 65 20 61 72 65 20 73 65 63 75 72 69 74 79 0a 09  e are security..
c520: 09 20 2a 20 63 6f 6e 63 65 72 6e 73 20 73 75 69  . * concerns sui
c530: 64 20 63 61 6e 20 62 65 20 64 69 73 61 62 6c 65  d can be disable
c540: 64 20 63 6f 6d 70 6c 65 74 65 6c 79 20 6f 6e 20  d completely on 
c550: 74 68 65 20 63 6f 6d 6d 61 6e 64 6c 69 6e 65 0a  the commandline.
c560: 09 09 20 2a 2f 0a 09 09 66 75 73 65 5f 6f 70 74  .. */...fuse_opt
c570: 5f 70 61 72 73 65 28 61 72 67 73 2c 20 4e 55 4c  _parse(args, NUL
c580: 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a  L, NULL, NULL);.
c590: 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61  ..fuse_opt_add_a
c5a0: 72 67 28 61 72 67 73 2c 20 22 2d 6f 73 75 69 64  rg(args, "-osuid
c5b0: 22 29 3b 0a 09 7d 0a 0a 09 77 68 69 6c 65 20 28  ");..}...while (
c5c0: 28 63 68 20 3d 20 67 65 74 6f 70 74 28 61 72 67  (ch = getopt(arg
c5d0: 63 2c 20 61 72 67 76 2c 20 22 64 66 73 68 76 6f  c, argv, "dfshvo
c5e0: 3a 22 29 29 20 21 3d 20 2d 31 29 20 7b 0a 09 09  :")) != -1) {...
c5f0: 73 77 69 74 63 68 20 28 63 68 29 20 7b 0a 09 09  switch (ch) {...
c600: 09 63 61 73 65 20 27 76 27 3a 0a 09 09 09 09 2f  .case 'v':...../
c610: 2a 20 49 67 6e 6f 72 65 64 20 2a 2f 0a 09 09 09  * Ignored */....
c620: 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20  .break;....case 
c630: 27 6f 27 3a 0a 09 09 09 09 6f 70 74 73 74 72 5f  'o':.....optstr_
c640: 6e 65 78 74 20 3d 20 6f 70 74 73 74 72 20 3d 20  next = optstr = 
c650: 6f 70 74 73 74 72 5f 73 20 3d 20 73 74 72 64 75  optstr_s = strdu
c660: 70 28 6f 70 74 61 72 67 29 3b 0a 0a 09 09 09 09  p(optarg);......
c670: 77 68 69 6c 65 20 28 31 29 20 7b 0a 09 09 09 09  while (1) {.....
c680: 09 6f 70 74 73 74 72 20 3d 20 6f 70 74 73 74 72  .optstr = optstr
c690: 5f 6e 65 78 74 3b 0a 0a 09 09 09 09 09 69 66 20  _next;.......if 
c6a0: 28 21 6f 70 74 73 74 72 29 20 7b 0a 09 09 09 09  (!optstr) {.....
c6b0: 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 09 7d 0a  ..break;......}.
c6c0: 0a 09 09 09 09 09 6f 70 74 73 74 72 5f 6e 65 78  ......optstr_nex
c6d0: 74 20 3d 20 73 74 72 63 68 72 28 6f 70 74 73 74  t = strchr(optst
c6e0: 72 2c 20 27 2c 27 29 3b 0a 09 09 09 09 09 69 66  r, ',');......if
c6f0: 20 28 6f 70 74 73 74 72 5f 6e 65 78 74 29 20 7b   (optstr_next) {
c700: 0a 09 09 09 09 09 09 2a 6f 70 74 73 74 72 5f 6e  .......*optstr_n
c710: 65 78 74 20 3d 20 27 5c 30 27 3b 0a 09 09 09 09  ext = '\0';.....
c720: 09 09 6f 70 74 73 74 72 5f 6e 65 78 74 2b 2b 3b  ..optstr_next++;
c730: 0a 09 09 09 09 09 7d 0a 0a 09 09 09 09 09 69 66  ......}.......if
c740: 20 28 73 74 72 63 6d 70 28 6f 70 74 73 74 72 2c   (strcmp(optstr,
c750: 20 22 6e 6f 74 68 72 65 61 64 73 22 29 20 3d 3d   "nothreads") ==
c760: 20 30 29 20 7b 0a 09 09 09 09 09 09 41 50 50 46   0) {.......APPF
c770: 53 5f 44 45 42 55 47 28 22 50 61 73 73 69 6e 67  S_DEBUG("Passing
c780: 20 6f 70 74 69 6f 6e 20 74 6f 20 46 55 53 45 3a   option to FUSE:
c790: 20 2d 73 22 29 3b 0a 0a 09 09 09 09 09 09 66 75   -s");........fu
c7a0: 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67  se_opt_parse(arg
c7b0: 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e  s, NULL, NULL, N
c7c0: 55 4c 4c 29 3b 0a 09 09 09 09 09 09 66 75 73 65  ULL);.......fuse
c7d0: 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72 67  _opt_add_arg(arg
c7e0: 73 2c 20 22 2d 73 22 29 3b 0a 0a 09 09 09 09 09  s, "-s");.......
c7f0: 09 61 70 70 66 73 5f 74 68 72 65 61 64 65 64 5f  .appfs_threaded_
c800: 74 63 6c 20 3d 20 30 3b 0a 09 09 09 09 09 7d 20  tcl = 0;......} 
c810: 65 6c 73 65 20 69 66 20 28 73 74 72 63 6d 70 28  else if (strcmp(
c820: 6f 70 74 73 74 72 2c 20 22 61 6c 6c 6f 77 5f 6f  optstr, "allow_o
c830: 74 68 65 72 22 29 20 3d 3d 20 30 29 20 7b 0a 09  ther") == 0) {..
c840: 09 09 09 09 09 41 50 50 46 53 5f 44 45 42 55 47  .....APPFS_DEBUG
c850: 28 22 50 61 73 73 69 6e 67 20 6f 70 74 69 6f 6e  ("Passing option
c860: 20 74 6f 20 46 55 53 45 3a 20 2d 6f 20 61 6c 6c   to FUSE: -o all
c870: 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 0a 09 09 09  ow_other");.....
c880: 09 09 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73  ...fuse_opt_pars
c890: 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55  e(args, NULL, NU
c8a0: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09 09 09 09  LL, NULL);......
c8b0: 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72  .fuse_opt_add_ar
c8c0: 67 28 61 72 67 73 2c 20 22 2d 6f 61 6c 6c 6f 77  g(args, "-oallow
c8d0: 5f 6f 74 68 65 72 22 29 3b 0a 09 09 09 09 09 7d  _other");......}
c8e0: 20 65 6c 73 65 20 69 66 20 28 73 74 72 63 6d 70   else if (strcmp
c8f0: 28 6f 70 74 73 74 72 2c 20 22 72 77 22 29 20 3d  (optstr, "rw") =
c900: 3d 20 30 29 20 7b 0a 09 09 09 09 09 09 2f 2a 20  = 0) {......./* 
c910: 49 67 6e 6f 72 65 64 20 2a 2f 0a 09 09 09 09 09  Ignored */......
c920: 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 09 09 41  } else {.......A
c930: 50 50 46 53 5f 45 52 52 4f 52 28 22 61 70 70 66  PPFS_ERROR("appf
c940: 73 64 3a 20 69 6e 76 61 6c 69 64 20 6f 70 74 69  sd: invalid opti
c950: 6f 6e 3a 20 5c 22 2d 6f 20 25 73 5c 22 22 2c 20  on: \"-o %s\"", 
c960: 6f 70 74 73 74 72 29 3b 0a 0a 09 09 09 09 09 09  optstr);........
c970: 66 72 65 65 28 6f 70 74 73 74 72 5f 73 29 3b 0a  free(optstr_s);.
c980: 0a 09 09 09 09 09 09 72 65 74 75 72 6e 28 31 29  .......return(1)
c990: 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a  ;......}.....}..
c9a0: 09 09 09 09 66 72 65 65 28 6f 70 74 73 74 72 5f  ....free(optstr_
c9b0: 73 29 3b 0a 0a 09 09 09 09 62 72 65 61 6b 3b 0a  s);......break;.
c9c0: 09 09 09 63 61 73 65 20 27 64 27 3a 0a 09 09 09  ...case 'd':....
c9d0: 63 61 73 65 20 27 66 27 3a 0a 09 09 09 63 61 73  case 'f':....cas
c9e0: 65 20 27 73 27 3a 0a 09 09 09 09 69 66 20 28 63  e 's':.....if (c
c9f0: 68 20 3d 3d 20 27 73 27 29 20 7b 0a 09 09 09 09  h == 's') {.....
ca00: 09 61 70 70 66 73 5f 74 68 72 65 61 64 65 64 5f  .appfs_threaded_
ca10: 74 63 6c 20 3d 20 30 3b 0a 09 09 09 09 7d 0a 0a  tcl = 0;.....}..
ca20: 09 09 09 09 66 61 6b 65 5f 61 72 67 5b 31 5d 20  ....fake_arg[1] 
ca30: 3d 20 63 68 3b 0a 0a 09 09 09 09 41 50 50 46 53  = ch;......APPFS
ca40: 5f 44 45 42 55 47 28 22 50 61 73 73 69 6e 67 20  _DEBUG("Passing 
ca50: 6f 70 74 69 6f 6e 20 74 6f 20 46 55 53 45 3a 20  option to FUSE: 
ca60: 25 73 22 2c 20 66 61 6b 65 5f 61 72 67 29 3b 0a  %s", fake_arg);.
ca70: 0a 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 70 61  .....fuse_opt_pa
ca80: 72 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20  rse(args, NULL, 
ca90: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09 09  NULL, NULL);....
caa0: 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72  .fuse_opt_add_ar
cab0: 67 28 61 72 67 73 2c 20 66 61 6b 65 5f 61 72 67  g(args, fake_arg
cac0: 29 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09  );.....break;...
cad0: 09 63 61 73 65 20 27 68 27 3a 0a 09 09 09 09 61  .case 'h':.....a
cae0: 70 70 66 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28  ppfs_print_help(
caf0: 73 74 64 6f 75 74 29 3b 0a 0a 09 09 09 09 72 65  stdout);......re
cb00: 74 75 72 6e 28 2d 31 29 3b 0a 09 09 09 63 61 73  turn(-1);....cas
cb10: 65 20 27 3a 27 3a 0a 09 09 09 63 61 73 65 20 27  e ':':....case '
cb20: 3f 27 3a 0a 09 09 09 64 65 66 61 75 6c 74 3a 0a  ?':....default:.
cb30: 09 09 09 09 61 70 70 66 73 5f 70 72 69 6e 74 5f  ....appfs_print_
cb40: 68 65 6c 70 28 73 74 64 65 72 72 29 3b 0a 0a 09  help(stderr);...
cb50: 09 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 09  ...return(1);...
cb60: 7d 0a 09 7d 0a 0a 09 69 66 20 28 28 6f 70 74 69  }..}...if ((opti
cb70: 6e 64 20 2b 20 32 29 20 21 3d 20 61 72 67 63 29  nd + 2) != argc)
cb80: 20 7b 0a 09 09 69 66 20 28 28 6f 70 74 69 6e 64   {...if ((optind
cb90: 20 2b 20 32 29 20 3c 20 61 72 67 63 29 20 7b 0a   + 2) < argc) {.
cba0: 09 09 09 41 50 50 46 53 5f 45 52 52 4f 52 28 22  ...APPFS_ERROR("
cbb0: 54 6f 6f 20 6d 61 6e 79 20 61 72 67 75 6d 65 6e  Too many argumen
cbc0: 74 73 22 29 3b 0a 09 09 7d 20 65 6c 73 65 20 7b  ts");...} else {
cbd0: 0a 09 09 09 41 50 50 46 53 5f 45 52 52 4f 52 28  ....APPFS_ERROR(
cbe0: 22 4d 69 73 73 69 6e 67 20 63 61 63 68 65 64 69  "Missing cachedi
cbf0: 72 20 6f 72 20 6d 6f 75 6e 74 70 6f 69 6e 74 22  r or mountpoint"
cc00: 29 3b 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f  );...}....appfs_
cc10: 70 72 69 6e 74 5f 68 65 6c 70 28 73 74 64 65 72  print_help(stder
cc20: 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29  r);....return(1)
cc30: 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65  ;..}.../*.. * Se
cc40: 74 20 63 61 63 68 65 20 64 69 72 20 61 73 20 66  t cache dir as f
cc50: 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 28 74  irst argument (t
cc60: 68 65 20 22 64 65 76 69 63 65 22 2c 20 65 73 73  he "device", ess
cc70: 65 6e 74 69 61 6c 6c 79 29 0a 09 20 2a 2f 0a 09  entially).. */..
cc80: 61 70 70 66 73 5f 63 61 63 68 65 64 69 72 20 3d  appfs_cachedir =
cc90: 20 61 72 67 76 5b 6f 70 74 69 6e 64 5d 3b 0a 0a   argv[optind];..
cca0: 09 2f 2a 0a 09 20 2a 20 50 61 73 73 20 74 68 65  ./*.. * Pass the
ccb0: 20 72 65 6d 61 69 6e 69 6e 67 20 61 72 67 75 6d   remaining argum
ccc0: 65 6e 74 20 74 6f 20 46 55 53 45 20 61 73 20 74  ent to FUSE as t
ccd0: 68 65 20 64 69 72 65 63 74 6f 72 79 0a 09 20 2a  he directory.. *
cce0: 2f 0a 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73  /..fuse_opt_pars
ccf0: 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55  e(args, NULL, NU
cd00: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 66 75 73 65  LL, NULL);..fuse
cd10: 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72 67  _opt_add_arg(arg
cd20: 73 2c 20 61 72 67 76 5b 6f 70 74 69 6e 64 20 2b  s, argv[optind +
cd30: 20 31 5d 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30   1]);...return(0
cd40: 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 20 2a 20 46 55 53  );.}.../*. * FUS
cd50: 45 20 6f 70 65 72 61 74 69 6f 6e 73 20 73 74 72  E operations str
cd60: 75 63 74 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69  ucture. */.stati
cd70: 63 20 73 74 72 75 63 74 20 66 75 73 65 5f 6f 70  c struct fuse_op
cd80: 65 72 61 74 69 6f 6e 73 20 61 70 70 66 73 5f 6f  erations appfs_o
cd90: 70 65 72 61 74 69 6f 6e 73 20 3d 20 7b 0a 09 2e  perations = {...
cda0: 67 65 74 61 74 74 72 20 20 20 3d 20 61 70 70 66  getattr   = appf
cdb0: 73 5f 66 75 73 65 5f 67 65 74 61 74 74 72 2c 0a  s_fuse_getattr,.
cdc0: 09 2e 72 65 61 64 64 69 72 20 20 20 3d 20 61 70  ..readdir   = ap
cdd0: 70 66 73 5f 66 75 73 65 5f 72 65 61 64 64 69 72  pfs_fuse_readdir
cde0: 2c 0a 09 2e 72 65 61 64 6c 69 6e 6b 20 20 3d 20  ,...readlink  = 
cdf0: 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 6c  appfs_fuse_readl
ce00: 69 6e 6b 2c 0a 09 2e 6f 70 65 6e 20 20 20 20 20  ink,...open     
ce10: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 6f 70   = appfs_fuse_op
ce20: 65 6e 2c 0a 09 2e 72 65 6c 65 61 73 65 20 20 20  en,...release   
ce30: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 63 6c 6f  = appfs_fuse_clo
ce40: 73 65 2c 0a 09 2e 72 65 61 64 20 20 20 20 20 20  se,...read      
ce50: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61  = appfs_fuse_rea
ce60: 64 2c 0a 09 2e 77 72 69 74 65 20 20 20 20 20 3d  d,...write     =
ce70: 20 61 70 70 66 73 5f 66 75 73 65 5f 77 72 69 74   appfs_fuse_writ
ce80: 65 2c 0a 09 2e 6d 6b 6e 6f 64 20 20 20 20 20 3d  e,...mknod     =
ce90: 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b 6e 6f   appfs_fuse_mkno
cea0: 64 2c 0a 09 2e 63 72 65 61 74 65 20 20 20 20 3d  d,...create    =
ceb0: 20 61 70 70 66 73 5f 66 75 73 65 5f 63 72 65 61   appfs_fuse_crea
cec0: 74 65 2c 0a 09 2e 74 72 75 6e 63 61 74 65 20 20  te,...truncate  
ced0: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 74 72 75  = appfs_fuse_tru
cee0: 6e 63 61 74 65 2c 0a 09 2e 75 6e 6c 69 6e 6b 20  ncate,...unlink 
cef0: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
cf00: 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e  unlink_rmdir,...
cf10: 72 6d 64 69 72 20 20 20 20 20 3d 20 61 70 70 66  rmdir     = appf
cf20: 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d  s_fuse_unlink_rm
cf30: 64 69 72 2c 0a 09 2e 6d 6b 64 69 72 20 20 20 20  dir,...mkdir    
cf40: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b   = appfs_fuse_mk
cf50: 64 69 72 2c 0a 09 2e 63 68 6d 6f 64 20 20 20 20  dir,...chmod    
cf60: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 63 68   = appfs_fuse_ch
cf70: 6d 6f 64 2c 0a 09 2e 73 79 6d 6c 69 6e 6b 20 20  mod,...symlink  
cf80: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 73 79   = appfs_fuse_sy
cf90: 6d 6c 69 6e 6b 2c 0a 7d 3b 0a 0a 0a 23 69 66 64  mlink,.};...#ifd
cfa0: 65 66 20 41 50 50 46 53 5f 4e 4f 5f 52 4c 49 4d  ef APPFS_NO_RLIM
cfb0: 49 54 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61  IT.static void a
cfc0: 70 70 66 73 5f 73 65 74 5f 72 65 73 6f 75 72 63  ppfs_set_resourc
cfd0: 65 5f 6c 69 6d 69 74 73 28 76 6f 69 64 29 20 7b  e_limits(void) {
cfe0: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 23 65 6c 73  ..return;.}.#els
cff0: 65 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f  e.#include <sys/
d000: 72 65 73 6f 75 72 63 65 2e 68 3e 20 20 0a 0a 73  resource.h>  ..s
d010: 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 73  tatic void appfs
d020: 5f 73 65 74 5f 72 65 73 6f 75 72 63 65 5f 6c 69  _set_resource_li
d030: 6d 69 74 73 28 76 6f 69 64 29 20 7b 0a 09 73 74  mits(void) {..st
d040: 72 75 63 74 20 72 6c 69 6d 69 74 20 6e 75 6d 62  ruct rlimit numb
d050: 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 3b 0a 09  er_open_files;..
d060: 72 6c 69 6d 5f 74 20 6e 75 6d 62 65 72 5f 6f 70  rlim_t number_op
d070: 65 6e 5f 66 69 6c 65 73 5f 6d 61 78 3b 0a 09 69  en_files_max;..i
d080: 6e 74 20 72 6c 69 6d 69 74 5f 72 65 74 3b 0a 0a  nt rlimit_ret;..
d090: 09 2f 2a 0a 09 20 2a 20 49 6e 63 72 65 61 73 65  ./*.. * Increase
d0a0: 20 72 65 73 6f 75 72 63 65 20 6c 69 6d 69 74 73   resource limits
d0b0: 20 66 6f 72 20 6e 75 6d 62 65 72 20 6f 66 20 6f   for number of o
d0c0: 70 65 6e 20 66 69 6c 65 73 0a 09 20 2a 20 74 6f  pen files.. * to
d0d0: 20 74 68 65 20 6d 61 78 69 6d 75 6d 20 76 61 6c   the maximum val
d0e0: 75 65 73 2c 20 73 69 6e 63 65 20 77 65 20 6d 61  ues, since we ma
d0f0: 79 20 62 65 20 61 73 6b 65 64 20 74 6f 0a 09 20  y be asked to.. 
d100: 2a 20 68 6f 6c 64 20 6f 70 65 6e 20 6d 61 6e 79  * hold open many
d110: 20 66 69 6c 65 73 20 6f 6e 20 62 65 68 61 6c 66   files on behalf
d120: 20 6f 66 20 6d 61 6e 79 20 6f 74 68 65 72 20 70   of many other p
d130: 72 6f 63 65 73 73 65 73 0a 09 20 2a 2f 0a 09 6e  rocesses.. */..n
d140: 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73  umber_open_files
d150: 2e 72 6c 69 6d 5f 63 75 72 20 3d 20 6e 75 6d 62  .rlim_cur = numb
d160: 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 2e 72 6c  er_open_files.rl
d170: 69 6d 5f 6d 61 78 20 3d 20 52 4c 49 4d 5f 49 4e  im_max = RLIM_IN
d180: 46 49 4e 49 54 59 3b 0a 0a 09 72 6c 69 6d 69 74  FINITY;...rlimit
d190: 5f 72 65 74 20 3d 20 73 65 74 72 6c 69 6d 69 74  _ret = setrlimit
d1a0: 28 52 4c 49 4d 49 54 5f 4e 4f 46 49 4c 45 2c 20  (RLIMIT_NOFILE, 
d1b0: 26 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c  &number_open_fil
d1c0: 65 73 29 3b 0a 0a 09 69 66 20 28 72 6c 69 6d 69  es);...if (rlimi
d1d0: 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  t_ret != 0) {...
d1e0: 72 6c 69 6d 69 74 5f 72 65 74 20 3d 20 67 65 74  rlimit_ret = get
d1f0: 72 6c 69 6d 69 74 28 52 4c 49 4d 49 54 5f 4e 4f  rlimit(RLIMIT_NO
d200: 46 49 4c 45 2c 20 26 6e 75 6d 62 65 72 5f 6f 70  FILE, &number_op
d210: 65 6e 5f 66 69 6c 65 73 29 3b 0a 09 09 69 66 20  en_files);...if 
d220: 28 72 6c 69 6d 69 74 5f 72 65 74 20 3d 3d 20 30  (rlimit_ret == 0
d230: 29 20 7b 0a 09 09 09 6e 75 6d 62 65 72 5f 6f 70  ) {....number_op
d240: 65 6e 5f 66 69 6c 65 73 5f 6d 61 78 20 3d 20 6e  en_files_max = n
d250: 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73  umber_open_files
d260: 2e 72 6c 69 6d 5f 6d 61 78 3b 0a 0a 09 09 09 69  .rlim_max;.....i
d270: 66 20 28 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66  f (number_open_f
d280: 69 6c 65 73 5f 6d 61 78 20 3c 20 28 31 30 32 34  iles_max < (1024
d290: 20 2a 20 31 30 32 34 29 29 20 7b 0a 09 09 09 09   * 1024)) {.....
d2a0: 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65  number_open_file
d2b0: 73 2e 72 6c 69 6d 5f 63 75 72 20 3d 20 6e 75 6d  s.rlim_cur = num
d2c0: 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 2e 72  ber_open_files.r
d2d0: 6c 69 6d 5f 6d 61 78 20 3d 20 31 30 32 34 20 2a  lim_max = 1024 *
d2e0: 20 31 30 32 34 3b 0a 0a 09 09 09 09 72 6c 69 6d   1024;......rlim
d2f0: 69 74 5f 72 65 74 20 3d 20 73 65 74 72 6c 69 6d  it_ret = setrlim
d300: 69 74 28 52 4c 49 4d 49 54 5f 4e 4f 46 49 4c 45  it(RLIMIT_NOFILE
d310: 2c 20 26 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66  , &number_open_f
d320: 69 6c 65 73 29 3b 0a 09 09 09 7d 20 65 6c 73 65  iles);....} else
d330: 20 7b 0a 09 09 09 09 6e 75 6d 62 65 72 5f 6f 70   {.....number_op
d340: 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f 63 75  en_files.rlim_cu
d350: 72 20 3d 20 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f  r = number_open_
d360: 66 69 6c 65 73 2e 72 6c 69 6d 5f 6d 61 78 3b 0a  files.rlim_max;.
d370: 09 09 09 7d 0a 0a 09 09 09 72 6c 69 6d 69 74 5f  ...}.....rlimit_
d380: 72 65 74 20 3d 20 73 65 74 72 6c 69 6d 69 74 28  ret = setrlimit(
d390: 52 4c 49 4d 49 54 5f 4e 4f 46 49 4c 45 2c 20 26  RLIMIT_NOFILE, &
d3a0: 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65  number_open_file
d3b0: 73 29 3b 0a 0a 09 09 09 69 66 20 28 72 6c 69 6d  s);.....if (rlim
d3c0: 69 74 5f 72 65 74 20 21 3d 20 30 20 26 26 20 6e  it_ret != 0 && n
d3d0: 75 6d 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73  umber_open_files
d3e0: 2e 72 6c 69 6d 5f 63 75 72 20 21 3d 20 6e 75 6d  .rlim_cur != num
d3f0: 62 65 72 5f 6f 70 65 6e 5f 66 69 6c 65 73 5f 6d  ber_open_files_m
d400: 61 78 29 20 7b 0a 09 09 09 09 6e 75 6d 62 65 72  ax) {.....number
d410: 5f 6f 70 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d  _open_files.rlim
d420: 5f 63 75 72 20 3d 20 6e 75 6d 62 65 72 5f 6f 70  _cur = number_op
d430: 65 6e 5f 66 69 6c 65 73 2e 72 6c 69 6d 5f 6d 61  en_files.rlim_ma
d440: 78 20 3d 20 6e 75 6d 62 65 72 5f 6f 70 65 6e 5f  x = number_open_
d450: 66 69 6c 65 73 5f 6d 61 78 3b 0a 0a 09 09 09 09  files_max;......
d460: 73 65 74 72 6c 69 6d 69 74 28 52 4c 49 4d 49 54  setrlimit(RLIMIT
d470: 5f 4e 4f 46 49 4c 45 2c 20 26 6e 75 6d 62 65 72  _NOFILE, &number
d480: 5f 6f 70 65 6e 5f 66 69 6c 65 73 29 3b 0a 09 09  _open_files);...
d490: 09 7d 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75  .}...}..}...retu
d4a0: 72 6e 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a  rn;.}.#endif../*
d4b0: 0a 20 2a 20 45 6e 74 72 79 20 70 6f 69 6e 74 20  . * Entry point 
d4c0: 69 6e 74 6f 20 74 68 69 73 20 70 72 6f 67 72 61  into this progra
d4d0: 6d 2e 0a 20 2a 2f 0a 69 6e 74 20 6d 61 69 6e 28  m.. */.int main(
d4e0: 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a  int argc, char *
d4f0: 2a 61 72 67 76 29 20 7b 0a 09 54 63 6c 5f 49 6e  *argv) {..Tcl_In
d500: 74 65 72 70 20 2a 74 65 73 74 5f 69 6e 74 65 72  terp *test_inter
d510: 70 3b 0a 09 63 68 61 72 20 2a 74 65 73 74 5f 69  p;..char *test_i
d520: 6e 74 65 72 70 5f 65 72 72 6f 72 3b 0a 09 73 74  nterp_error;..st
d530: 72 75 63 74 20 66 75 73 65 5f 61 72 67 73 20 61  ruct fuse_args a
d540: 72 67 73 20 3d 20 46 55 53 45 5f 41 52 47 53 5f  rgs = FUSE_ARGS_
d550: 49 4e 49 54 28 30 2c 20 4e 55 4c 4c 29 3b 0a 09  INIT(0, NULL);..
d560: 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 2c  int pthread_ret,
d570: 20 61 6f 70 5f 72 65 74 3b 0a 09 63 68 61 72 20   aop_ret;..char 
d580: 2a 61 72 67 76 30 3b 0a 69 6e 74 20 69 3b 0a 0a  *argv0;.int i;..
d590: 09 2f 2a 0a 09 20 2a 20 53 6b 69 70 20 70 61 73  ./*.. * Skip pas
d5a0: 73 65 64 20 70 72 6f 67 72 61 6d 20 6e 61 6d 65  sed program name
d5b0: 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20  .. */..if (argc 
d5c0: 3d 3d 20 30 20 7c 7c 20 61 72 67 76 20 3d 3d 20  == 0 || argv == 
d5d0: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
d5e0: 28 31 29 3b 0a 09 7d 0a 66 6f 72 20 28 69 20 3d  (1);..}.for (i =
d5f0: 20 30 3b 20 69 20 3c 20 61 72 67 63 3b 20 69 2b   0; i < argc; i+
d600: 2b 29 20 7b 0a 2f 2f 09 70 72 69 6e 74 66 28 22  +) {.//.printf("
d610: 61 72 67 76 5b 25 69 5d 20 3d 20 5c 22 25 73 5c  argv[%i] = \"%s\
d620: 22 5c 6e 22 2c 20 69 2c 20 61 72 67 76 5b 69 5d  "\n", i, argv[i]
d630: 29 3b 0a 7d 0a 0a 09 61 72 67 76 30 20 3d 20 61  );.}...argv0 = a
d640: 72 67 76 5b 30 5d 3b 0a 0a 09 61 72 67 63 2d 2d  rgv[0];...argc--
d650: 3b 0a 09 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a  ;..argv++;.../*.
d660: 09 20 2a 20 53 65 74 20 61 70 70 72 6f 70 72 69  . * Set appropri
d670: 61 74 65 20 75 6d 61 73 6b 0a 09 20 2a 2f 0a 09  ate umask.. */..
d680: 75 6d 61 73 6b 28 30 32 32 29 3b 0a 0a 09 2f 2a  umask(022);.../*
d690: 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20  .. * Set global 
d6a0: 76 61 72 69 61 62 6c 65 73 2c 20 74 68 65 73 65  variables, these
d6b0: 20 73 68 6f 75 6c 64 20 62 65 20 63 6f 6e 66 69   should be confi
d6c0: 67 75 72 61 74 69 6f 6e 20 6f 70 74 69 6f 6e 73  guration options
d6d0: 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61  ... */..appfs_ca
d6e0: 63 68 65 64 69 72 20 3d 20 41 50 50 46 53 5f 43  chedir = APPFS_C
d6f0: 41 43 48 45 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20  ACHEDIR;.../*.. 
d700: 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72  * Set global var
d710: 69 61 62 6c 65 20 66 6f 72 20 22 62 6f 6f 74 20  iable for "boot 
d720: 74 69 6d 65 22 20 74 6f 20 73 65 74 20 61 20 74  time" to set a t
d730: 69 6d 65 20 6f 6e 20 64 69 72 65 63 74 6f 72 69  ime on directori
d740: 65 73 0a 09 20 2a 20 74 68 61 74 20 77 65 20 66  es.. * that we f
d750: 61 6b 65 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73  ake... */..appfs
d760: 5f 62 6f 6f 74 74 69 6d 65 20 3d 20 74 69 6d 65  _boottime = time
d770: 28 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a  (NULL);.../*.. *
d780: 20 52 65 67 69 73 74 65 72 20 22 73 68 61 31 22   Register "sha1"
d790: 20 61 6e 64 20 22 61 70 70 66 73 64 22 20 70 61   and "appfsd" pa
d7a0: 63 6b 61 67 65 20 77 69 74 68 20 6c 69 62 74 63  ckage with libtc
d7b0: 6c 20 73 6f 20 74 68 61 74 20 61 6e 79 20 6e 65  l so that any ne
d7c0: 77 0a 09 20 2a 20 69 6e 74 65 72 70 72 65 74 65  w.. * interprete
d7d0: 72 73 20 63 72 65 61 74 65 64 20 28 77 68 69 63  rs created (whic
d7e0: 68 20 61 72 65 20 64 6f 6e 65 20 64 79 6e 61 6d  h are done dynam
d7f0: 69 63 61 6c 6c 79 20 62 79 20 46 55 53 45 29 20  ically by FUSE) 
d800: 63 61 6e 20 68 61 76 65 0a 09 20 2a 20 74 68 65  can have.. * the
d810: 20 61 70 70 72 6f 70 72 69 61 74 65 20 63 6f 6e   appropriate con
d820: 66 69 67 75 72 61 74 69 6f 6e 20 64 6f 6e 65 20  figuration done 
d830: 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 09  automatically...
d840: 20 2a 2f 0a 09 54 63 6c 5f 53 74 61 74 69 63 50   */..Tcl_StaticP
d850: 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 73 68  ackage(NULL, "sh
d860: 61 31 22 2c 20 53 68 61 31 5f 49 6e 69 74 2c 20  a1", Sha1_Init, 
d870: 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 53 74 61 74  NULL);..Tcl_Stat
d880: 69 63 50 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20  icPackage(NULL, 
d890: 22 61 70 70 66 73 64 22 2c 20 41 70 70 66 73 64  "appfsd", Appfsd
d8a0: 5f 49 6e 69 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09  _Init, NULL);...
d8b0: 2f 2a 0a 09 20 2a 20 43 72 65 61 74 65 20 61 20  /*.. * Create a 
d8c0: 74 68 72 65 61 64 2d 73 70 65 63 69 66 69 63 2d  thread-specific-
d8d0: 64 61 74 61 20 28 54 53 44 29 20 6b 65 79 20 66  data (TSD) key f
d8e0: 6f 72 20 65 61 63 68 20 74 68 72 65 61 64 20 74  or each thread t
d8f0: 6f 20 72 65 66 65 72 0a 09 20 2a 20 74 6f 20 69  o refer.. * to i
d900: 74 73 20 6f 77 6e 20 54 63 6c 20 69 6e 74 65 72  ts own Tcl inter
d910: 70 72 65 74 65 72 2e 20 20 54 63 6c 20 69 6e 74  preter.  Tcl int
d920: 65 72 70 72 65 74 65 72 73 20 6d 75 73 74 20 62  erpreters must b
d930: 65 20 75 6e 69 71 75 65 20 70 65 72 0a 09 20 2a  e unique per.. *
d940: 20 74 68 72 65 61 64 20 61 6e 64 20 6e 65 77 20   thread and new 
d950: 74 68 72 65 61 64 73 20 61 72 65 20 64 79 6e 61  threads are dyna
d960: 6d 69 63 61 6c 6c 79 20 63 72 65 61 74 65 64 20  mically created 
d970: 62 79 20 46 55 53 45 2e 0a 09 20 2a 2f 0a 09 70  by FUSE... */..p
d980: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68  thread_ret = pth
d990: 72 65 61 64 5f 6b 65 79 5f 63 72 65 61 74 65 28  read_key_create(
d9a0: 26 69 6e 74 65 72 70 4b 65 79 2c 20 61 70 70 66  &interpKey, appf
d9b0: 73 5f 74 65 72 6d 69 6e 61 74 65 5f 69 6e 74 65  s_terminate_inte
d9c0: 72 70 5f 61 6e 64 5f 74 68 72 65 61 64 29 3b 0a  rp_and_thread);.
d9d0: 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74  .if (pthread_ret
d9e0: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53   != 0) {...APPFS
d9f0: 5f 45 52 52 4f 52 28 22 55 6e 61 62 6c 65 20 74  _ERROR("Unable t
da00: 6f 20 63 72 65 61 74 65 20 54 53 44 20 6b 65 79  o create TSD key
da10: 20 66 6f 72 20 54 63 6c 2e 20 20 41 62 6f 72 74   for Tcl.  Abort
da20: 69 6e 67 2e 22 29 3b 0a 0a 09 09 72 65 74 75 72  ing.");....retur
da30: 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  n(1);..}.../*.. 
da40: 2a 20 4d 61 6e 75 61 6c 6c 79 20 73 70 65 63 69  * Manually speci
da50: 66 79 20 63 61 63 68 65 20 64 69 72 65 63 74 6f  fy cache directo
da60: 72 79 2c 20 77 69 74 68 6f 75 74 20 46 55 53 45  ry, without FUSE
da70: 20 63 61 6c 6c 62 61 63 6b 0a 09 20 2a 20 54 68   callback.. * Th
da80: 69 73 20 6f 70 74 69 6f 6e 20 6f 6e 6c 79 20 77  is option only w
da90: 6f 72 6b 73 20 77 68 65 6e 20 6e 6f 74 20 75 73  orks when not us
daa0: 69 6e 67 20 46 55 53 45 2c 20 73 69 6e 63 65 20  ing FUSE, since 
dab0: 77 65 0a 09 20 2a 20 64 6f 20 6e 6f 74 20 70 72  we.. * do not pr
dac0: 6f 63 65 73 73 20 69 74 20 77 69 74 68 20 46 55  ocess it with FU
dad0: 53 45 73 20 6f 70 74 69 6f 6e 20 70 72 6f 63 65  SEs option proce
dae0: 73 73 69 6e 67 2e 0a 09 20 2a 2f 0a 09 69 66 20  ssing... */..if 
daf0: 28 61 72 67 63 20 3e 3d 20 32 29 20 7b 0a 09 09  (argc >= 2) {...
db00: 69 66 20 28 73 74 72 63 6d 70 28 61 72 67 76 5b  if (strcmp(argv[
db10: 30 5d 2c 20 22 2d 2d 63 61 63 68 65 64 69 72 22  0], "--cachedir"
db20: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 61 70 70  ) == 0) {....app
db30: 66 73 5f 63 61 63 68 65 64 69 72 20 3d 20 73 74  fs_cachedir = st
db40: 72 64 75 70 28 61 72 67 76 5b 31 5d 29 3b 0a 0a  rdup(argv[1]);..
db50: 09 09 09 61 72 67 63 20 2d 3d 20 32 3b 0a 09 09  ...argc -= 2;...
db60: 09 61 72 67 76 20 2b 3d 20 32 3b 0a 09 09 7d 0a  .argv += 2;...}.
db70: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 51 4c 69  .}.../*.. * SQLi
db80: 74 65 33 20 6d 6f 64 65 2c 20 66 6f 72 20 72 75  te3 mode, for ru
db90: 6e 6e 69 6e 67 20 72 61 77 20 53 51 4c 20 61 67  nning raw SQL ag
dba0: 61 69 6e 73 74 20 74 68 65 20 63 61 63 68 65 20  ainst the cache 
dbb0: 64 61 74 61 62 61 73 65 0a 09 20 2a 2f 0a 09 69  database.. */..i
dbc0: 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26 26 20  f (argc == 2 && 
dbd0: 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20  strcmp(argv[0], 
dbe0: 22 2d 2d 73 71 6c 69 74 65 33 22 29 20 3d 3d 20  "--sqlite3") == 
dbf0: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 61 70  0) {...return(ap
dc00: 70 66 73 5f 73 71 6c 69 74 65 33 28 61 72 67 76  pfs_sqlite3(argv
dc10: 5b 31 5d 29 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  [1]));..}.../*..
dc20: 20 2a 20 54 63 6c 20 6d 6f 64 65 2c 20 66 6f 72   * Tcl mode, for
dc30: 20 72 75 6e 6e 69 6e 67 20 72 61 77 20 54 63 6c   running raw Tcl
dc40: 20 69 6e 20 74 68 65 20 73 61 6d 65 20 65 6e 76   in the same env
dc50: 69 72 6f 6e 6d 65 6e 74 20 41 70 70 46 53 64 20  ironment AppFSd 
dc60: 77 6f 75 6c 64 0a 09 20 2a 20 72 75 6e 20 63 6f  would.. * run co
dc70: 64 65 2e 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72  de... */..if (ar
dc80: 67 63 20 3d 3d 20 32 20 26 26 20 73 74 72 63 6d  gc == 2 && strcm
dc90: 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 74 63  p(argv[0], "--tc
dca0: 6c 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65  l") == 0) {...re
dcb0: 74 75 72 6e 28 61 70 70 66 73 5f 74 63 6c 28 61  turn(appfs_tcl(a
dcc0: 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 0a 09 2f  rgv[1]));..}.../
dcd0: 2a 0a 09 20 2a 20 50 61 72 73 65 20 63 6f 6d 6d  *.. * Parse comm
dce0: 61 6e 64 20 6c 69 6e 65 20 61 72 67 75 6d 65 6e  and line argumen
dcf0: 74 73 0a 09 20 2a 2f 0a 09 2f 2a 2a 0a 09 20 2a  ts.. */../**.. *
dd00: 2a 20 52 65 73 74 6f 72 65 20 61 72 67 63 2f 61  * Restore argc/a
dd10: 72 67 76 20 74 6f 20 6f 72 69 67 69 6e 61 6c 20  rgv to original 
dd20: 76 61 6c 75 65 73 2c 20 72 65 70 6c 61 63 69 6e  values, replacin
dd30: 67 20 61 72 67 76 5b 30 5d 20 69 6e 20 63 61 73  g argv[0] in cas
dd40: 65 0a 09 20 2a 2a 20 69 74 20 77 61 73 20 6d 6f  e.. ** it was mo
dd50: 69 66 69 65 64 20 62 79 20 2d 2d 63 61 63 68 65  ified by --cache
dd60: 64 69 72 20 6f 70 74 69 6f 6e 2e 0a 09 20 2a 2a  dir option... **
dd70: 2f 0a 09 61 72 67 63 2b 2b 3b 0a 09 61 72 67 76  /..argc++;..argv
dd80: 2d 2d 3b 0a 09 61 72 67 76 5b 30 5d 20 3d 20 61  --;..argv[0] = a
dd90: 72 67 76 30 3b 0a 0a 09 2f 2a 2a 0a 09 20 2a 2a  rgv0;.../**.. **
dda0: 20 50 65 72 66 6f 72 6d 20 74 68 65 20 61 72 67   Perform the arg
ddb0: 75 6d 65 6e 74 20 70 61 72 73 69 6e 67 0a 09 20  ument parsing.. 
ddc0: 2a 2a 2f 0a 09 61 6f 70 5f 72 65 74 20 3d 20 61  **/..aop_ret = a
ddd0: 70 70 66 73 5f 6f 70 74 5f 70 61 72 73 65 28 61  ppfs_opt_parse(a
dde0: 72 67 63 2c 20 61 72 67 76 2c 20 26 61 72 67 73  rgc, argv, &args
ddf0: 29 3b 0a 09 69 66 20 28 61 6f 70 5f 72 65 74 20  );..if (aop_ret 
de00: 21 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 61 6f  != 0) {...if (ao
de10: 70 5f 72 65 74 20 3c 20 30 29 20 7b 0a 09 09 09  p_ret < 0) {....
de20: 72 65 74 75 72 6e 28 30 29 3b 0a 09 09 7d 0a 0a  return(0);...}..
de30: 09 09 72 65 74 75 72 6e 28 61 6f 70 5f 72 65 74  ..return(aop_ret
de40: 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43  );..}.../*.. * C
de50: 72 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65  reate a Tcl inte
de60: 72 70 72 65 74 65 72 20 6a 75 73 74 20 74 6f 20  rpreter just to 
de70: 76 65 72 69 66 79 20 74 68 61 74 20 74 68 69 6e  verify that thin
de80: 67 73 20 61 72 65 20 69 6e 20 77 6f 72 6b 69 6e  gs are in workin
de90: 67 20 0a 09 20 2a 20 6f 72 64 65 72 20 62 65 66  g .. * order bef
dea0: 6f 72 65 20 77 65 20 62 65 63 6f 6d 65 20 61 20  ore we become a 
deb0: 64 61 65 6d 6f 6e 2e 0a 09 20 2a 2f 0a 09 74 65  daemon... */..te
dec0: 73 74 5f 69 6e 74 65 72 70 20 3d 20 61 70 70 66  st_interp = appf
ded0: 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65  s_create_TclInte
dee0: 72 70 28 26 74 65 73 74 5f 69 6e 74 65 72 70 5f  rp(&test_interp_
def0: 65 72 72 6f 72 29 3b 0a 09 69 66 20 28 74 65 73  error);..if (tes
df00: 74 5f 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c  t_interp == NULL
df10: 29 20 7b 0a 09 09 69 66 20 28 74 65 73 74 5f 69  ) {...if (test_i
df20: 6e 74 65 72 70 5f 65 72 72 6f 72 20 3d 3d 20 4e  nterp_error == N
df30: 55 4c 4c 29 20 7b 0a 09 09 09 74 65 73 74 5f 69  ULL) {....test_i
df40: 6e 74 65 72 70 5f 65 72 72 6f 72 20 3d 20 22 55  nterp_error = "U
df50: 6e 6b 6e 6f 77 6e 20 65 72 72 6f 72 22 3b 0a 09  nknown error";..
df60: 09 7d 0a 0a 09 09 41 50 50 46 53 5f 45 52 52 4f  .}....APPFS_ERRO
df70: 52 28 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69  R("Unable to ini
df80: 74 69 61 6c 69 7a 65 20 54 63 6c 20 69 6e 74 65  tialize Tcl inte
df90: 72 70 72 65 74 65 72 20 66 6f 72 20 41 70 70 46  rpreter for AppF
dfa0: 53 64 3a 22 29 3b 0a 09 09 41 50 50 46 53 5f 45  Sd:");...APPFS_E
dfb0: 52 52 4f 52 28 22 25 73 22 2c 20 74 65 73 74 5f  RROR("%s", test_
dfc0: 69 6e 74 65 72 70 5f 65 72 72 6f 72 29 3b 0a 0a  interp_error);..
dfd0: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
dfe0: 0a 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65  ..Tcl_DeleteInte
dff0: 72 70 28 74 65 73 74 5f 69 6e 74 65 72 70 29 3b  rp(test_interp);
e000: 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 74 68 72  ...if (appfs_thr
e010: 65 61 64 65 64 5f 74 63 6c 29 20 7b 0a 09 09 54  eaded_tcl) {...T
e020: 63 6c 5f 46 69 6e 61 6c 69 7a 65 4e 6f 74 69 66  cl_FinalizeNotif
e030: 69 65 72 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  ier(NULL);..}...
e040: 61 70 70 66 73 5f 73 65 74 5f 72 65 73 6f 75 72  appfs_set_resour
e050: 63 65 5f 6c 69 6d 69 74 73 28 29 3b 0a 09 61 70  ce_limits();..ap
e060: 70 66 73 5f 73 65 74 5f 73 69 67 68 61 6e 64 6c  pfs_set_sighandl
e070: 65 72 28 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 45  er();.../*.. * E
e080: 6e 74 65 72 20 74 68 65 20 46 55 53 45 20 6d 61  nter the FUSE ma
e090: 69 6e 20 6c 6f 6f 70 20 2d 2d 20 74 68 69 73 20  in loop -- this 
e0a0: 77 69 6c 6c 20 70 72 6f 63 65 73 73 20 61 6e 79  will process any
e0b0: 20 61 72 67 75 6d 65 6e 74 73 0a 09 20 2a 20 61   arguments.. * a
e0c0: 6e 64 20 73 74 61 72 74 20 73 65 72 76 69 63 69  nd start servici
e0d0: 6e 67 20 72 65 71 75 65 73 74 73 2e 0a 09 20 2a  ng requests... *
e0e0: 2f 0a 09 61 70 70 66 73 5f 66 75 73 65 5f 73 74  /..appfs_fuse_st
e0f0: 61 72 74 65 64 20 3d 20 31 3b 0a 09 72 65 74 75  arted = 1;..retu
e100: 72 6e 28 66 75 73 65 5f 6d 61 69 6e 28 61 72 67  rn(fuse_main(arg
e110: 73 2e 61 72 67 63 2c 20 61 72 67 73 2e 61 72 67  s.argc, args.arg
e120: 76 2c 20 26 61 70 70 66 73 5f 6f 70 65 72 61 74  v, &appfs_operat
e130: 69 6f 6e 73 2c 20 4e 55 4c 4c 29 29 3b 0a 7d 0a  ions, NULL));.}.