Hex Artifact Content

Artifact e49bb6021f43ff1270db6a223c1c35f535bfd115:


0000: 23 64 65 66 69 6e 65 20 46 55 53 45 5f 55 53 45  #define FUSE_USE
0010: 5f 56 45 52 53 49 4f 4e 20 32 36 0a 0a 23 69 6e  _VERSION 26..#in
0020: 63 6c 75 64 65 20 3c 73 79 73 2f 66 73 75 69 64  clude <sys/fsuid
0030: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79  .h>.#include <sy
0040: 73 2f 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63 6c  s/types.h>.#incl
0050: 75 64 65 20 3c 70 74 68 72 65 61 64 2e 68 3e 0a  ude <pthread.h>.
0060: 23 69 6e 63 6c 75 64 65 20 3c 73 69 67 6e 61 6c  #include <signal
0070: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74  .h>.#include <st
0080: 72 69 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  ring.h>.#include
0090: 20 3c 73 74 64 61 72 67 2e 68 3e 0a 23 69 6e 63   <stdarg.h>.#inc
00a0: 6c 75 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a  lude <stdlib.h>.
00b0: 23 69 6e 63 6c 75 64 65 20 3c 75 6e 69 73 74 64  #include <unistd
00c0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 65 72  .h>.#include <er
00d0: 72 6e 6f 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  rno.h>.#include 
00e0: 3c 66 63 6e 74 6c 2e 68 3e 0a 23 69 6e 63 6c 75  <fcntl.h>.#inclu
00f0: 64 65 20 3c 73 74 64 69 6f 2e 68 3e 0a 23 69 6e  de <stdio.h>.#in
0100: 63 6c 75 64 65 20 3c 66 75 73 65 2e 68 3e 0a 23  clude <fuse.h>.#
0110: 69 6e 63 6c 75 64 65 20 3c 70 77 64 2e 68 3e 0a  include <pwd.h>.
0120: 23 69 6e 63 6c 75 64 65 20 3c 74 63 6c 2e 68 3e  #include <tcl.h>
0130: 0a 0a 2f 2a 0a 20 2a 20 44 65 66 61 75 6c 74 20  ../*. * Default 
0140: 63 61 63 68 65 20 64 69 72 65 63 74 6f 72 79 0a  cache directory.
0150: 20 2a 2f 0a 23 69 66 6e 64 65 66 20 41 50 50 46   */.#ifndef APPF
0160: 53 5f 43 41 43 48 45 44 49 52 0a 23 64 65 66 69  S_CACHEDIR.#defi
0170: 6e 65 20 41 50 50 46 53 5f 43 41 43 48 45 44 49  ne APPFS_CACHEDI
0180: 52 20 22 2f 76 61 72 2f 63 61 63 68 65 2f 61 70  R "/var/cache/ap
0190: 70 66 73 22 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20  pfs".#endif../* 
01a0: 44 65 62 75 67 67 69 6e 67 20 6d 61 63 72 6f 73  Debugging macros
01b0: 20 2a 2f 0a 23 69 66 64 65 66 20 44 45 42 55 47   */.#ifdef DEBUG
01c0: 0a 23 64 65 66 69 6e 65 20 41 50 50 46 53 5f 44  .#define APPFS_D
01d0: 45 42 55 47 28 78 2e 2e 2e 29 20 7b 20 66 70 72  EBUG(x...) { fpr
01e0: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 5b 64  intf(stderr, "[d
01f0: 65 62 75 67 5d 20 25 73 3a 25 69 3a 25 73 3a 20  ebug] %s:%i:%s: 
0200: 22 2c 20 5f 5f 46 49 4c 45 5f 5f 2c 20 5f 5f 4c  ", __FILE__, __L
0210: 49 4e 45 5f 5f 2c 20 5f 5f 66 75 6e 63 5f 5f 29  INE__, __func__)
0220: 3b 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ; fprintf(stderr
0230: 2c 20 78 29 3b 20 66 70 72 69 6e 74 66 28 73 74  , x); fprintf(st
0240: 64 65 72 72 2c 20 22 5c 6e 22 29 3b 20 7d 0a 23  derr, "\n"); }.#
0250: 65 6c 73 65 0a 23 64 65 66 69 6e 65 20 41 50 50  else.#define APP
0260: 46 53 5f 44 45 42 55 47 28 78 2e 2e 2e 29 20 2f  FS_DEBUG(x...) /
0270: 2a 2a 2f 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 20  **/.#endif../*. 
0280: 2a 20 53 48 41 31 20 54 63 6c 20 50 61 63 6b 61  * SHA1 Tcl Packa
0290: 67 65 20 69 6e 69 74 69 61 6c 69 7a 65 72 2c 20  ge initializer, 
02a0: 66 72 6f 6d 20 73 68 61 31 2e 6f 0a 20 2a 2f 0a  from sha1.o. */.
02b0: 69 6e 74 20 53 68 61 31 5f 49 6e 69 74 28 54 63  int Sha1_Init(Tc
02c0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
02d0: 29 3b 0a 0a 2f 2a 0a 20 2a 20 54 68 72 65 61 64  );../*. * Thread
02e0: 20 53 70 65 63 69 66 69 63 20 44 61 74 61 20 28   Specific Data (
02f0: 54 53 44 29 20 66 6f 72 20 54 63 6c 20 49 6e 74  TSD) for Tcl Int
0300: 65 72 70 72 65 74 65 72 20 66 6f 72 20 74 68 65  erpreter for the
0310: 20 63 75 72 72 65 6e 74 20 74 68 72 65 61 64 0a   current thread.
0320: 20 2a 2f 0a 73 74 61 74 69 63 20 70 74 68 72 65   */.static pthre
0330: 61 64 5f 6b 65 79 5f 74 20 69 6e 74 65 72 70 4b  ad_key_t interpK
0340: 65 79 3b 0a 0a 2f 2a 0a 20 2a 20 47 6c 6f 62 61  ey;../*. * Globa
0350: 6c 20 76 61 72 69 61 62 6c 65 73 2c 20 6e 65 65  l variables, nee
0360: 64 65 64 20 66 6f 72 20 61 6c 6c 20 74 68 72 65  ded for all thre
0370: 61 64 73 20 62 75 74 20 6f 6e 6c 79 20 69 6e 69  ads but only ini
0380: 74 69 61 6c 69 7a 65 64 20 62 65 66 6f 72 65 20  tialized before 
0390: 61 6e 79 0a 20 2a 20 46 55 53 45 20 74 68 72 65  any. * FUSE thre
03a0: 61 64 73 20 61 72 65 20 63 72 65 61 74 65 64 0a  ads are created.
03b0: 20 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 72 20 2a   */.const char *
03c0: 61 70 70 66 73 5f 63 61 63 68 65 64 69 72 3b 0a  appfs_cachedir;.
03d0: 74 69 6d 65 5f 74 20 61 70 70 66 73 5f 62 6f 6f  time_t appfs_boo
03e0: 74 74 69 6d 65 3b 0a 69 6e 74 20 61 70 70 66 73  ttime;.int appfs
03f0: 5f 66 75 73 65 5f 73 74 61 72 74 65 64 20 3d 20  _fuse_started = 
0400: 30 3b 0a 0a 2f 2a 0a 20 2a 20 47 6c 6f 62 61 6c  0;../*. * Global
0410: 20 76 61 72 69 61 62 6c 65 73 20 66 6f 72 20 41   variables for A
0420: 70 70 46 53 20 63 61 63 68 69 6e 67 0a 20 2a 2f  ppFS caching. */
0430: 0a 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 74  .pthread_mutex_t
0440: 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f   appfs_path_info
0450: 5f 63 61 63 68 65 5f 6d 75 74 65 78 20 3d 20 50  _cache_mutex = P
0460: 54 48 52 45 41 44 5f 4d 55 54 45 58 5f 49 4e 49  THREAD_MUTEX_INI
0470: 54 49 41 4c 49 5a 45 52 3b 0a 69 6e 74 20 61 70  TIALIZER;.int ap
0480: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  pfs_path_info_ca
0490: 63 68 65 5f 73 69 7a 65 20 3d 20 38 32 30 39 3b  che_size = 8209;
04a0: 0a 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61  .struct appfs_pa
04b0: 74 68 69 6e 66 6f 20 2a 61 70 70 66 73 5f 70 61  thinfo *appfs_pa
04c0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20  th_info_cache = 
04d0: 4e 55 4c 4c 3b 0a 0a 2f 2a 0a 20 2a 20 47 6c 6f  NULL;../*. * Glo
04e0: 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20 66 6f  bal variables fo
04f0: 72 20 41 70 70 46 53 20 54 63 6c 20 49 6e 74 65  r AppFS Tcl Inte
0500: 72 70 72 65 74 65 72 20 72 65 73 74 61 72 74 69  rpreter restarti
0510: 6e 67 0a 20 2a 2f 0a 69 6e 74 20 69 6e 74 65 72  ng. */.int inter
0520: 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 30 3b  p_reset_key = 0;
0530: 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 20 50 61  ../*. * AppFS Pa
0540: 74 68 20 54 79 70 65 3a 20 20 44 65 73 63 72 69  th Type:  Descri
0550: 62 65 73 20 74 68 65 20 74 79 70 65 20 6f 66 20  bes the type of 
0560: 70 61 74 68 20 61 20 67 69 76 65 6e 20 66 69 6c  path a given fil
0570: 65 20 69 73 0a 20 2a 2f 0a 74 79 70 65 64 65 66  e is. */.typedef
0580: 20 65 6e 75 6d 20 7b 0a 09 41 50 50 46 53 5f 50   enum {..APPFS_P
0590: 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 2c  ATHTYPE_INVALID,
05a0: 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  ..APPFS_PATHTYPE
05b0: 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 2c  _DOES_NOT_EXIST,
05c0: 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  ..APPFS_PATHTYPE
05d0: 5f 46 49 4c 45 2c 0a 09 41 50 50 46 53 5f 50 41  _FILE,..APPFS_PA
05e0: 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59  THTYPE_DIRECTORY
05f0: 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50  ,..APPFS_PATHTYP
0600: 45 5f 53 59 4d 4c 49 4e 4b 2c 0a 09 41 50 50 46  E_SYMLINK,..APPF
0610: 53 5f 50 41 54 48 54 59 50 45 5f 53 4f 43 4b 45  S_PATHTYPE_SOCKE
0620: 54 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59  T,..APPFS_PATHTY
0630: 50 45 5f 46 49 46 4f 2c 0a 7d 20 61 70 70 66 73  PE_FIFO,.} appfs
0640: 5f 70 61 74 68 74 79 70 65 5f 74 3b 0a 0a 2f 2a  _pathtype_t;../*
0650: 0a 20 2a 20 41 70 70 46 53 20 50 61 74 68 20 49  . * AppFS Path I
0660: 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 20 2a 20 20  nformation:. *  
0670: 20 20 20 20 20 20 20 43 6f 6d 70 6c 65 74 65 6c         Completel
0680: 79 20 64 65 73 63 72 69 62 65 73 20 61 20 73 70  y describes a sp
0690: 65 63 69 66 69 63 20 70 61 74 68 2c 20 68 6f 77  ecific path, how
06a0: 20 69 74 20 73 68 6f 75 6c 64 20 62 65 20 72 65   it should be re
06b0: 74 75 72 6e 65 64 20 74 6f 0a 20 2a 20 20 20 20  turned to. *    
06c0: 20 20 20 20 20 74 6f 20 74 68 65 20 6b 65 72 6e       to the kern
06d0: 65 6c 0a 20 2a 2f 0a 73 74 72 75 63 74 20 61 70  el. */.struct ap
06e0: 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 7b 0a 09  pfs_pathinfo {..
06f0: 61 70 70 66 73 5f 70 61 74 68 74 79 70 65 5f 74  appfs_pathtype_t
0700: 20 74 79 70 65 3b 0a 09 74 69 6d 65 5f 74 20 74   type;..time_t t
0710: 69 6d 65 3b 0a 09 63 68 61 72 20 68 6f 73 74 6e  ime;..char hostn
0720: 61 6d 65 5b 32 35 36 5d 3b 0a 09 69 6e 74 20 70  ame[256];..int p
0730: 61 63 6b 61 67 65 64 3b 0a 09 75 6e 73 69 67 6e  ackaged;..unsign
0740: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 20 69 6e 6f  ed long long ino
0750: 64 65 3b 0a 09 75 6e 69 6f 6e 20 7b 0a 09 09 73  de;..union {...s
0760: 74 72 75 63 74 20 7b 0a 09 09 09 69 6e 74 20 63  truct {....int c
0770: 68 69 6c 64 63 6f 75 6e 74 3b 0a 09 09 7d 20 64  hildcount;...} d
0780: 69 72 3b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09  ir;...struct {..
0790: 09 09 69 6e 74 20 65 78 65 63 75 74 61 62 6c 65  ..int executable
07a0: 3b 0a 09 09 09 6f 66 66 5f 74 20 73 69 7a 65 3b  ;....off_t size;
07b0: 0a 09 09 7d 20 66 69 6c 65 3b 0a 09 09 73 74 72  ...} file;...str
07c0: 75 63 74 20 7b 0a 09 09 09 6f 66 66 5f 74 20 73  uct {....off_t s
07d0: 69 7a 65 3b 0a 09 09 09 63 68 61 72 20 73 6f 75  ize;....char sou
07e0: 72 63 65 5b 32 35 36 5d 3b 0a 09 09 7d 20 73 79  rce[256];...} sy
07f0: 6d 6c 69 6e 6b 3b 0a 09 7d 20 74 79 70 65 69 6e  mlink;..} typein
0800: 66 6f 3b 0a 0a 09 2f 2a 20 41 74 74 72 69 62 75  fo;.../* Attribu
0810: 74 65 73 20 75 73 65 64 20 6f 6e 6c 79 20 66 6f  tes used only fo
0820: 72 20 63 61 63 68 69 6e 67 20 65 6e 74 72 69 65  r caching entrie
0830: 73 20 2a 2f 0a 09 63 68 61 72 20 2a 5f 63 61 63  s */..char *_cac
0840: 68 65 5f 70 61 74 68 3b 0a 09 75 69 64 5f 74 20  he_path;..uid_t 
0850: 5f 63 61 63 68 65 5f 75 69 64 3b 0a 7d 3b 0a 0a  _cache_uid;.};..
0860: 2f 2a 0a 20 2a 20 43 72 65 61 74 65 20 61 20 6e  /*. * Create a n
0870: 65 77 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  ew Tcl interpret
0880: 65 72 20 61 6e 64 20 63 6f 6d 70 6c 65 74 65 6c  er and completel
0890: 79 20 69 6e 69 74 69 61 6c 69 7a 65 20 69 74 0a  y initialize it.
08a0: 20 2a 2f 0a 73 74 61 74 69 63 20 54 63 6c 5f 49   */.static Tcl_I
08b0: 6e 74 65 72 70 20 2a 61 70 70 66 73 5f 63 72 65  nterp *appfs_cre
08c0: 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 63 68  ate_TclInterp(ch
08d0: 61 72 20 2a 2a 65 72 72 6f 72 5f 73 74 72 69 6e  ar **error_strin
08e0: 67 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  g) {..Tcl_Interp
08f0: 20 2a 69 6e 74 65 72 70 3b 0a 09 69 6e 74 20 74   *interp;..int t
0900: 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f  cl_ret;...APPFS_
0910: 44 45 42 55 47 28 22 43 72 65 61 74 69 6e 67 20  DEBUG("Creating 
0920: 6e 65 77 20 54 63 6c 20 69 6e 74 65 72 70 72 65  new Tcl interpre
0930: 74 65 72 20 66 6f 72 20 54 49 44 20 3d 20 30 78  ter for TID = 0x
0940: 25 6c 6c 78 22 2c 20 28 75 6e 73 69 67 6e 65 64  %llx", (unsigned
0950: 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 70 74 68 72   long long) pthr
0960: 65 61 64 5f 73 65 6c 66 28 29 29 3b 0a 0a 09 69  ead_self());...i
0970: 6e 74 65 72 70 20 3d 20 54 63 6c 5f 43 72 65 61  nterp = Tcl_Crea
0980: 74 65 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20  teInterp();..if 
0990: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
09a0: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
09b0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
09c0: 63 72 65 61 74 65 20 54 63 6c 20 49 6e 74 65 72  create Tcl Inter
09d0: 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69 6e  preter.  Abortin
09e0: 67 2e 5c 6e 22 29 3b 0a 0a 09 09 69 66 20 28 65  g.\n");....if (e
09f0: 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09  rror_string) {..
0a00: 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20  ..*error_string 
0a10: 3d 20 73 74 72 64 75 70 28 22 55 6e 61 62 6c 65  = strdup("Unable
0a20: 20 74 6f 20 63 72 65 61 74 65 20 54 63 6c 20 69   to create Tcl i
0a30: 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 09  nterpreter.");..
0a40: 09 7d 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  .}....return(NUL
0a50: 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74  L);..}...tcl_ret
0a60: 20 3d 20 54 63 6c 5f 49 6e 69 74 28 69 6e 74 65   = Tcl_Init(inte
0a70: 72 70 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65  rp);..if (tcl_re
0a80: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
0a90: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
0aa0: 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74   "Unable to init
0ab0: 69 61 6c 69 7a 65 20 54 63 6c 2e 20 20 41 62 6f  ialize Tcl.  Abo
0ac0: 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66 70  rting.\n");...fp
0ad0: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54  rintf(stderr, "T
0ae0: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c  cl Error is: %s\
0af0: 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  n", Tcl_GetStrin
0b00: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
0b10: 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73  ;....if (error_s
0b20: 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72 72  tring) {....*err
0b30: 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64  or_string = strd
0b40: 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  up(Tcl_GetString
0b50: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
0b60: 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44 65 6c 65  ...}....Tcl_Dele
0b70: 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29  teInterp(interp)
0b80: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c  ;....return(NULL
0b90: 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20  );..}...tcl_ret 
0ba0: 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  = Tcl_Eval(inter
0bb0: 70 2c 20 22 70 61 63 6b 61 67 65 20 69 66 6e 65  p, "package ifne
0bc0: 65 64 65 64 20 73 68 61 31 20 31 2e 30 20 5b 6c  eded sha1 1.0 [l
0bd0: 69 73 74 20 6c 6f 61 64 20 7b 7d 20 73 68 61 31  ist load {} sha1
0be0: 5d 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65  ]");..if (tcl_re
0bf0: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09  t != TCL_OK) {..
0c00: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
0c10: 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74   "Unable to init
0c20: 69 61 6c 69 7a 65 20 54 63 6c 20 53 48 41 31 2e  ialize Tcl SHA1.
0c30: 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b    Aborting.\n");
0c40: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
0c50: 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73  r, "Tcl Error is
0c60: 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74  : %s\n", Tcl_Get
0c70: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
0c80: 65 72 70 29 29 3b 0a 0a 09 09 69 66 20 28 65 72  erp));....if (er
0c90: 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09  ror_string) {...
0ca0: 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d  .*error_string =
0cb0: 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53   strdup(Tcl_GetS
0cc0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
0cd0: 72 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c  rp));...}....Tcl
0ce0: 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e  _DeleteInterp(in
0cf0: 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e  terp);....return
0d00: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c  (NULL);..}...tcl
0d10: 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28  _ret = Tcl_Eval(
0d20: 69 6e 74 65 72 70 2c 20 22 70 61 63 6b 61 67 65  interp, "package
0d30: 20 69 66 6e 65 65 64 65 64 20 61 70 70 66 73 64   ifneeded appfsd
0d40: 20 31 2e 30 20 5b 6c 69 73 74 20 6c 6f 61 64 20   1.0 [list load 
0d50: 7b 7d 20 61 70 70 66 73 64 5d 22 29 3b 0a 09 69  {} appfsd]");..i
0d60: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
0d70: 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74  L_OK) {...fprint
0d80: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
0d90: 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20  e to initialize 
0da0: 54 63 6c 20 41 70 70 46 53 20 50 61 63 6b 61 67  Tcl AppFS Packag
0db0: 65 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22  e.  Aborting.\n"
0dc0: 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64  );...fprintf(std
0dd0: 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20  err, "Tcl Error 
0de0: 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47  is: %s\n", Tcl_G
0df0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
0e00: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 69 66 20 28  nterp));....if (
0e10: 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a  error_string) {.
0e20: 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67  ...*error_string
0e30: 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65   = strdup(Tcl_Ge
0e40: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
0e50: 74 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54  terp));...}....T
0e60: 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28  cl_DeleteInterp(
0e70: 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75  interp);....retu
0e80: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f  rn(NULL);..}.../
0e90: 2a 0a 09 20 2a 20 4c 6f 61 64 20 22 70 6b 69 2e  *.. * Load "pki.
0ea0: 74 63 6c 22 20 69 6e 20 74 68 65 20 73 61 6d 65  tcl" in the same
0eb0: 20 77 61 79 20 61 73 20 61 70 70 66 73 64 2e 74   way as appfsd.t
0ec0: 63 6c 20 28 73 65 65 20 62 65 6c 6f 77 29 0a 09  cl (see below)..
0ed0: 20 2a 2f 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54   */..tcl_ret = T
0ee0: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
0ef0: 22 22 0a 23 69 6e 63 6c 75 64 65 20 22 70 6b 69  "".#include "pki
0f00: 2e 74 63 6c 2e 68 22 0a 09 22 22 29 3b 0a 09 69  .tcl.h".."");..i
0f10: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
0f20: 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74  L_OK) {...fprint
0f30: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
0f40: 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20  e to initialize 
0f50: 54 63 6c 20 50 4b 49 2e 20 20 41 62 6f 72 74 69  Tcl PKI.  Aborti
0f60: 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e  ng.\n");...fprin
0f70: 74 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20  tf(stderr, "Tcl 
0f80: 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c  Error is: %s\n",
0f90: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
0fa0: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a  sult(interp));..
0fb0: 09 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69  ..if (error_stri
0fc0: 6e 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f  ng) {....*error_
0fd0: 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28  string = strdup(
0fe0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
0ff0: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
1000: 7d 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49  }....Tcl_DeleteI
1010: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a  nterp(interp);..
1020: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
1030: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4c 6f 61 64  .}.../*.. * Load
1040: 20 74 68 65 20 22 61 70 70 66 73 64 2e 74 63 6c   the "appfsd.tcl
1050: 22 20 73 63 72 69 70 74 2c 20 77 68 69 63 68 20  " script, which 
1060: 69 73 20 22 63 6f 6d 70 69 6c 65 64 22 20 69 6e  is "compiled" in
1070: 74 6f 20 61 20 43 20 68 65 61 64 65 72 0a 09 20  to a C header.. 
1080: 2a 20 73 6f 20 74 68 61 74 20 69 74 20 64 6f 65  * so that it doe
1090: 73 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 65 78  s not need to ex
10a0: 69 73 74 20 6f 6e 20 74 68 65 20 66 69 6c 65 73  ist on the files
10b0: 79 73 74 65 6d 20 61 6e 64 20 63 61 6e 20 62 65  ystem and can be
10c0: 0a 09 20 2a 20 64 69 72 65 63 74 6c 79 20 65 76  .. * directly ev
10d0: 61 6c 75 61 74 65 64 2e 0a 09 20 2a 2f 0a 09 74  aluated... */..t
10e0: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61  cl_ret = Tcl_Eva
10f0: 6c 28 69 6e 74 65 72 70 2c 20 22 22 0a 23 69 6e  l(interp, "".#in
1100: 63 6c 75 64 65 20 22 61 70 70 66 73 64 2e 74 63  clude "appfsd.tc
1110: 6c 2e 68 22 0a 09 22 22 29 3b 0a 09 69 66 20 28  l.h".."");..if (
1120: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
1130: 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73  K) {...fprintf(s
1140: 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74  tderr, "Unable t
1150: 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c  o initialize Tcl
1160: 20 41 70 70 46 53 20 73 63 72 69 70 74 2e 20 20   AppFS script.  
1170: 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09  Aborting.\n");..
1180: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
1190: 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20   "Tcl Error is: 
11a0: 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74  %s\n", Tcl_GetSt
11b0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
11c0: 70 29 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f  p));....if (erro
11d0: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a  r_string) {....*
11e0: 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73  error_string = s
11f0: 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72  trdup(Tcl_GetStr
1200: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
1210: 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44  ));...}....Tcl_D
1220: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65  eleteInterp(inte
1230: 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e  rp);....return(N
1240: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  ULL);..}.../*.. 
1250: 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72  * Set global var
1260: 69 61 62 6c 65 73 20 66 72 6f 6d 20 43 20 74 6f  iables from C to
1270: 20 54 63 6c 0a 09 20 2a 2f 0a 09 69 66 20 28 54   Tcl.. */..if (T
1280: 63 6c 5f 53 65 74 56 61 72 28 69 6e 74 65 72 70  cl_SetVar(interp
1290: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 63 61 63 68  , "::appfs::cach
12a0: 65 64 69 72 22 2c 20 61 70 70 66 73 5f 63 61 63  edir", appfs_cac
12b0: 68 65 64 69 72 2c 20 54 43 4c 5f 47 4c 4f 42 41  hedir, TCL_GLOBA
12c0: 4c 5f 4f 4e 4c 59 29 20 3d 3d 20 4e 55 4c 4c 29  L_ONLY) == NULL)
12d0: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
12e0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
12f0: 73 65 74 20 63 61 63 68 65 20 64 69 72 65 63 74  set cache direct
1300: 6f 72 79 2e 20 20 54 68 69 73 20 73 68 6f 75 6c  ory.  This shoul
1310: 64 20 6e 65 76 65 72 20 66 61 69 6c 2e 5c 6e 22  d never fail.\n"
1320: 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f  );....if (error_
1330: 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72  string) {....*er
1340: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72  ror_string = str
1350: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e  dup(Tcl_GetStrin
1360: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
1370: 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44 65 6c  ;...}....Tcl_Del
1380: 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70  eteInterp(interp
1390: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  );....return(NUL
13a0: 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20  L);..}.../*.. * 
13b0: 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 22  Initialize the "
13c0: 61 70 70 66 73 64 2e 74 63 6c 22 20 65 6e 76 69  appfsd.tcl" envi
13d0: 72 6f 6e 6d 65 6e 74 2c 20 77 68 69 63 68 20 6d  ronment, which m
13e0: 75 73 74 20 62 65 20 64 6f 6e 65 20 61 66 74 65  ust be done afte
13f0: 72 0a 09 20 2a 20 67 6c 6f 62 61 6c 20 76 61 72  r.. * global var
1400: 69 61 62 6c 65 73 20 61 72 65 20 73 65 74 2e 0a  iables are set..
1410: 09 20 2a 2f 0a 09 74 63 6c 5f 72 65 74 20 3d 20  . */..tcl_ret = 
1420: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
1430: 20 22 3a 3a 61 70 70 66 73 3a 3a 69 6e 69 74 22   "::appfs::init"
1440: 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  );..if (tcl_ret 
1450: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66  != TCL_OK) {...f
1460: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
1470: 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61  Unable to initia
1480: 6c 69 7a 65 20 54 63 6c 20 41 70 70 46 53 20 73  lize Tcl AppFS s
1490: 63 72 69 70 74 20 28 3a 3a 61 70 70 66 73 3a 3a  cript (::appfs::
14a0: 69 6e 69 74 29 2e 20 20 41 62 6f 72 74 69 6e 67  init).  Aborting
14b0: 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66  .\n");...fprintf
14c0: 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45 72  (stderr, "Tcl Er
14d0: 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54  ror is: %s\n", T
14e0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
14f0: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09  lt(interp));....
1500: 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67  if (error_string
1510: 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73 74  ) {....*error_st
1520: 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63  ring = strdup(Tc
1530: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
1540: 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 7d 0a  t(interp));...}.
1550: 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74  ...Tcl_DeleteInt
1560: 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09  erp(interp);....
1570: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
1580: 0a 0a 09 2f 2a 0a 09 20 2a 20 48 69 64 65 20 73  .../*.. * Hide s
1590: 6f 6d 65 20 54 63 6c 20 63 6f 6d 6d 61 6e 64 73  ome Tcl commands
15a0: 20 74 68 61 74 20 77 65 20 64 6f 20 6e 6f 74 20   that we do not 
15b0: 63 61 72 65 20 74 6f 20 75 73 65 20 61 6e 64 20  care to use and 
15c0: 77 68 69 63 68 20 6d 61 79 0a 09 20 2a 20 73 6c  which may.. * sl
15d0: 6f 77 20 64 6f 77 6e 20 72 75 6e 2d 74 69 6d 65  ow down run-time
15e0: 20 6f 70 65 72 61 74 69 6f 6e 73 2e 0a 09 20 2a   operations... *
15f0: 2f 0a 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61  /..Tcl_HideComma
1600: 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 75 74 6f  nd(interp, "auto
1610: 5f 6c 6f 61 64 5f 69 6e 64 65 78 22 2c 20 22 61  _load_index", "a
1620: 75 74 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22 29  uto_load_index")
1630: 3b 0a 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61  ;..Tcl_HideComma
1640: 6e 64 28 69 6e 74 65 72 70 2c 20 22 75 6e 6b 6e  nd(interp, "unkn
1650: 6f 77 6e 22 2c 20 22 75 6e 6b 6e 6f 77 6e 22 29  own", "unknown")
1660: 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 74 75 72  ;.../*.. * Retur
1670: 6e 20 74 68 65 20 63 6f 6d 70 6c 65 74 65 6c 79  n the completely
1680: 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 69 6e 74   initialized int
1690: 65 72 70 72 65 74 65 72 0a 09 20 2a 2f 0a 09 72  erpreter.. */..r
16a0: 65 74 75 72 6e 28 69 6e 74 65 72 70 29 3b 0a 7d  eturn(interp);.}
16b0: 0a 0a 2f 2a 0a 20 2a 20 52 65 74 75 72 6e 20 74  ../*. * Return t
16c0: 68 65 20 74 68 72 65 61 64 2d 73 70 65 63 69 66  he thread-specif
16d0: 69 63 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  ic Tcl interpret
16e0: 65 72 2c 20 63 72 65 61 74 69 6e 67 20 69 74 20  er, creating it 
16f0: 69 66 20 6e 65 65 64 65 64 0a 20 2a 2f 0a 73 74  if needed. */.st
1700: 61 74 69 63 20 54 63 6c 5f 49 6e 74 65 72 70 20  atic Tcl_Interp 
1710: 2a 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70  *appfs_TclInterp
1720: 28 76 6f 69 64 29 20 7b 0a 09 54 63 6c 5f 49 6e  (void) {..Tcl_In
1730: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 69  terp *interp;..i
1740: 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a  nt pthread_ret;.
1750: 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64  .static __thread
1760: 20 69 6e 74 20 74 68 72 65 61 64 5f 69 6e 74 65   int thread_inte
1770: 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 30  rp_reset_key = 0
1780: 3b 0a 09 69 6e 74 20 67 6c 6f 62 61 6c 5f 69 6e  ;..int global_in
1790: 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 3b 0a  terp_reset_key;.
17a0: 0a 09 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f  ..global_interp_
17b0: 72 65 73 65 74 5f 6b 65 79 20 3d 20 5f 5f 73 79  reset_key = __sy
17c0: 6e 63 5f 66 65 74 63 68 5f 61 6e 64 5f 61 64 64  nc_fetch_and_add
17d0: 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b  (&interp_reset_k
17e0: 65 79 2c 20 30 29 3b 0a 0a 09 69 6e 74 65 72 70  ey, 0);...interp
17f0: 20 3d 20 70 74 68 72 65 61 64 5f 67 65 74 73 70   = pthread_getsp
1800: 65 63 69 66 69 63 28 69 6e 74 65 72 70 4b 65 79  ecific(interpKey
1810: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 21  );..if (interp !
1820: 3d 20 4e 55 4c 4c 20 26 26 20 74 68 72 65 61 64  = NULL && thread
1830: 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65  _interp_reset_ke
1840: 79 20 21 3d 20 67 6c 6f 62 61 6c 5f 69 6e 74 65  y != global_inte
1850: 72 70 5f 72 65 73 65 74 5f 6b 65 79 29 20 7b 0a  rp_reset_key) {.
1860: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
1870: 65 72 6d 69 6e 61 74 69 6e 67 20 6f 6c 64 20 69  erminating old i
1880: 6e 74 65 72 70 72 65 74 65 72 20 61 6e 64 20 72  nterpreter and r
1890: 65 73 74 61 72 74 69 6e 67 20 64 75 65 20 74 6f  estarting due to
18a0: 20 72 65 73 65 74 20 72 65 71 75 65 73 74 2e 22   reset request."
18b0: 29 3b 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65  );....Tcl_Delete
18c0: 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a  Interp(interp);.
18d0: 0a 09 09 69 6e 74 65 72 70 20 3d 20 4e 55 4c 4c  ...interp = NULL
18e0: 3b 0a 0a 09 09 74 68 72 65 61 64 5f 69 6e 74 65  ;....thread_inte
18f0: 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 3d 20 67  rp_reset_key = g
1900: 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73  lobal_interp_res
1910: 65 74 5f 6b 65 79 3b 0a 09 7d 0a 0a 09 69 66 20  et_key;..}...if 
1920: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29  (interp == NULL)
1930: 20 7b 0a 09 09 69 6e 74 65 72 70 20 3d 20 61 70   {...interp = ap
1940: 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e  pfs_create_TclIn
1950: 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 0a 09 09 69  terp(NULL);....i
1960: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c  f (interp == NUL
1970: 4c 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 4e  L) {....return(N
1980: 55 4c 4c 29 3b 0a 09 09 7d 0a 0a 09 09 70 74 68  ULL);...}....pth
1990: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
19a0: 61 64 5f 73 65 74 73 70 65 63 69 66 69 63 28 69  ad_setspecific(i
19b0: 6e 74 65 72 70 4b 65 79 2c 20 69 6e 74 65 72 70  nterpKey, interp
19c0: 29 3b 0a 09 09 69 66 20 28 70 74 68 72 65 61 64  );...if (pthread
19d0: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09  _ret != 0) {....
19e0: 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70  Tcl_DeleteInterp
19f0: 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 09 72 65  (interp);.....re
1a00: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a  turn(NULL);...}.
1a10: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 69 6e 74 65  .}...return(inte
1a20: 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 76  rp);.}../*. * Ev
1a30: 61 6c 75 61 74 65 20 61 20 54 63 6c 20 73 63 72  aluate a Tcl scr
1a40: 69 70 74 20 63 6f 6e 73 74 72 75 63 74 65 64 20  ipt constructed 
1a50: 62 79 20 63 6f 6e 63 61 74 65 6e 61 74 69 6e 67  by concatenating
1a60: 20 61 20 62 75 6e 63 68 20 6f 66 20 43 20 73 74   a bunch of C st
1a70: 72 69 6e 67 73 0a 20 2a 20 74 6f 67 65 74 68 65  rings. * togethe
1a80: 72 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  r.. */.static in
1a90: 74 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c  t appfs_Tcl_Eval
1aa0: 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  (Tcl_Interp *int
1ab0: 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 63  erp, int objc, c
1ac0: 6f 6e 73 74 20 63 68 61 72 20 2a 63 6d 64 2c 20  onst char *cmd, 
1ad0: 2e 2e 2e 29 20 7b 0a 09 54 63 6c 5f 4f 62 6a 20  ...) {..Tcl_Obj 
1ae0: 2a 2a 6f 62 6a 76 3b 0a 09 63 6f 6e 73 74 20 63  **objv;..const c
1af0: 68 61 72 20 2a 61 72 67 3b 0a 09 76 61 5f 6c 69  har *arg;..va_li
1b00: 73 74 20 61 72 67 70 3b 0a 09 69 6e 74 20 72 65  st argp;..int re
1b10: 74 76 61 6c 3b 0a 09 69 6e 74 20 69 3b 0a 0a 09  tval;..int i;...
1b20: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
1b30: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 54  LL) {...return(T
1b40: 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09  CL_ERROR);..}...
1b50: 6f 62 6a 76 20 3d 20 28 76 6f 69 64 20 2a 29 20  objv = (void *) 
1b60: 63 6b 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 2a  ckalloc(sizeof(*
1b70: 6f 62 6a 76 29 20 2a 20 6f 62 6a 63 29 3b 0a 09  objv) * objc);..
1b80: 6f 62 6a 76 5b 30 5d 20 3d 20 54 63 6c 5f 4e 65  objv[0] = Tcl_Ne
1b90: 77 53 74 72 69 6e 67 4f 62 6a 28 63 6d 64 2c 20  wStringObj(cmd, 
1ba0: 2d 31 29 3b 0a 09 54 63 6c 5f 49 6e 63 72 52 65  -1);..Tcl_IncrRe
1bb0: 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 30 5d 29 3b  fCount(objv[0]);
1bc0: 0a 0a 09 76 61 5f 73 74 61 72 74 28 61 72 67 70  ...va_start(argp
1bd0: 2c 20 63 6d 64 29 3b 0a 09 66 6f 72 20 28 69 20  , cmd);..for (i 
1be0: 3d 20 31 3b 20 69 20 3c 20 6f 62 6a 63 3b 20 69  = 1; i < objc; i
1bf0: 2b 2b 29 20 7b 0a 09 09 61 72 67 20 3d 20 76 61  ++) {...arg = va
1c00: 5f 61 72 67 28 61 72 67 70 2c 20 63 6f 6e 73 74  _arg(argp, const
1c10: 20 63 68 61 72 20 2a 29 3b 0a 09 09 6f 62 6a 76   char *);...objv
1c20: 5b 69 5d 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72  [i] = Tcl_NewStr
1c30: 69 6e 67 4f 62 6a 28 61 72 67 2c 20 2d 31 29 3b  ingObj(arg, -1);
1c40: 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f  ...Tcl_IncrRefCo
1c50: 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09 7d  unt(objv[i]);..}
1c60: 0a 09 76 61 5f 65 6e 64 28 61 72 67 70 29 3b 0a  ..va_end(argp);.
1c70: 0a 09 72 65 74 76 61 6c 20 3d 20 54 63 6c 5f 45  ..retval = Tcl_E
1c80: 76 61 6c 4f 62 6a 76 28 69 6e 74 65 72 70 2c 20  valObjv(interp, 
1c90: 6f 62 6a 63 2c 20 6f 62 6a 76 2c 20 30 29 3b 0a  objc, objv, 0);.
1ca0: 0a 09 66 6f 72 20 28 69 20 3d 20 30 3b 20 69 20  ..for (i = 0; i 
1cb0: 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09  < objc; i++) {..
1cc0: 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e  .Tcl_DecrRefCoun
1cd0: 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09 7d 0a 0a  t(objv[i]);..}..
1ce0: 09 63 6b 66 72 65 65 28 28 76 6f 69 64 20 2a 29  .ckfree((void *)
1cf0: 20 6f 62 6a 76 29 3b 0a 0a 09 69 66 20 28 72 65   objv);...if (re
1d00: 74 76 61 6c 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  tval != TCL_OK) 
1d10: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
1d20: 22 54 63 6c 20 63 6f 6d 6d 61 6e 64 20 66 61 69  "Tcl command fai
1d30: 6c 65 64 2c 20 3a 3a 65 72 72 6f 72 49 6e 66 6f  led, ::errorInfo
1d40: 20 63 6f 6e 74 61 69 6e 73 3a 20 25 73 5c 6e 22   contains: %s\n"
1d50: 2c 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74  , Tcl_GetVar(int
1d60: 65 72 70 2c 20 22 3a 3a 65 72 72 6f 72 49 6e 66  erp, "::errorInf
1d70: 6f 22 2c 20 30 29 29 3b 0a 09 7d 0a 0a 09 72 65  o", 0));..}...re
1d80: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a  turn(retval);.}.
1d90: 0a 2f 2a 0a 20 2a 20 52 65 71 75 65 73 74 20 61  ./*. * Request a
1da0: 6c 6c 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  ll Tcl interpret
1db0: 65 72 73 20 72 65 73 74 61 72 74 0a 20 2a 2f 0a  ers restart. */.
1dc0: 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66  static void appf
1dd0: 73 5f 74 63 6c 5f 52 65 73 65 74 49 6e 74 65 72  s_tcl_ResetInter
1de0: 70 73 28 76 6f 69 64 29 20 7b 0a 09 41 50 50 46  ps(void) {..APPF
1df0: 53 5f 44 45 42 55 47 28 22 52 65 71 75 65 73 74  S_DEBUG("Request
1e00: 69 6e 67 20 72 65 73 65 74 20 6f 66 20 61 6c 6c  ing reset of all
1e10: 20 69 6e 74 65 72 70 72 65 74 65 72 73 2e 22 29   interpreters.")
1e20: 3b 0a 0a 09 5f 5f 73 79 6e 63 5f 61 64 64 5f 61  ;...__sync_add_a
1e30: 6e 64 5f 66 65 74 63 68 28 26 69 6e 74 65 72 70  nd_fetch(&interp
1e40: 5f 72 65 73 65 74 5f 6b 65 79 2c 20 31 29 3b 0a  _reset_key, 1);.
1e50: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a  ..return;.}../*.
1e60: 20 2a 20 44 65 74 65 72 6d 69 6e 65 20 74 68 65   * Determine the
1e70: 20 55 49 44 20 66 6f 72 20 74 68 65 20 75 73 65   UID for the use
1e80: 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 63 75 72  r making the cur
1e90: 72 65 6e 74 20 46 55 53 45 20 66 69 6c 65 73 79  rent FUSE filesy
1ea0: 73 74 65 6d 20 72 65 71 75 65 73 74 2e 0a 20 2a  stem request.. *
1eb0: 20 54 68 69 73 20 77 69 6c 6c 20 62 65 20 75 73   This will be us
1ec0: 65 64 20 74 6f 20 6c 6f 6f 6b 75 70 20 74 68 65  ed to lookup the
1ed0: 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64 69 72   user's home dir
1ee0: 65 63 74 6f 72 79 20 73 6f 20 77 65 20 63 61 6e  ectory so we can
1ef0: 20 73 65 61 72 63 68 20 66 6f 72 0a 20 2a 20 6c   search for. * l
1f00: 6f 63 61 6c 6c 79 20 6d 6f 64 69 66 69 65 64 20  ocally modified 
1f10: 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73 74 61 74 69  files.. */.stati
1f20: 63 20 75 69 64 5f 74 20 61 70 70 66 73 5f 67 65  c uid_t appfs_ge
1f30: 74 5f 66 73 75 69 64 28 76 6f 69 64 29 20 7b 0a  t_fsuid(void) {.
1f40: 09 73 74 72 75 63 74 20 66 75 73 65 5f 63 6f 6e  .struct fuse_con
1f50: 74 65 78 74 20 2a 63 74 78 3b 0a 0a 09 69 66 20  text *ctx;...if 
1f60: 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61  (!appfs_fuse_sta
1f70: 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75 72 6e  rted) {...return
1f80: 28 67 65 74 75 69 64 28 29 29 3b 0a 09 7d 0a 0a  (getuid());..}..
1f90: 09 63 74 78 20 3d 20 66 75 73 65 5f 67 65 74 5f  .ctx = fuse_get_
1fa0: 63 6f 6e 74 65 78 74 28 29 3b 0a 09 69 66 20 28  context();..if (
1fb0: 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ctx == NULL) {..
1fc0: 09 2f 2a 20 55 6e 61 62 6c 65 20 74 6f 20 6c 6f  ./* Unable to lo
1fd0: 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20 73 6f  okup user for so
1fe0: 6d 65 20 72 65 61 73 6f 6e 20 2a 2f 0a 09 09 2f  me reason */.../
1ff0: 2a 20 52 65 74 75 72 6e 20 61 6e 20 75 6e 70 72  * Return an unpr
2000: 69 76 69 6c 65 67 65 64 20 75 73 65 72 20 49 44  ivileged user ID
2010: 20 2a 2f 0a 09 09 72 65 74 75 72 6e 28 31 29 3b   */...return(1);
2020: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 63 74 78  ..}...return(ctx
2030: 2d 3e 75 69 64 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  ->uid);.}../*. *
2040: 20 44 65 74 65 72 6d 69 6e 65 20 74 68 65 20 47   Determine the G
2050: 49 44 20 66 6f 72 20 74 68 65 20 75 73 65 72 20  ID for the user 
2060: 6d 61 6b 69 6e 67 20 74 68 65 20 63 75 72 72 65  making the curre
2070: 6e 74 20 46 55 53 45 20 66 69 6c 65 73 79 73 74  nt FUSE filesyst
2080: 65 6d 20 72 65 71 75 65 73 74 2e 0a 20 2a 20 54  em request.. * T
2090: 68 69 73 20 77 69 6c 6c 20 62 65 20 75 73 65 64  his will be used
20a0: 20 74 6f 20 6c 6f 6f 6b 75 70 20 74 68 65 20 75   to lookup the u
20b0: 73 65 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63  ser's home direc
20c0: 74 6f 72 79 20 73 6f 20 77 65 20 63 61 6e 20 73  tory so we can s
20d0: 65 61 72 63 68 20 66 6f 72 0a 20 2a 20 6c 6f 63  earch for. * loc
20e0: 61 6c 6c 79 20 6d 6f 64 69 66 69 65 64 20 66 69  ally modified fi
20f0: 6c 65 73 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20  les.. */.static 
2100: 67 69 64 5f 74 20 61 70 70 66 73 5f 67 65 74 5f  gid_t appfs_get_
2110: 66 73 67 69 64 28 76 6f 69 64 29 20 7b 0a 09 73  fsgid(void) {..s
2120: 74 72 75 63 74 20 66 75 73 65 5f 63 6f 6e 74 65  truct fuse_conte
2130: 78 74 20 2a 63 74 78 3b 0a 0a 09 69 66 20 28 21  xt *ctx;...if (!
2140: 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74  appfs_fuse_start
2150: 65 64 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 67  ed) {...return(g
2160: 65 74 67 69 64 28 29 29 3b 0a 09 7d 0a 0a 09 63  etgid());..}...c
2170: 74 78 20 3d 20 66 75 73 65 5f 67 65 74 5f 63 6f  tx = fuse_get_co
2180: 6e 74 65 78 74 28 29 3b 0a 09 69 66 20 28 63 74  ntext();..if (ct
2190: 78 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2f  x == NULL) {.../
21a0: 2a 20 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b  * Unable to look
21b0: 75 70 20 75 73 65 72 20 66 6f 72 20 73 6f 6d 65  up user for some
21c0: 20 72 65 61 73 6f 6e 20 2a 2f 0a 09 09 2f 2a 20   reason */.../* 
21d0: 52 65 74 75 72 6e 20 61 6e 20 75 6e 70 72 69 76  Return an unpriv
21e0: 69 6c 65 67 65 64 20 75 73 65 72 20 49 44 20 2a  ileged user ID *
21f0: 2f 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  /...return(1);..
2200: 7d 0a 0a 09 72 65 74 75 72 6e 28 63 74 78 2d 3e  }...return(ctx->
2210: 67 69 64 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  gid);.}..static 
2220: 76 6f 69 64 20 61 70 70 66 73 5f 73 69 6d 75 6c  void appfs_simul
2230: 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65  ate_user_fs_ente
2240: 72 28 76 6f 69 64 29 20 7b 0a 09 73 65 74 66 73  r(void) {..setfs
2250: 75 69 64 28 61 70 70 66 73 5f 67 65 74 5f 66 73  uid(appfs_get_fs
2260: 75 69 64 28 29 29 3b 0a 09 73 65 74 66 73 67 69  uid());..setfsgi
2270: 64 28 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69  d(appfs_get_fsgi
2280: 64 28 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  d());.}..static 
2290: 76 6f 69 64 20 61 70 70 66 73 5f 73 69 6d 75 6c  void appfs_simul
22a0: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76  ate_user_fs_leav
22b0: 65 28 76 6f 69 64 29 20 7b 0a 09 73 65 74 66 73  e(void) {..setfs
22c0: 75 69 64 28 30 29 3b 0a 09 73 65 74 66 73 67 69  uid(0);..setfsgi
22d0: 64 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 4c  d(0);.}../*. * L
22e0: 6f 6f 6b 20 75 70 20 74 68 65 20 68 6f 6d 65 20  ook up the home 
22f0: 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20 61 20  directory for a 
2300: 67 69 76 65 6e 20 55 49 44 0a 20 2a 20 20 20 20  given UID. *    
2310: 20 20 20 20 52 65 74 75 72 6e 73 20 61 20 43 20      Returns a C 
2320: 73 74 72 69 6e 67 20 63 6f 6e 74 61 69 6e 69 6e  string containin
2330: 67 20 74 68 65 20 75 73 65 72 27 73 20 68 6f 6d  g the user's hom
2340: 65 20 64 69 72 65 63 74 6f 72 79 20 6f 72 20 4e  e directory or N
2350: 55 4c 4c 20 69 66 0a 20 2a 20 20 20 20 20 20 20  ULL if. *       
2360: 20 74 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65   the user's home
2370: 20 64 69 72 65 63 74 6f 72 79 20 64 6f 65 73 20   directory does 
2380: 6e 6f 74 20 65 78 69 73 74 20 6f 72 20 69 73 20  not exist or is 
2390: 6e 6f 74 20 63 6f 72 72 65 63 74 6c 79 0a 20 2a  not correctly. *
23a0: 20 20 20 20 20 20 20 20 63 6f 6e 66 69 67 75 72          configur
23b0: 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 63 68  ed. */.static ch
23c0: 61 72 20 2a 61 70 70 66 73 5f 67 65 74 5f 68 6f  ar *appfs_get_ho
23d0: 6d 65 64 69 72 28 75 69 64 5f 74 20 66 73 75 69  medir(uid_t fsui
23e0: 64 29 20 7b 0a 09 73 74 72 75 63 74 20 70 61 73  d) {..struct pas
23f0: 73 77 64 20 65 6e 74 72 79 2c 20 2a 72 65 73 75  swd entry, *resu
2400: 6c 74 3b 0a 09 73 74 72 75 63 74 20 73 74 61 74  lt;..struct stat
2410: 20 73 74 62 75 66 3b 0a 09 63 68 61 72 20 62 75   stbuf;..char bu
2420: 66 5b 31 30 32 34 5d 2c 20 2a 72 65 74 76 61 6c  f[1024], *retval
2430: 3b 0a 09 69 6e 74 20 67 70 75 5f 72 65 74 2c 20  ;..int gpu_ret, 
2440: 73 74 61 74 5f 72 65 74 3b 0a 0a 09 67 70 75 5f  stat_ret;...gpu_
2450: 72 65 74 20 3d 20 67 65 74 70 77 75 69 64 5f 72  ret = getpwuid_r
2460: 28 66 73 75 69 64 2c 20 26 65 6e 74 72 79 2c 20  (fsuid, &entry, 
2470: 62 75 66 2c 20 73 69 7a 65 6f 66 28 62 75 66 29  buf, sizeof(buf)
2480: 2c 20 26 72 65 73 75 6c 74 29 3b 0a 09 69 66 20  , &result);..if 
2490: 28 67 70 75 5f 72 65 74 20 21 3d 20 30 29 20 7b  (gpu_ret != 0) {
24a0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
24b0: 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c  getpwuid_r(%llu,
24c0: 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64 20 69   ...) returned i
24d0: 6e 20 66 61 69 6c 75 72 65 22 2c 20 28 75 6e 73  n failure", (uns
24e0: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29  igned long long)
24f0: 20 66 73 75 69 64 29 3b 0a 0a 09 09 72 65 74 75   fsuid);....retu
2500: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69  rn(NULL);..}...i
2510: 66 20 28 72 65 73 75 6c 74 20 3d 3d 20 4e 55 4c  f (result == NUL
2520: 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  L) {...APPFS_DEB
2530: 55 47 28 22 67 65 74 70 77 75 69 64 5f 72 28 25  UG("getpwuid_r(%
2540: 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e  llu, ...) return
2550: 65 64 20 4e 55 4c 4c 20 72 65 73 75 6c 74 22 2c  ed NULL result",
2560: 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20   (unsigned long 
2570: 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b 0a 0a 09  long) fsuid);...
2580: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
2590: 7d 0a 0a 09 69 66 20 28 72 65 73 75 6c 74 2d 3e  }...if (result->
25a0: 70 77 5f 64 69 72 20 3d 3d 20 4e 55 4c 4c 29 20  pw_dir == NULL) 
25b0: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  {...APPFS_DEBUG(
25c0: 22 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c 75  "getpwuid_r(%llu
25d0: 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64 20  , ...) returned 
25e0: 4e 55 4c 4c 20 68 6f 6d 65 20 64 69 72 65 63 74  NULL home direct
25f0: 6f 72 79 22 2c 20 28 75 6e 73 69 67 6e 65 64 20  ory", (unsigned 
2600: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64  long long) fsuid
2610: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  );....return(NUL
2620: 4c 29 3b 0a 09 7d 0a 0a 09 73 74 61 74 5f 72 65  L);..}...stat_re
2630: 74 20 3d 20 73 74 61 74 28 72 65 73 75 6c 74 2d  t = stat(result-
2640: 3e 70 77 5f 64 69 72 2c 20 26 73 74 62 75 66 29  >pw_dir, &stbuf)
2650: 3b 0a 09 69 66 20 28 73 74 61 74 5f 72 65 74 20  ;..if (stat_ret 
2660: 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f  != 0) {...APPFS_
2670: 44 45 42 55 47 28 22 73 74 61 74 28 25 73 29 20  DEBUG("stat(%s) 
2680: 72 65 74 75 72 6e 65 64 20 69 6e 20 66 61 69 6c  returned in fail
2690: 75 72 65 22 2c 20 72 65 73 75 6c 74 2d 3e 70 77  ure", result->pw
26a0: 5f 64 69 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e  _dir);....return
26b0: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20  (NULL);..}...if 
26c0: 28 73 74 62 75 66 2e 73 74 5f 75 69 64 20 21 3d  (stbuf.st_uid !=
26d0: 20 66 73 75 69 64 29 20 7b 0a 09 09 41 50 50 46   fsuid) {...APPF
26e0: 53 5f 44 45 42 55 47 28 22 55 49 44 20 6d 69 73  S_DEBUG("UID mis
26f0: 2d 6d 61 74 63 68 20 6f 6e 20 75 73 65 72 20 25  -match on user %
2700: 6c 6c 75 27 73 20 68 6f 6d 65 20 64 69 72 65 63  llu's home direc
2710: 74 6f 72 79 20 28 25 73 29 2e 20 20 49 74 27 73  tory (%s).  It's
2720: 20 6f 77 6e 65 64 20 62 79 20 25 6c 6c 75 2e 22   owned by %llu."
2730: 2c 0a 09 09 20 20 20 20 28 75 6e 73 69 67 6e 65  ,...    (unsigne
2740: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75  d long long) fsu
2750: 69 64 2c 0a 09 09 20 20 20 20 72 65 73 75 6c 74  id,...    result
2760: 2d 3e 70 77 5f 64 69 72 2c 0a 09 09 20 20 20 20  ->pw_dir,...    
2770: 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c  (unsigned long l
2780: 6f 6e 67 29 20 73 74 62 75 66 2e 73 74 5f 75 69  ong) stbuf.st_ui
2790: 64 0a 09 09 29 3b 0a 0a 09 09 72 65 74 75 72 6e  d...);....return
27a0: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74  (NULL);..}...ret
27b0: 76 61 6c 20 3d 20 73 74 72 64 75 70 28 72 65 73  val = strdup(res
27c0: 75 6c 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09  ult->pw_dir);...
27d0: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a  return(retval);.
27e0: 7d 0a 0a 2f 2a 0a 20 2a 20 47 65 6e 65 72 61 74  }../*. * Generat
27f0: 65 20 61 6e 20 69 6e 6f 64 65 20 66 6f 72 20 61  e an inode for a
2800: 20 67 69 76 65 6e 20 70 61 74 68 2e 20 20 54 68   given path.  Th
2810: 65 20 69 6e 6f 64 65 20 73 68 6f 75 6c 64 20 62  e inode should b
2820: 65 20 63 6f 6d 70 75 74 65 64 20 69 6e 20 73 75  e computed in su
2830: 63 68 0a 20 2a 20 61 20 77 61 79 20 74 68 61 74  ch. * a way that
2840: 20 69 74 20 69 73 20 75 6e 6c 69 6b 65 6c 79 20   it is unlikely 
2850: 74 6f 20 62 65 20 64 75 70 6c 69 63 61 74 65 64  to be duplicated
2860: 20 61 6e 64 20 72 65 6d 61 69 6e 73 20 74 68 65   and remains the
2870: 20 73 61 6d 65 20 66 6f 72 20 61 20 67 69 76 65   same for a give
2880: 6e 0a 20 2a 20 66 69 6c 65 0a 20 2a 2f 0a 73 74  n. * file. */.st
2890: 61 74 69 63 20 6c 6f 6e 67 20 6c 6f 6e 67 20 61  atic long long a
28a0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
28b0: 6f 64 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ode(const char *
28c0: 70 61 74 68 29 20 7b 0a 09 6c 6f 6e 67 20 6c 6f  path) {..long lo
28d0: 6e 67 20 72 65 74 76 61 6c 3b 0a 09 63 6f 6e 73  ng retval;..cons
28e0: 74 20 63 68 61 72 20 2a 70 3b 0a 0a 09 72 65 74  t char *p;...ret
28f0: 76 61 6c 20 3d 20 31 30 3b 0a 0a 09 66 6f 72 20  val = 10;...for 
2900: 28 70 20 3d 20 70 61 74 68 3b 20 2a 70 3b 20 70  (p = path; *p; p
2910: 2b 2b 29 20 7b 0a 09 09 72 65 74 76 61 6c 20 25  ++) {...retval %
2920: 3d 20 34 32 39 30 39 36 30 32 39 30 55 4c 4c 3b  = 4290960290ULL;
2930: 0a 09 09 72 65 74 76 61 6c 20 2b 3d 20 2a 70 3b  ...retval += *p;
2940: 0a 09 09 72 65 74 76 61 6c 20 3c 3c 3d 20 37 3b  ...retval <<= 7;
2950: 0a 09 7d 0a 0a 09 72 65 74 76 61 6c 20 2b 3d 20  ..}...retval += 
2960: 31 30 3b 0a 09 72 65 74 76 61 6c 20 25 3d 20 34  10;..retval %= 4
2970: 32 39 34 39 36 37 32 39 36 55 4c 4c 3b 0a 0a 09  294967296ULL;...
2980: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a  return(retval);.
2990: 7d 0a 0a 2f 2a 0a 20 2a 20 43 61 63 68 65 20 47  }../*. * Cache G
29a0: 65 74 20 50 61 74 68 20 49 6e 66 6f 20 6c 6f 6f  et Path Info loo
29b0: 6b 75 70 73 20 66 6f 72 20 73 70 65 65 64 0a 20  kups for speed. 
29c0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  */.static int ap
29d0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
29e0: 6f 5f 63 61 63 68 65 5f 67 65 74 28 63 6f 6e 73  o_cache_get(cons
29f0: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 75 69  t char *path, ui
2a00: 64 5f 74 20 75 69 64 2c 20 73 74 72 75 63 74 20  d_t uid, struct 
2a10: 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a  appfs_pathinfo *
2a20: 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 75 6e 73  pathinfo) {..uns
2a30: 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68 5f 69  igned int hash_i
2a40: 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64  dx;..int pthread
2a50: 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65 74 76 61  _ret;..int retva
2a60: 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 31 3b  l;...retval = 1;
2a70: 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d  ...pthread_ret =
2a80: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c   pthread_mutex_l
2a90: 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f  ock(&appfs_path_
2aa0: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78  info_cache_mutex
2ab0: 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f  );..if (pthread_
2ac0: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50  ret != 0) {...AP
2ad0: 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c  PFS_DEBUG("Unabl
2ae0: 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69  e to lock path_i
2af0: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20  nfo cache mutex 
2b00: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d  !");....return(-
2b10: 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70  1);..}...if (app
2b20: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
2b30: 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  he != NULL) {...
2b40: 68 61 73 68 5f 69 64 78 20 3d 20 28 61 70 70 66  hash_idx = (appf
2b50: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65  s_get_path_inode
2b60: 28 70 61 74 68 29 20 2b 20 75 69 64 29 20 25 20  (path) + uid) % 
2b70: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
2b80: 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 09 69  cache_size;....i
2b90: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
2ba0: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
2bb0: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21  x]._cache_path !
2bc0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 69 66 20  = NULL) {....if 
2bd0: 28 73 74 72 63 6d 70 28 61 70 70 66 73 5f 70 61  (strcmp(appfs_pa
2be0: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61  th_info_cache[ha
2bf0: 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70  sh_idx]._cache_p
2c00: 61 74 68 2c 20 70 61 74 68 29 20 3d 3d 20 30 20  ath, path) == 0 
2c10: 26 26 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  && appfs_path_in
2c20: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
2c30: 78 5d 2e 5f 63 61 63 68 65 5f 75 69 64 20 3d 3d  x]._cache_uid ==
2c40: 20 75 69 64 29 20 7b 0a 09 09 09 09 72 65 74 76   uid) {.....retv
2c50: 61 6c 20 3d 20 30 3b 0a 0a 09 09 09 09 6d 65 6d  al = 0;......mem
2c60: 63 70 79 28 70 61 74 68 69 6e 66 6f 2c 20 26 61  cpy(pathinfo, &a
2c70: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
2c80: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2c 20  ache[hash_idx], 
2c90: 73 69 7a 65 6f 66 28 2a 70 61 74 68 69 6e 66 6f  sizeof(*pathinfo
2ca0: 29 29 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f  ));.....pathinfo
2cb0: 2d 3e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20  ->_cache_path = 
2cc0: 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09  NULL;....}...}..
2cd0: 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20  }...pthread_ret 
2ce0: 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  = pthread_mutex_
2cf0: 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61  unlock(&appfs_pa
2d00: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75  th_info_cache_mu
2d10: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65  tex);..if (pthre
2d20: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
2d30: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
2d40: 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70  able to unlock p
2d50: 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d  ath_info cache m
2d60: 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74  utex !");....ret
2d70: 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66  urn(-1);..}...if
2d80: 20 28 72 65 74 76 61 6c 20 3d 3d 20 30 29 20 7b   (retval == 0) {
2d90: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
2da0: 43 61 63 68 65 20 68 69 74 20 6f 6e 20 25 73 22  Cache hit on %s"
2db0: 2c 20 70 61 74 68 29 3b 0a 09 7d 20 65 6c 73 65  , path);..} else
2dc0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
2dd0: 28 22 43 61 63 68 65 20 6d 69 73 73 20 6f 6e 20  ("Cache miss on 
2de0: 25 73 22 2c 20 70 61 74 68 29 3b 0a 09 7d 0a 0a  %s", path);..}..
2df0: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
2e00: 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .}..static void 
2e10: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
2e20: 6e 66 6f 5f 63 61 63 68 65 5f 61 64 64 28 63 6f  nfo_cache_add(co
2e30: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
2e40: 75 69 64 5f 74 20 75 69 64 2c 20 73 74 72 75 63  uid_t uid, struc
2e50: 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f  t appfs_pathinfo
2e60: 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 75   *pathinfo) {..u
2e70: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68  nsigned int hash
2e80: 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65  _idx;..int pthre
2e90: 61 64 5f 72 65 74 3b 0a 0a 09 70 74 68 72 65 61  ad_ret;...pthrea
2ea0: 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f  d_ret = pthread_
2eb0: 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66  mutex_lock(&appf
2ec0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
2ed0: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70  e_mutex);..if (p
2ee0: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
2ef0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
2f00: 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b  ("Unable to lock
2f10: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65   path_info cache
2f20: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72   mutex !");....r
2f30: 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28  eturn;..}...if (
2f40: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
2f50: 63 61 63 68 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b  cache == NULL) {
2f60: 0a 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  ...appfs_path_in
2f70: 66 6f 5f 63 61 63 68 65 20 3d 20 63 61 6c 6c 6f  fo_cache = callo
2f80: 63 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66  c(appfs_path_inf
2f90: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 2c 20 73 69  o_cache_size, si
2fa0: 7a 65 6f 66 28 2a 61 70 70 66 73 5f 70 61 74 68  zeof(*appfs_path
2fb0: 5f 69 6e 66 6f 5f 63 61 63 68 65 29 29 3b 0a 09  _info_cache));..
2fc0: 7d 0a 0a 09 68 61 73 68 5f 69 64 78 20 3d 20 28  }...hash_idx = (
2fd0: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
2fe0: 6e 6f 64 65 28 70 61 74 68 29 20 2b 20 75 69 64  node(path) + uid
2ff0: 29 20 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69  ) % appfs_path_i
3000: 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a  nfo_cache_size;.
3010: 0a 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68  ..if (appfs_path
3020: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68  _info_cache[hash
3030: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74  _idx]._cache_pat
3040: 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66  h != NULL) {...f
3050: 72 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69  ree(appfs_path_i
3060: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69  nfo_cache[hash_i
3070: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 29  dx]._cache_path)
3080: 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 79 28 26 61  ;..}...memcpy(&a
3090: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
30a0: 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2c 20  ache[hash_idx], 
30b0: 70 61 74 68 69 6e 66 6f 2c 20 73 69 7a 65 6f 66  pathinfo, sizeof
30c0: 28 2a 70 61 74 68 69 6e 66 6f 29 29 3b 0a 0a 09  (*pathinfo));...
30d0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
30e0: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e  cache[hash_idx].
30f0: 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20 73 74  _cache_path = st
3100: 72 64 75 70 28 70 61 74 68 29 3b 0a 09 61 70 70  rdup(path);..app
3110: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
3120: 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61  he[hash_idx]._ca
3130: 63 68 65 5f 75 69 64 20 20 3d 20 75 69 64 3b 0a  che_uid  = uid;.
3140: 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20  ..pthread_ret = 
3150: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e  pthread_mutex_un
3160: 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68  lock(&appfs_path
3170: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65  _info_cache_mute
3180: 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64  x);..if (pthread
3190: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41  _ret != 0) {...A
31a0: 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62  PPFS_DEBUG("Unab
31b0: 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74  le to unlock pat
31c0: 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74  h_info cache mut
31d0: 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72  ex !");....retur
31e0: 6e 3b 0a 09 7d 0a 09 72 65 74 75 72 6e 3b 0a 7d  n;..}..return;.}
31f0: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  ..static void ap
3200: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
3210: 6f 5f 63 61 63 68 65 5f 72 6d 28 63 6f 6e 73 74  o_cache_rm(const
3220: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 75 69 64   char *path, uid
3230: 5f 74 20 75 69 64 29 20 7b 0a 09 75 6e 73 69 67  _t uid) {..unsig
3240: 6e 65 64 20 69 6e 74 20 68 61 73 68 5f 69 64 78  ned int hash_idx
3250: 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72  ;..int pthread_r
3260: 65 74 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65  et;...pthread_re
3270: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65  t = pthread_mute
3280: 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61  x_lock(&appfs_pa
3290: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75  th_info_cache_mu
32a0: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65  tex);..if (pthre
32b0: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
32c0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e  .APPFS_DEBUG("Un
32d0: 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74  able to lock pat
32e0: 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74  h_info cache mut
32f0: 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72  ex !");....retur
3300: 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66  n;..}...if (appf
3310: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68  s_path_info_cach
3320: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68  e != NULL) {...h
3330: 61 73 68 5f 69 64 78 20 3d 20 28 61 70 70 66 73  ash_idx = (appfs
3340: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28  _get_path_inode(
3350: 70 61 74 68 29 20 2b 20 75 69 64 29 20 25 20 61  path) + uid) % a
3360: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
3370: 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 09 69 66  ache_size;....if
3380: 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66   (appfs_path_inf
3390: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78  o_cache[hash_idx
33a0: 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d  ]._cache_path !=
33b0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 66 72 65 65   NULL) {....free
33c0: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f  (appfs_path_info
33d0: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d  _cache[hash_idx]
33e0: 2e 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a 0a  ._cache_path);..
33f0: 09 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  ...appfs_path_in
3400: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64  fo_cache[hash_id
3410: 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d  x]._cache_path =
3420: 20 4e 55 4c 4c 3b 0a 09 09 7d 0a 09 7d 0a 0a 09   NULL;...}..}...
3430: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
3440: 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f  hread_mutex_unlo
3450: 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69  ck(&appfs_path_i
3460: 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29  nfo_cache_mutex)
3470: 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72  ;..if (pthread_r
3480: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50  et != 0) {...APP
3490: 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65  FS_DEBUG("Unable
34a0: 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f   to unlock path_
34b0: 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78  info cache mutex
34c0: 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b   !");....return;
34d0: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a  ..}...return;.}.
34e0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70  .static void app
34f0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
3500: 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 75 69 64  _cache_flush(uid
3510: 5f 74 20 75 69 64 2c 20 69 6e 74 20 6e 65 77 5f  _t uid, int new_
3520: 73 69 7a 65 29 20 7b 0a 09 75 6e 73 69 67 6e 65  size) {..unsigne
3530: 64 20 69 6e 74 20 69 64 78 3b 0a 09 69 6e 74 20  d int idx;..int 
3540: 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 41  pthread_ret;...A
3550: 50 50 46 53 5f 44 45 42 55 47 28 22 46 6c 75 73  PPFS_DEBUG("Flus
3560: 68 69 6e 67 20 41 70 70 46 53 20 63 61 63 68 65  hing AppFS cache
3570: 20 28 75 69 64 20 3d 20 25 6c 6c 69 2c 20 6e 65   (uid = %lli, ne
3580: 77 5f 73 69 7a 65 20 3d 20 25 69 29 22 2c 20 28  w_size = %i)", (
3590: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 75 69 64 2c 20  long long) uid, 
35a0: 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a 09 70 74 68  new_size);...pth
35b0: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65  read_ret = pthre
35c0: 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61  ad_mutex_lock(&a
35d0: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
35e0: 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66  ache_mutex);..if
35f0: 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d   (pthread_ret !=
3600: 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45   0) {...APPFS_DE
3610: 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c  BUG("Unable to l
3620: 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61  ock path_info ca
3630: 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a  che mutex !");..
3640: 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69  ..return;..}...i
3650: 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e  f (appfs_path_in
3660: 66 6f 5f 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c  fo_cache != NULL
3670: 29 20 7b 0a 09 09 66 6f 72 20 28 69 64 78 20 3d  ) {...for (idx =
3680: 20 30 3b 20 69 64 78 20 3c 20 61 70 70 66 73 5f   0; idx < appfs_
3690: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f  path_info_cache_
36a0: 73 69 7a 65 3b 20 69 64 78 2b 2b 29 20 7b 0a 09  size; idx++) {..
36b0: 09 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68  ..if (appfs_path
36c0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d  _info_cache[idx]
36d0: 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20  ._cache_path != 
36e0: 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 69 66 20 28  NULL) {.....if (
36f0: 75 69 64 20 21 3d 20 28 28 75 69 64 5f 74 29 20  uid != ((uid_t) 
3700: 2d 31 29 29 20 7b 0a 09 09 09 09 09 69 66 20 28  -1)) {......if (
3710: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f  appfs_path_info_
3720: 63 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68  cache[idx]._cach
3730: 65 5f 75 69 64 20 21 3d 20 75 69 64 29 20 7b 0a  e_uid != uid) {.
3740: 09 09 09 09 09 09 63 6f 6e 74 69 6e 75 65 3b 0a  ......continue;.
3750: 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09  .....}.....}....
3760: 09 09 66 72 65 65 28 61 70 70 66 73 5f 70 61 74  ..free(appfs_pat
3770: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78  h_info_cache[idx
3780: 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a  ]._cache_path);.
3790: 0a 09 09 09 09 61 70 70 66 73 5f 70 61 74 68 5f  .....appfs_path_
37a0: 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e  info_cache[idx].
37b0: 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20 4e 55  _cache_path = NU
37c0: 4c 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a  LL;....}...}..}.
37d0: 0a 09 69 66 20 28 75 69 64 20 3d 3d 20 28 28 75  ..if (uid == ((u
37e0: 69 64 5f 74 29 20 2d 31 29 29 20 7b 0a 09 09 66  id_t) -1)) {...f
37f0: 72 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69  ree(appfs_path_i
3800: 6e 66 6f 5f 63 61 63 68 65 29 3b 0a 0a 09 09 61  nfo_cache);....a
3810: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  ppfs_path_info_c
3820: 61 63 68 65 20 3d 20 4e 55 4c 4c 3b 0a 0a 09 09  ache = NULL;....
3830: 69 66 20 28 6e 65 77 5f 73 69 7a 65 20 21 3d 20  if (new_size != 
3840: 2d 31 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 70  -1) {....appfs_p
3850: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73  ath_info_cache_s
3860: 69 7a 65 20 3d 20 6e 65 77 5f 73 69 7a 65 3b 0a  ize = new_size;.
3870: 09 09 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64  ..}..}...pthread
3880: 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d  _ret = pthread_m
3890: 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70  utex_unlock(&app
38a0: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  fs_path_info_cac
38b0: 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28  he_mutex);..if (
38c0: 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30  pthread_ret != 0
38d0: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
38e0: 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c  G("Unable to unl
38f0: 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61  ock path_info ca
3900: 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a  che mutex !");..
3910: 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72  ..return;..}...r
3920: 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20 47 65 74  eturn;.}../* Get
3930: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f   information abo
3940: 75 74 20 61 20 70 61 74 68 2c 20 61 6e 64 20 6f  ut a path, and o
3950: 70 74 69 6f 6e 61 6c 6c 79 20 6c 69 73 74 20 63  ptionally list c
3960: 68 69 6c 64 72 65 6e 20 2a 2f 0a 73 74 61 74 69  hildren */.stati
3970: 63 20 69 6e 74 20 61 70 70 66 73 5f 67 65 74 5f  c int appfs_get_
3980: 70 61 74 68 5f 69 6e 66 6f 28 63 6f 6e 73 74 20  path_info(const 
3990: 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75  char *path, stru
39a0: 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66  ct appfs_pathinf
39b0: 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09  o *pathinfo) {..
39c0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
39d0: 72 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 61 74  rp;..Tcl_Obj *at
39e0: 74 72 73 5f 64 69 63 74 2c 20 2a 61 74 74 72 5f  trs_dict, *attr_
39f0: 76 61 6c 75 65 3b 0a 09 63 6f 6e 73 74 20 63 68  value;..const ch
3a00: 61 72 20 2a 61 74 74 72 5f 76 61 6c 75 65 5f 73  ar *attr_value_s
3a10: 74 72 3b 0a 09 54 63 6c 5f 57 69 64 65 49 6e 74  tr;..Tcl_WideInt
3a20: 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65   attr_value_wide
3a30: 3b 0a 09 69 6e 74 20 61 74 74 72 5f 76 61 6c 75  ;..int attr_valu
3a40: 65 5f 69 6e 74 3b 0a 09 73 74 61 74 69 63 20 5f  e_int;..static _
3a50: 5f 74 68 72 65 61 64 20 54 63 6c 5f 4f 62 6a 20  _thread Tcl_Obj 
3a60: 2a 61 74 74 72 5f 6b 65 79 5f 74 79 70 65 20 3d  *attr_key_type =
3a70: 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79   NULL, *attr_key
3a80: 5f 70 65 72 6d 73 20 3d 20 4e 55 4c 4c 2c 20 2a  _perms = NULL, *
3a90: 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 20 3d 20  attr_key_size = 
3aa0: 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f  NULL, *attr_key_
3ab0: 74 69 6d 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74  time = NULL, *at
3ac0: 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65 20 3d 20  tr_key_source = 
3ad0: 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f  NULL, *attr_key_
3ae0: 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 4e 55 4c  childcount = NUL
3af0: 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 70 61 63  L, *attr_key_pac
3b00: 6b 61 67 65 64 20 3d 20 4e 55 4c 4c 3b 0a 09 69  kaged = NULL;..i
3b10: 6e 74 20 63 61 63 68 65 5f 72 65 74 3b 0a 09 69  nt cache_ret;..i
3b20: 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 63 61  nt tcl_ret;...ca
3b30: 63 68 65 5f 72 65 74 20 3d 20 61 70 70 66 73 5f  che_ret = appfs_
3b40: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
3b50: 63 68 65 5f 67 65 74 28 70 61 74 68 2c 20 61 70  che_get(path, ap
3b60: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 2c  pfs_get_fsuid(),
3b70: 20 70 61 74 68 69 6e 66 6f 29 3b 0a 09 69 66 20   pathinfo);..if 
3b80: 28 63 61 63 68 65 5f 72 65 74 20 3d 3d 20 30 29  (cache_ret == 0)
3b90: 20 7b 0a 09 09 69 66 20 28 70 61 74 68 69 6e 66   {...if (pathinf
3ba0: 6f 2d 3e 74 79 70 65 20 3d 3d 20 41 50 50 46 53  o->type == APPFS
3bb0: 5f 50 41 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e  _PATHTYPE_DOES_N
3bc0: 4f 54 5f 45 58 49 53 54 29 20 7b 0a 09 09 09 72  OT_EXIST) {....r
3bd0: 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a  eturn(-ENOENT);.
3be0: 09 09 7d 0a 0a 09 09 69 66 20 28 70 61 74 68 69  ..}....if (pathi
3bf0: 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d 20 41 50 50  nfo->type == APP
3c00: 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41  FS_PATHTYPE_INVA
3c10: 4c 49 44 29 20 7b 0a 09 09 09 72 65 74 75 72 6e  LID) {....return
3c20: 28 2d 45 49 4f 29 3b 0a 09 09 7d 0a 0a 09 09 72  (-EIO);...}....r
3c30: 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 69  eturn(0);..}...i
3c40: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63  nterp = appfs_Tc
3c50: 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28  lInterp();..if (
3c60: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
3c70: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
3c80: 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 50 72 65 73 65  ;..}...Tcl_Prese
3c90: 72 76 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 74  rve(interp);...t
3ca0: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54  cl_ret = appfs_T
3cb0: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20  cl_Eval(interp, 
3cc0: 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74  2, "::appfs::get
3cd0: 61 74 74 72 22 2c 20 70 61 74 68 29 3b 0a 09 69  attr", path);..i
3ce0: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
3cf0: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f  L_OK) {...APPFS_
3d00: 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a  DEBUG("::appfs::
3d10: 67 65 74 61 74 74 72 28 25 73 29 20 66 61 69 6c  getattr(%s) fail
3d20: 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41  ed.", path);...A
3d30: 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20  PPFS_DEBUG("Tcl 
3d40: 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54  Error is: %s", T
3d50: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
3d60: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09  lt(interp));....
3d70: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d  pathinfo->type =
3d80: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
3d90: 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 3b 0a  DOES_NOT_EXIST;.
3da0: 0a 09 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74  ...appfs_get_pat
3db0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64 64  h_info_cache_add
3dc0: 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74  (path, appfs_get
3dd0: 5f 66 73 75 69 64 28 29 2c 20 70 61 74 68 69 6e  _fsuid(), pathin
3de0: 66 6f 29 3b 0a 0a 09 09 54 63 6c 5f 52 65 6c 65  fo);....Tcl_Rele
3df0: 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09  ase(interp);....
3e00: 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b  return(-ENOENT);
3e10: 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 6b  ..}...if (attr_k
3e20: 65 79 5f 74 79 70 65 20 3d 3d 20 4e 55 4c 4c 29  ey_type == NULL)
3e30: 20 7b 0a 09 09 61 74 74 72 5f 6b 65 79 5f 74 79   {...attr_key_ty
3e40: 70 65 20 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e  pe       = Tcl_N
3e50: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 74 79 70  ewStringObj("typ
3e60: 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f  e", -1);...attr_
3e70: 6b 65 79 5f 70 65 72 6d 73 20 20 20 20 20 20 3d  key_perms      =
3e80: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
3e90: 6a 28 22 70 65 72 6d 73 22 2c 20 2d 31 29 3b 0a  j("perms", -1);.
3ea0: 09 09 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 20  ..attr_key_size 
3eb0: 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53        = Tcl_NewS
3ec0: 74 72 69 6e 67 4f 62 6a 28 22 73 69 7a 65 22 2c  tringObj("size",
3ed0: 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79   -1);...attr_key
3ee0: 5f 74 69 6d 65 20 20 20 20 20 20 20 3d 20 54 63  _time       = Tc
3ef0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22  l_NewStringObj("
3f00: 74 69 6d 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74  time", -1);...at
3f10: 74 72 5f 6b 65 79 5f 73 6f 75 72 63 65 20 20 20  tr_key_source   
3f20: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e    = Tcl_NewStrin
3f30: 67 4f 62 6a 28 22 73 6f 75 72 63 65 22 2c 20 2d  gObj("source", -
3f40: 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79 5f 63  1);...attr_key_c
3f50: 68 69 6c 64 63 6f 75 6e 74 20 3d 20 54 63 6c 5f  hildcount = Tcl_
3f60: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 63 68  NewStringObj("ch
3f70: 69 6c 64 63 6f 75 6e 74 22 2c 20 2d 31 29 3b 0a  ildcount", -1);.
3f80: 09 09 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61  ..attr_key_packa
3f90: 67 65 64 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53  ged   = Tcl_NewS
3fa0: 74 72 69 6e 67 4f 62 6a 28 22 70 61 63 6b 61 67  tringObj("packag
3fb0: 65 64 22 2c 20 2d 31 29 3b 0a 09 7d 0a 0a 09 61  ed", -1);..}...a
3fc0: 74 74 72 73 5f 64 69 63 74 20 3d 20 54 63 6c 5f  ttrs_dict = Tcl_
3fd0: 47 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  GetObjResult(int
3fe0: 65 72 70 29 3b 0a 09 74 63 6c 5f 72 65 74 20 3d  erp);..tcl_ret =
3ff0: 20 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28   Tcl_DictObjGet(
4000: 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69  interp, attrs_di
4010: 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74 79 70  ct, attr_key_typ
4020: 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b  e, &attr_value);
4030: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d  ..if (tcl_ret !=
4040: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50   TCL_OK) {...APP
4050: 46 53 5f 44 45 42 55 47 28 22 5b 64 69 63 74 20  FS_DEBUG("[dict 
4060: 67 65 74 20 5c 22 74 79 70 65 5c 22 5d 20 66 61  get \"type\"] fa
4070: 69 6c 65 64 22 29 3b 0a 09 09 41 50 50 46 53 5f  iled");...APPFS_
4080: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72  DEBUG("Tcl Error
4090: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65   is: %s", Tcl_Ge
40a0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
40b0: 74 65 72 70 29 29 3b 0a 0a 09 09 54 63 6c 5f 52  terp));....Tcl_R
40c0: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a  elease(interp);.
40d0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
40e0: 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 76  ..}...if (attr_v
40f0: 61 6c 75 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  alue == NULL) {.
4100: 09 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  ..Tcl_Release(in
4110: 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e  terp);....return
4120: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 70 61 74  (-EIO);..}...pat
4130: 68 69 6e 66 6f 2d 3e 70 61 63 6b 61 67 65 64 20  hinfo->packaged 
4140: 3d 20 30 3b 0a 09 70 61 74 68 69 6e 66 6f 2d 3e  = 0;..pathinfo->
4150: 69 6e 6f 64 65 20 3d 20 61 70 70 66 73 5f 67 65  inode = appfs_ge
4160: 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74  t_path_inode(pat
4170: 68 29 3b 0a 0a 09 61 74 74 72 5f 76 61 6c 75 65  h);...attr_value
4180: 5f 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74  _str = Tcl_GetSt
4190: 72 69 6e 67 28 61 74 74 72 5f 76 61 6c 75 65 29  ring(attr_value)
41a0: 3b 0a 09 73 77 69 74 63 68 20 28 61 74 74 72 5f  ;..switch (attr_
41b0: 76 61 6c 75 65 5f 73 74 72 5b 30 5d 29 20 7b 0a  value_str[0]) {.
41c0: 09 09 63 61 73 65 20 27 64 27 3a 20 2f 2a 20 64  ..case 'd': /* d
41d0: 69 72 65 63 74 6f 72 79 20 2a 2f 0a 09 09 09 70  irectory */....p
41e0: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20  athinfo->type = 
41f0: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44  APPFS_PATHTYPE_D
4200: 49 52 45 43 54 4f 52 59 3b 0a 09 09 09 70 61 74  IRECTORY;....pat
4210: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
4220: 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d  dir.childcount =
4230: 20 30 3b 0a 0a 09 09 09 54 63 6c 5f 44 69 63 74   0;.....Tcl_Dict
4240: 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61  ObjGet(interp, a
4250: 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f  ttrs_dict, attr_
4260: 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 2c 20  key_childcount, 
4270: 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09  &attr_value);...
4280: 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20  .if (attr_value 
4290: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 74  != NULL) {.....t
42a0: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74  cl_ret = Tcl_Get
42b0: 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e  WideIntFromObj(N
42c0: 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c  ULL, attr_value,
42d0: 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64   &attr_value_wid
42e0: 65 29 3b 0a 09 09 09 09 69 66 20 28 74 63 6c 5f  e);.....if (tcl_
42f0: 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret == TCL_OK) {
4300: 0a 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e  ......pathinfo->
4310: 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69  typeinfo.dir.chi
4320: 6c 64 63 6f 75 6e 74 20 3d 20 61 74 74 72 5f 76  ldcount = attr_v
4330: 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09 09 7d  alue_wide;.....}
4340: 0a 09 09 09 7d 0a 0a 09 09 09 62 72 65 61 6b 3b  ....}.....break;
4350: 0a 09 09 63 61 73 65 20 27 66 27 3a 20 2f 2a 20  ...case 'f': /* 
4360: 66 69 6c 65 20 2a 2f 0a 09 09 09 70 61 74 68 69  file */....pathi
4370: 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46  nfo->type = APPF
4380: 53 5f 50 41 54 48 54 59 50 45 5f 46 49 4c 45 3b  S_PATHTYPE_FILE;
4390: 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
43a0: 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65  peinfo.file.size
43b0: 20 3d 20 30 3b 0a 09 09 09 70 61 74 68 69 6e 66   = 0;....pathinf
43c0: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  o->typeinfo.file
43d0: 2e 65 78 65 63 75 74 61 62 6c 65 20 3d 20 30 3b  .executable = 0;
43e0: 0a 0a 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a  .....Tcl_DictObj
43f0: 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72  Get(interp, attr
4400: 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79  s_dict, attr_key
4410: 5f 73 69 7a 65 2c 20 26 61 74 74 72 5f 76 61 6c  _size, &attr_val
4420: 75 65 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72  ue);....if (attr
4430: 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20  _value != NULL) 
4440: 7b 0a 09 09 09 09 74 63 6c 5f 72 65 74 20 3d 20  {.....tcl_ret = 
4450: 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72  Tcl_GetWideIntFr
4460: 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72  omObj(NULL, attr
4470: 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61  _value, &attr_va
4480: 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 09 69  lue_wide);.....i
4490: 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43  f (tcl_ret == TC
44a0: 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 70 61 74  L_OK) {......pat
44b0: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
44c0: 66 69 6c 65 2e 73 69 7a 65 20 3d 20 61 74 74 72  file.size = attr
44d0: 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09  _value_wide;....
44e0: 09 7d 0a 09 09 09 7d 0a 0a 09 09 09 54 63 6c 5f  .}....}.....Tcl_
44f0: 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72  DictObjGet(inter
4500: 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61  p, attrs_dict, a
4510: 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 2c 20 26  ttr_key_perms, &
4520: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09  attr_value);....
4530: 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21  if (attr_value !
4540: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 61 74  = NULL) {.....at
4550: 74 72 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20 54  tr_value_str = T
4560: 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 61 74 74  cl_GetString(att
4570: 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09 69 66  r_value);.....if
4580: 20 28 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72   (attr_value_str
4590: 5b 30 5d 20 3d 3d 20 27 78 27 29 20 7b 0a 09 09  [0] == 'x') {...
45a0: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
45b0: 65 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75  einfo.file.execu
45c0: 74 61 62 6c 65 20 3d 20 31 3b 0a 09 09 09 09 7d  table = 1;.....}
45d0: 0a 09 09 09 7d 0a 09 09 09 62 72 65 61 6b 3b 0a  ....}....break;.
45e0: 09 09 63 61 73 65 20 27 73 27 3a 20 2f 2a 20 73  ..case 's': /* s
45f0: 79 6d 6c 69 6e 6b 20 2a 2f 0a 09 09 09 70 61 74  ymlink */....pat
4600: 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50  hinfo->type = AP
4610: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d  PFS_PATHTYPE_SYM
4620: 4c 49 4e 4b 3b 0a 09 09 09 70 61 74 68 69 6e 66  LINK;....pathinf
4630: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c  o->typeinfo.syml
4640: 69 6e 6b 2e 73 69 7a 65 20 3d 20 30 3b 0a 09 09  ink.size = 0;...
4650: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  .pathinfo->typei
4660: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72  nfo.symlink.sour
4670: 63 65 5b 30 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09  ce[0] = '\0';...
4680: 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74  ..Tcl_DictObjGet
4690: 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64  (interp, attrs_d
46a0: 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 73 6f  ict, attr_key_so
46b0: 75 72 63 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  urce, &attr_valu
46c0: 65 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72 5f  e);....if (attr_
46d0: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  value != NULL) {
46e0: 0a 09 09 09 09 61 74 74 72 5f 76 61 6c 75 65 5f  .....attr_value_
46f0: 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  str = Tcl_GetStr
4700: 69 6e 67 46 72 6f 6d 4f 62 6a 28 61 74 74 72 5f  ingFromObj(attr_
4710: 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c  value, &attr_val
4720: 75 65 5f 69 6e 74 29 3b 20 0a 0a 09 09 09 09 69  ue_int); ......i
4730: 66 20 28 28 61 74 74 72 5f 76 61 6c 75 65 5f 69  f ((attr_value_i
4740: 6e 74 20 2b 20 31 29 20 3c 3d 20 73 69 7a 65 6f  nt + 1) <= sizeo
4750: 66 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  f(pathinfo->type
4760: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75  info.symlink.sou
4770: 72 63 65 29 29 20 7b 0a 09 09 09 09 09 70 61 74  rce)) {......pat
4780: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e  hinfo->typeinfo.
4790: 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20 61  symlink.size = a
47a0: 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a 09  ttr_value_int;..
47b0: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79  ....pathinfo->ty
47c0: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
47d0: 6f 75 72 63 65 5b 61 74 74 72 5f 76 61 6c 75 65  ource[attr_value
47e0: 5f 69 6e 74 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09  _int] = '\0';...
47f0: 09 09 09 09 6d 65 6d 63 70 79 28 70 61 74 68 69  ....memcpy(pathi
4800: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79  nfo->typeinfo.sy
4810: 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c 20 61 74  mlink.source, at
4820: 74 72 5f 76 61 6c 75 65 5f 73 74 72 2c 20 61 74  tr_value_str, at
4830: 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 0a 09  tr_value_int);..
4840: 09 09 09 7d 0a 09 09 09 7d 0a 09 09 09 62 72 65  ...}....}....bre
4850: 61 6b 3b 0a 09 09 63 61 73 65 20 27 46 27 3a 20  ak;...case 'F': 
4860: 2f 2a 20 70 69 70 65 2f 66 69 66 6f 20 2a 2f 0a  /* pipe/fifo */.
4870: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
4880: 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59  e = APPFS_PATHTY
4890: 50 45 5f 46 49 46 4f 3b 0a 09 09 09 62 72 65 61  PE_FIFO;....brea
48a0: 6b 3b 0a 09 09 63 61 73 65 20 27 53 27 3a 20 2f  k;...case 'S': /
48b0: 2a 20 55 4e 49 58 20 64 6f 6d 61 69 6e 20 73 6f  * UNIX domain so
48c0: 63 6b 65 74 20 2a 2f 0a 09 09 09 70 61 74 68 69  cket */....pathi
48d0: 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46  nfo->type = APPF
48e0: 53 5f 50 41 54 48 54 59 50 45 5f 53 4f 43 4b 45  S_PATHTYPE_SOCKE
48f0: 54 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 64  T;....break;...d
4900: 65 66 61 75 6c 74 3a 0a 09 09 09 54 63 6c 5f 52  efault:....Tcl_R
4910: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a  elease(interp);.
4920: 0a 09 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  ....return(-EIO)
4930: 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 44 69 63 74 4f  ;..}...Tcl_DictO
4940: 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74  bjGet(interp, at
4950: 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b  trs_dict, attr_k
4960: 65 79 5f 70 61 63 6b 61 67 65 64 2c 20 26 61 74  ey_packaged, &at
4970: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 69 66 20 28  tr_value);..if (
4980: 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55  attr_value != NU
4990: 4c 4c 29 20 7b 0a 09 09 70 61 74 68 69 6e 66 6f  LL) {...pathinfo
49a0: 2d 3e 70 61 63 6b 61 67 65 64 20 3d 20 31 3b 0a  ->packaged = 1;.
49b0: 09 7d 0a 0a 09 54 63 6c 5f 44 69 63 74 4f 62 6a  .}...Tcl_DictObj
49c0: 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72  Get(interp, attr
49d0: 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79  s_dict, attr_key
49e0: 5f 74 69 6d 65 2c 20 26 61 74 74 72 5f 76 61 6c  _time, &attr_val
49f0: 75 65 29 3b 0a 09 69 66 20 28 61 74 74 72 5f 76  ue);..if (attr_v
4a00: 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  alue != NULL) {.
4a10: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
4a20: 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62  GetWideIntFromOb
4a30: 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c  j(NULL, attr_val
4a40: 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 5f  ue, &attr_value_
4a50: 77 69 64 65 29 3b 0a 09 09 69 66 20 28 74 63 6c  wide);...if (tcl
4a60: 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20  _ret == TCL_OK) 
4a70: 7b 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  {....pathinfo->t
4a80: 69 6d 65 20 3d 20 61 74 74 72 5f 76 61 6c 75 65  ime = attr_value
4a90: 5f 77 69 64 65 3b 0a 09 09 7d 0a 09 7d 20 65 6c  _wide;...}..} el
4aa0: 73 65 20 7b 0a 09 09 70 61 74 68 69 6e 66 6f 2d  se {...pathinfo-
4ab0: 3e 74 69 6d 65 20 3d 20 30 3b 0a 09 7d 0a 0a 09  >time = 0;..}...
4ac0: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65  Tcl_Release(inte
4ad0: 72 70 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74  rp);...appfs_get
4ae0: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65  _path_info_cache
4af0: 5f 61 64 64 28 70 61 74 68 2c 20 61 70 70 66 73  _add(path, appfs
4b00: 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20 70 61  _get_fsuid(), pa
4b10: 74 68 69 6e 66 6f 29 3b 0a 0a 09 72 65 74 75 72  thinfo);...retur
4b20: 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n(0);.}..static 
4b30: 63 68 61 72 20 2a 61 70 70 66 73 5f 70 72 65 70  char *appfs_prep
4b40: 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 63 6f  are_to_create(co
4b50: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 29 20  nst char *path) 
4b60: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
4b70: 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68  nterp;..const ch
4b80: 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09  ar *real_path;..
4b90: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 61  int tcl_ret;...a
4ba0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
4bb0: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 61  fo_cache_flush(a
4bc0: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
4bd0: 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74 65 72 70 20  , -1);...interp 
4be0: 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72  = appfs_TclInter
4bf0: 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  p();..if (interp
4c00: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
4c10: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
4c20: 09 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e  .Tcl_Preserve(in
4c30: 74 65 72 70 29 3b 0a 0a 09 74 63 6c 5f 72 65 74  terp);...tcl_ret
4c40: 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61   = appfs_Tcl_Eva
4c50: 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a  l(interp, 2, "::
4c60: 61 70 70 66 73 3a 3a 70 72 65 70 61 72 65 5f 74  appfs::prepare_t
4c70: 6f 5f 63 72 65 61 74 65 22 2c 20 70 61 74 68 29  o_create", path)
4c80: 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21  ;..if (tcl_ret !
4c90: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50  = TCL_OK) {...AP
4ca0: 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70  PFS_DEBUG("::app
4cb0: 66 73 3a 3a 70 72 65 70 61 72 65 5f 74 6f 5f 63  fs::prepare_to_c
4cc0: 72 65 61 74 65 28 25 73 29 20 66 61 69 6c 65 64  reate(%s) failed
4cd0: 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41 50 50  .", path);...APP
4ce0: 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72  FS_DEBUG("Tcl Er
4cf0: 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c  ror is: %s", Tcl
4d00: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
4d10: 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 54 63  (interp));....Tc
4d20: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
4d30: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  );....return(NUL
4d40: 4c 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61  L);..}...real_pa
4d50: 74 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  th = Tcl_GetStri
4d60: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
4d70: 3b 0a 0a 09 54 63 6c 5f 52 65 6c 65 61 73 65 28  ;...Tcl_Release(
4d80: 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 72  interp);...if (r
4d90: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
4da0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c  ) {...return(NUL
4db0: 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  L);..}...return(
4dc0: 73 74 72 64 75 70 28 72 65 61 6c 5f 70 61 74 68  strdup(real_path
4dd0: 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68  ));.}..static ch
4de0: 61 72 20 2a 61 70 70 66 73 5f 6c 6f 63 61 6c 70  ar *appfs_localp
4df0: 61 74 68 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ath(const char *
4e00: 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74  path) {..Tcl_Int
4e10: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f  erp *interp;..co
4e20: 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70  nst char *real_p
4e30: 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65  ath;..int tcl_re
4e40: 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  t;...interp = ap
4e50: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  pfs_TclInterp();
4e60: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
4e70: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
4e80: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 54 63 6c  (NULL);..}...Tcl
4e90: 5f 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70  _Preserve(interp
4ea0: 29 3b 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61  );...tcl_ret = a
4eb0: 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e  ppfs_Tcl_Eval(in
4ec0: 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66  terp, 2, "::appf
4ed0: 73 3a 3a 6c 6f 63 61 6c 70 61 74 68 22 2c 20 70  s::localpath", p
4ee0: 61 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72  ath);..if (tcl_r
4ef0: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
4f00: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a  ..APPFS_DEBUG(":
4f10: 3a 61 70 70 66 73 3a 3a 6c 6f 63 61 6c 70 61 74  :appfs::localpat
4f20: 68 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20  h(%s) failed.", 
4f30: 70 61 74 68 29 3b 0a 09 09 41 50 50 46 53 5f 44  path);...APPFS_D
4f40: 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20  EBUG("Tcl Error 
4f50: 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74  is: %s", Tcl_Get
4f60: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
4f70: 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e  erp));....return
4f80: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 61  (NULL);..}...rea
4f90: 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74  l_path = Tcl_Get
4fa0: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
4fb0: 65 72 70 29 3b 0a 0a 09 54 63 6c 5f 52 65 6c 65  erp);...Tcl_Rele
4fc0: 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a 09 69  ase(interp);...i
4fd0: 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20  f (real_path == 
4fe0: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
4ff0: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74  (NULL);..}...ret
5000: 75 72 6e 28 73 74 72 64 75 70 28 72 65 61 6c 5f  urn(strdup(real_
5010: 70 61 74 68 29 29 3b 0a 7d 0a 0a 73 74 61 74 69  path));.}..stati
5020: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
5030: 5f 72 65 61 64 6c 69 6e 6b 28 63 6f 6e 73 74 20  _readlink(const 
5040: 63 68 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72  char *path, char
5050: 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69   *buf, size_t si
5060: 7a 65 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70  ze) {..struct ap
5070: 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74  pfs_pathinfo pat
5080: 68 69 6e 66 6f 3b 0a 09 69 6e 74 20 72 65 74 76  hinfo;..int retv
5090: 61 6c 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f  al = 0;...APPFS_
50a0: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
50b0: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
50c0: 70 61 74 68 29 3b 0a 0a 09 70 61 74 68 69 6e 66  path);...pathinf
50d0: 6f 2e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50  o.type = APPFS_P
50e0: 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b  ATHTYPE_INVALID;
50f0: 0a 0a 09 72 65 74 76 61 6c 20 3d 20 61 70 70 66  ...retval = appf
5100: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28  s_get_path_info(
5110: 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29  path, &pathinfo)
5120: 3b 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d  ;..if (retval !=
5130: 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 72   0) {...return(r
5140: 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09 69 66 20  etval);..}...if 
5150: 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 21  (pathinfo.type !
5160: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  = APPFS_PATHTYPE
5170: 5f 53 59 4d 4c 49 4e 4b 29 20 7b 0a 09 09 72 65  _SYMLINK) {...re
5180: 74 75 72 6e 28 2d 45 49 4e 56 41 4c 29 3b 0a 09  turn(-EINVAL);..
5190: 7d 0a 0a 09 69 66 20 28 28 73 74 72 6c 65 6e 28  }...if ((strlen(
51a0: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66  pathinfo.typeinf
51b0: 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65  o.symlink.source
51c0: 29 20 2b 20 31 29 20 3e 20 73 69 7a 65 29 20 7b  ) + 1) > size) {
51d0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 4e 41 4d 45  ...return(-ENAME
51e0: 54 4f 4f 4c 4f 4e 47 29 3b 0a 09 7d 0a 0a 09 6d  TOOLONG);..}...m
51f0: 65 6d 63 70 79 28 62 75 66 2c 20 70 61 74 68 69  emcpy(buf, pathi
5200: 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  nfo.typeinfo.sym
5210: 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c 20 73 74 72  link.source, str
5220: 6c 65 6e 28 70 61 74 68 69 6e 66 6f 2e 74 79 70  len(pathinfo.typ
5230: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f  einfo.symlink.so
5240: 75 72 63 65 29 20 2b 20 31 29 3b 0a 0a 09 72 65  urce) + 1);...re
5250: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
5260: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
5270: 65 5f 67 65 74 61 74 74 72 28 63 6f 6e 73 74 20  e_getattr(const 
5280: 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75  char *path, stru
5290: 63 74 20 73 74 61 74 20 2a 73 74 62 75 66 29 20  ct stat *stbuf) 
52a0: 7b 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f  {..struct appfs_
52b0: 70 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66  pathinfo pathinf
52c0: 6f 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a  o;..int retval;.
52d0: 0a 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09  ..retval = 0;...
52e0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
52f0: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
5300: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 70  ..)", path);...p
5310: 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41  athinfo.type = A
5320: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e  PPFS_PATHTYPE_IN
5330: 56 41 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20  VALID;...retval 
5340: 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68  = appfs_get_path
5350: 5f 69 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74  _info(path, &pat
5360: 68 69 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65 74  hinfo);..if (ret
5370: 76 61 6c 20 21 3d 20 30 29 20 7b 0a 09 09 72 65  val != 0) {...re
5380: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d  turn(retval);..}
5390: 0a 0a 09 6d 65 6d 73 65 74 28 73 74 62 75 66 2c  ...memset(stbuf,
53a0: 20 30 2c 20 73 69 7a 65 6f 66 28 73 74 72 75 63   0, sizeof(struc
53b0: 74 20 73 74 61 74 29 29 3b 0a 0a 09 73 74 62 75  t stat));...stbu
53c0: 66 2d 3e 73 74 5f 6d 74 69 6d 65 20 3d 20 70 61  f->st_mtime = pa
53d0: 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74  thinfo.time;..st
53e0: 62 75 66 2d 3e 73 74 5f 63 74 69 6d 65 20 3d 20  buf->st_ctime = 
53f0: 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09  pathinfo.time;..
5400: 73 74 62 75 66 2d 3e 73 74 5f 61 74 69 6d 65 20  stbuf->st_atime 
5410: 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b  = pathinfo.time;
5420: 0a 09 73 74 62 75 66 2d 3e 73 74 5f 69 6e 6f 20  ..stbuf->st_ino 
5430: 20 20 3d 20 70 61 74 68 69 6e 66 6f 2e 69 6e 6f    = pathinfo.ino
5440: 64 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 6d  de;..stbuf->st_m
5450: 6f 64 65 20 20 3d 20 30 3b 0a 0a 09 73 77 69 74  ode  = 0;...swit
5460: 63 68 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70  ch (pathinfo.typ
5470: 65 29 20 7b 0a 09 09 63 61 73 65 20 41 50 50 46  e) {...case APPF
5480: 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45 43  S_PATHTYPE_DIREC
5490: 54 4f 52 59 3a 0a 09 09 09 73 74 62 75 66 2d 3e  TORY:....stbuf->
54a0: 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 44 49  st_mode = S_IFDI
54b0: 52 20 7c 20 30 35 35 35 3b 0a 09 09 09 73 74 62  R | 0555;....stb
54c0: 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 32  uf->st_nlink = 2
54d0: 20 2b 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65   + pathinfo.type
54e0: 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f  info.dir.childco
54f0: 75 6e 74 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09  unt;....break;..
5500: 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48  .case APPFS_PATH
5510: 54 59 50 45 5f 46 49 4c 45 3a 0a 09 09 09 69 66  TYPE_FILE:....if
5520: 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69   (pathinfo.typei
5530: 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74 61  nfo.file.executa
5540: 62 6c 65 29 20 7b 0a 09 09 09 09 73 74 62 75 66  ble) {.....stbuf
5550: 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46  ->st_mode = S_IF
5560: 52 45 47 20 7c 20 30 35 35 35 3b 0a 09 09 09 7d  REG | 0555;....}
5570: 20 65 6c 73 65 20 7b 0a 09 09 09 09 73 74 62 75   else {.....stbu
5580: 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49  f->st_mode = S_I
5590: 46 52 45 47 20 7c 20 30 34 34 34 3b 0a 09 09 09  FREG | 0444;....
55a0: 7d 0a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  }.....stbuf->st_
55b0: 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74  nlink = 1;....st
55c0: 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 70  buf->st_size = p
55d0: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
55e0: 2e 66 69 6c 65 2e 73 69 7a 65 3b 0a 09 09 09 62  .file.size;....b
55f0: 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50  reak;...case APP
5600: 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c  FS_PATHTYPE_SYML
5610: 49 4e 4b 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73  INK:....stbuf->s
5620: 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 4c 4e 4b  t_mode = S_IFLNK
5630: 20 7c 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75   | 0555;....stbu
5640: 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b  f->st_nlink = 1;
5650: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69  ....stbuf->st_si
5660: 7a 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 79  ze = pathinfo.ty
5670: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
5680: 69 7a 65 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09  ize;....break;..
5690: 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48  .case APPFS_PATH
56a0: 54 59 50 45 5f 53 4f 43 4b 45 54 3a 0a 09 09 09  TYPE_SOCKET:....
56b0: 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d  stbuf->st_mode =
56c0: 20 53 5f 49 46 53 4f 43 4b 20 7c 20 30 35 35 35   S_IFSOCK | 0555
56d0: 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e  ;....stbuf->st_n
56e0: 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62  link = 1;....stb
56f0: 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 30 3b  uf->st_size = 0;
5700: 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73  ....break;...cas
5710: 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  e APPFS_PATHTYPE
5720: 5f 46 49 46 4f 3a 0a 09 09 09 73 74 62 75 66 2d  _FIFO:....stbuf-
5730: 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 49  >st_mode = S_IFI
5740: 46 4f 20 7c 20 30 35 35 35 3b 0a 09 09 09 73 74  FO | 0555;....st
5750: 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20  buf->st_nlink = 
5760: 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  1;....stbuf->st_
5770: 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 62 72 65  size = 0;....bre
5780: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53  ak;...case APPFS
5790: 5f 50 41 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e  _PATHTYPE_DOES_N
57a0: 4f 54 5f 45 58 49 53 54 3a 0a 09 09 09 72 65 74  OT_EXIST:....ret
57b0: 76 61 6c 20 3d 20 2d 45 4e 4f 45 4e 54 3b 0a 0a  val = -ENOENT;..
57c0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65  ...break;...case
57d0: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
57e0: 49 4e 56 41 4c 49 44 3a 0a 09 09 09 72 65 74 76  INVALID:....retv
57f0: 61 6c 20 3d 20 2d 45 49 4f 3b 0a 0a 09 09 09 62  al = -EIO;.....b
5800: 72 65 61 6b 3b 0a 09 7d 0a 0a 09 69 66 20 28 70  reak;..}...if (p
5810: 61 74 68 69 6e 66 6f 2e 70 61 63 6b 61 67 65 64  athinfo.packaged
5820: 29 20 7b 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f  ) {...stbuf->st_
5830: 75 69 64 20 20 20 3d 20 61 70 70 66 73 5f 67 65  uid   = appfs_ge
5840: 74 5f 66 73 75 69 64 28 29 3b 0a 09 09 73 74 62  t_fsuid();...stb
5850: 75 66 2d 3e 73 74 5f 67 69 64 20 20 20 3d 20 61  uf->st_gid   = a
5860: 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 28 29  ppfs_get_fsgid()
5870: 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ;...stbuf->st_mo
5880: 64 65 20 7c 3d 20 30 32 30 30 3b 0a 09 7d 0a 0a  de |= 0200;..}..
5890: 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b  .return(retval);
58a0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61  .}..static int a
58b0: 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 64 69  ppfs_fuse_readdi
58c0: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  r(const char *pa
58d0: 74 68 2c 20 76 6f 69 64 20 2a 62 75 66 2c 20 66  th, void *buf, f
58e0: 75 73 65 5f 66 69 6c 6c 5f 64 69 72 5f 74 20 66  use_fill_dir_t f
58f0: 69 6c 6c 65 72 2c 20 6f 66 66 5f 74 20 6f 66 66  iller, off_t off
5900: 73 65 74 2c 20 73 74 72 75 63 74 20 66 75 73 65  set, struct fuse
5910: 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20  _file_info *fi) 
5920: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
5930: 6e 74 65 72 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20  nterp;..Tcl_Obj 
5940: 2a 2a 63 68 69 6c 64 72 65 6e 3b 0a 09 69 6e 74  **children;..int
5950: 20 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c   children_count,
5960: 20 69 64 78 3b 0a 09 69 6e 74 20 74 63 6c 5f 72   idx;..int tcl_r
5970: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  et;...APPFS_DEBU
5980: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
5990: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
59a0: 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  );...interp = ap
59b0: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  pfs_TclInterp();
59c0: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
59d0: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
59e0: 28 30 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 50 72  (0);..}...Tcl_Pr
59f0: 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 0a  eserve(interp);.
5a00: 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e  ..filler(buf, ".
5a10: 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 66 69  ", NULL, 0);..fi
5a20: 6c 6c 65 72 28 62 75 66 2c 20 22 2e 2e 22 2c 20  ller(buf, "..", 
5a30: 4e 55 4c 4c 2c 20 30 29 3b 0a 0a 09 74 63 6c 5f  NULL, 0);...tcl_
5a40: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
5a50: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20  Eval(interp, 2, 
5a60: 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 63 68 69  "::appfs::getchi
5a70: 6c 64 72 65 6e 22 2c 20 70 61 74 68 29 3b 0a 09  ldren", path);..
5a80: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
5a90: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
5aa0: 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a  _DEBUG("::appfs:
5ab0: 3a 67 65 74 63 68 69 6c 64 72 65 6e 28 25 73 29  :getchildren(%s)
5ac0: 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29   failed.", path)
5ad0: 3b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
5ae0: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
5af0: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  s", Tcl_GetStrin
5b00: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29  gResult(interp))
5b10: 3b 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73 65  ;....Tcl_Release
5b20: 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74  (interp);....ret
5b30: 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 74 63 6c  urn(0);..}...tcl
5b40: 5f 72 65 74 20 3d 20 54 63 6c 5f 4c 69 73 74 4f  _ret = Tcl_ListO
5b50: 62 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e  bjGetElements(in
5b60: 74 65 72 70 2c 20 54 63 6c 5f 47 65 74 4f 62 6a  terp, Tcl_GetObj
5b70: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 20  Result(interp), 
5b80: 26 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c  &children_count,
5b90: 20 26 63 68 69 6c 64 72 65 6e 29 3b 0a 09 69 66   &children);..if
5ba0: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
5bb0: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
5bc0: 45 42 55 47 28 22 50 61 72 73 69 6e 67 20 6c 69  EBUG("Parsing li
5bd0: 73 74 20 6f 66 20 63 68 69 6c 64 72 65 6e 20 6f  st of children o
5be0: 6e 20 70 61 74 68 20 25 73 20 66 61 69 6c 65 64  n path %s failed
5bf0: 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41 50 50  .", path);...APP
5c00: 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72  FS_DEBUG("Tcl Er
5c10: 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c  ror is: %s", Tcl
5c20: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
5c30: 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 54 63  (interp));....Tc
5c40: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
5c50: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b  );....return(0);
5c60: 0a 09 7d 0a 0a 09 66 6f 72 20 28 69 64 78 20 3d  ..}...for (idx =
5c70: 20 30 3b 20 69 64 78 20 3c 20 63 68 69 6c 64 72   0; idx < childr
5c80: 65 6e 5f 63 6f 75 6e 74 3b 20 69 64 78 2b 2b 29  en_count; idx++)
5c90: 20 7b 0a 09 09 66 69 6c 6c 65 72 28 62 75 66 2c   {...filler(buf,
5ca0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 63   Tcl_GetString(c
5cb0: 68 69 6c 64 72 65 6e 5b 69 64 78 5d 29 2c 20 4e  hildren[idx]), N
5cc0: 55 4c 4c 2c 20 30 29 3b 0a 09 7d 0a 0a 09 54 63  ULL, 0);..}...Tc
5cd0: 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70  l_Release(interp
5ce0: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  );...return(0);.
5cf0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
5d00: 70 66 73 5f 66 75 73 65 5f 6f 70 65 6e 28 63 6f  pfs_fuse_open(co
5d10: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
5d20: 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65  struct fuse_file
5d30: 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63  _info *fi) {..Tc
5d40: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
5d50: 3b 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f  ;..struct appfs_
5d60: 70 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66  pathinfo pathinf
5d70: 6f 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a  o;..const char *
5d80: 72 65 61 6c 5f 70 61 74 68 2c 20 2a 6d 6f 64 65  real_path, *mode
5d90: 3b 0a 09 69 6e 74 20 67 70 69 5f 72 65 74 2c 20  ;..int gpi_ret, 
5da0: 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 66 68  tcl_ret;..int fh
5db0: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
5dc0: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
5dd0: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b  s, ...)", path);
5de0: 0a 0a 09 67 70 69 5f 72 65 74 20 3d 20 61 70 70  ...gpi_ret = app
5df0: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
5e00: 28 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f  (path, &pathinfo
5e10: 29 3b 0a 0a 09 69 66 20 28 28 66 69 2d 3e 66 6c  );...if ((fi->fl
5e20: 61 67 73 20 26 20 28 4f 5f 57 52 4f 4e 4c 59 7c  ags & (O_WRONLY|
5e30: 4f 5f 43 52 45 41 54 29 29 20 3d 3d 20 28 4f 5f  O_CREAT)) == (O_
5e40: 43 52 45 41 54 7c 4f 5f 57 52 4f 4e 4c 59 29 29  CREAT|O_WRONLY))
5e50: 20 7b 0a 09 09 2f 2a 20 54 68 65 20 66 69 6c 65   {.../* The file
5e60: 20 77 69 6c 6c 20 62 65 20 63 72 65 61 74 65 64   will be created
5e70: 20 69 66 20 69 74 20 64 6f 65 73 20 6e 6f 74 20   if it does not 
5e80: 65 78 69 73 74 20 2a 2f 0a 09 09 69 66 20 28 67  exist */...if (g
5e90: 70 69 5f 72 65 74 20 21 3d 20 30 20 26 26 20 67  pi_ret != 0 && g
5ea0: 70 69 5f 72 65 74 20 21 3d 20 2d 45 4e 4f 45 4e  pi_ret != -ENOEN
5eb0: 54 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 67  T) {....return(g
5ec0: 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09  pi_ret);...}....
5ed0: 6d 6f 64 65 20 3d 20 22 63 72 65 61 74 65 22 3b  mode = "create";
5ee0: 0a 0a 09 09 2f 2a 0a 09 09 20 2a 20 57 65 20 68  ..../*... * We h
5ef0: 61 76 65 20 74 6f 20 63 6c 65 61 72 20 74 68 65  ave to clear the
5f00: 20 63 61 63 68 65 20 68 65 72 65 20 73 6f 20 74   cache here so t
5f10: 68 61 74 20 74 68 65 20 6e 75 6d 62 65 72 20 6f  hat the number o
5f20: 66 0a 09 09 20 2a 20 6c 69 6e 6b 73 20 67 65 74  f... * links get
5f30: 73 20 6d 61 69 6e 74 61 69 6e 65 64 20 6f 6e 20  s maintained on 
5f40: 74 68 65 20 70 61 72 65 6e 74 20 64 69 72 65 63  the parent direc
5f50: 74 6f 72 79 0a 09 09 20 2a 2f 0a 09 09 61 70 70  tory... */...app
5f60: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
5f70: 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70  _cache_flush(app
5f80: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20  fs_get_fsuid(), 
5f90: 2d 31 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09  -1);..} else {..
5fa0: 09 2f 2a 20 54 68 65 20 66 69 6c 65 20 6d 75 73  ./* The file mus
5fb0: 74 20 61 6c 72 65 61 64 79 20 65 78 69 73 74 20  t already exist 
5fc0: 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f 72 65 74  */...if (gpi_ret
5fd0: 20 21 3d 20 30 29 20 7b 0a 09 09 09 72 65 74 75   != 0) {....retu
5fe0: 72 6e 28 67 70 69 5f 72 65 74 29 3b 0a 09 09 7d  rn(gpi_ret);...}
5ff0: 0a 0a 09 09 6d 6f 64 65 20 3d 20 22 22 3b 0a 0a  ....mode = "";..
6000: 09 09 69 66 20 28 28 66 69 2d 3e 66 6c 61 67 73  ..if ((fi->flags
6010: 20 26 20 4f 5f 57 52 4f 4e 4c 59 29 20 3d 3d 20   & O_WRONLY) == 
6020: 4f 5f 57 52 4f 4e 4c 59 29 20 7b 0a 09 09 09 6d  O_WRONLY) {....m
6030: 6f 64 65 20 3d 20 22 77 72 69 74 65 22 3b 0a 09  ode = "write";..
6040: 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68  .}..}...if (path
6050: 69 6e 66 6f 2e 74 79 70 65 20 3d 3d 20 41 50 50  info.type == APP
6060: 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45  FS_PATHTYPE_DIRE
6070: 43 54 4f 52 59 29 20 7b 0a 09 09 72 65 74 75 72  CTORY) {...retur
6080: 6e 28 2d 45 49 53 44 49 52 29 3b 0a 09 7d 0a 0a  n(-EISDIR);..}..
6090: 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f  .interp = appfs_
60a0: 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66  TclInterp();..if
60b0: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c   (interp == NULL
60c0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
60d0: 4f 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 50 72 65  O);..}...Tcl_Pre
60e0: 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 0a 0a  serve(interp);..
60f0: 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73  .tcl_ret = appfs
6100: 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70  _Tcl_Eval(interp
6110: 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6f  , 3, "::appfs::o
6120: 70 65 6e 70 61 74 68 22 2c 20 70 61 74 68 2c 20  penpath", path, 
6130: 6d 6f 64 65 29 3b 0a 09 69 66 20 28 74 63 6c 5f  mode);..if (tcl_
6140: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
6150: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
6160: 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74  ::appfs::openpat
6170: 68 28 25 73 2c 20 25 73 29 20 66 61 69 6c 65 64  h(%s, %s) failed
6180: 2e 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65 29 3b  .", path, mode);
6190: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
61a0: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
61b0: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
61c0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
61d0: 0a 0a 09 09 54 63 6c 5f 52 65 6c 65 61 73 65 28  ....Tcl_Release(
61e0: 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75  interp);....retu
61f0: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72  rn(-EIO);..}...r
6200: 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47  eal_path = Tcl_G
6210: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
6220: 6e 74 65 72 70 29 3b 0a 0a 09 54 63 6c 5f 52 65  nterp);...Tcl_Re
6230: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 0a  lease(interp);..
6240: 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d  .if (real_path =
6250: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
6260: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 41  rn(-EIO);..}...A
6270: 50 50 46 53 5f 44 45 42 55 47 28 22 54 72 61 6e  PPFS_DEBUG("Tran
6280: 73 6c 61 74 65 64 20 72 65 71 75 65 73 74 20 74  slated request t
6290: 6f 20 6f 70 65 6e 20 25 73 20 74 6f 20 6f 70 65  o open %s to ope
62a0: 6e 69 6e 67 20 25 73 20 28 6d 6f 64 65 20 3d 20  ning %s (mode = 
62b0: 5c 22 25 73 5c 22 29 22 2c 20 70 61 74 68 2c 20  \"%s\")", path, 
62c0: 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29  real_path, mode)
62d0: 3b 0a 0a 09 66 68 20 3d 20 6f 70 65 6e 28 72 65  ;...fh = open(re
62e0: 61 6c 5f 70 61 74 68 2c 20 66 69 2d 3e 66 6c 61  al_path, fi->fla
62f0: 67 73 2c 20 30 36 30 30 29 3b 0a 0a 09 69 66 20  gs, 0600);...if 
6300: 28 66 68 20 3c 20 30 29 20 7b 0a 09 09 72 65 74  (fh < 0) {...ret
6310: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
6320: 66 69 2d 3e 66 68 20 3d 20 66 68 3b 0a 0a 09 72  fi->fh = fh;...r
6330: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61  eturn(0);.}..sta
6340: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75  tic int appfs_fu
6350: 73 65 5f 63 6c 6f 73 65 28 63 6f 6e 73 74 20 63  se_close(const c
6360: 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63  har *path, struc
6370: 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f  t fuse_file_info
6380: 20 2a 66 69 29 20 7b 0a 09 69 6e 74 20 63 6c 6f   *fi) {..int clo
6390: 73 65 5f 72 65 74 3b 0a 0a 09 61 70 70 66 73 5f  se_ret;...appfs_
63a0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
63b0: 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70 70  che_rm(path, app
63c0: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b  fs_get_fsuid());
63d0: 0a 0a 09 63 6c 6f 73 65 5f 72 65 74 20 3d 20 63  ...close_ret = c
63e0: 6c 6f 73 65 28 66 69 2d 3e 66 68 29 3b 0a 09 69  lose(fi->fh);..i
63f0: 66 20 28 63 6c 6f 73 65 5f 72 65 74 20 21 3d 20  f (close_ret != 
6400: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  0) {...return(-E
6410: 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  IO);..}...return
6420: 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69  (0);.}..static i
6430: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65  nt appfs_fuse_re
6440: 61 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  ad(const char *p
6450: 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c 20  ath, char *buf, 
6460: 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f 66 66  size_t size, off
6470: 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63  _t offset, struc
6480: 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f  t fuse_file_info
6490: 20 2a 66 69 29 20 7b 0a 09 6f 66 66 5f 74 20 6c   *fi) {..off_t l
64a0: 73 65 65 6b 5f 72 65 74 3b 0a 09 73 73 69 7a 65  seek_ret;..ssize
64b0: 5f 74 20 72 65 61 64 5f 72 65 74 3b 0a 0a 09 41  _t read_ret;...A
64c0: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
64d0: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
64e0: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 6c 73  .)", path);...ls
64f0: 65 65 6b 5f 72 65 74 20 3d 20 6c 73 65 65 6b 28  eek_ret = lseek(
6500: 66 69 2d 3e 66 68 2c 20 6f 66 66 73 65 74 2c 20  fi->fh, offset, 
6510: 53 45 45 4b 5f 53 45 54 29 3b 0a 09 69 66 20 28  SEEK_SET);..if (
6520: 6c 73 65 65 6b 5f 72 65 74 20 21 3d 20 6f 66 66  lseek_ret != off
6530: 73 65 74 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  set) {...return(
6540: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65 61 64  -EIO);..}...read
6550: 5f 72 65 74 20 3d 20 72 65 61 64 28 66 69 2d 3e  _ret = read(fi->
6560: 66 68 2c 20 62 75 66 2c 20 73 69 7a 65 29 3b 0a  fh, buf, size);.
6570: 0a 09 72 65 74 75 72 6e 28 72 65 61 64 5f 72 65  ..return(read_re
6580: 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  t);.}..static in
6590: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 77 72 69  t appfs_fuse_wri
65a0: 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  te(const char *p
65b0: 61 74 68 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  ath, const char 
65c0: 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a  *buf, size_t siz
65d0: 65 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c  e, off_t offset,
65e0: 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c   struct fuse_fil
65f0: 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 6f  e_info *fi) {..o
6600: 66 66 5f 74 20 6c 73 65 65 6b 5f 72 65 74 3b 0a  ff_t lseek_ret;.
6610: 09 73 73 69 7a 65 5f 74 20 77 72 69 74 65 5f 72  .ssize_t write_r
6620: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  et;...APPFS_DEBU
6630: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
6640: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
6650: 29 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70  );...appfs_get_p
6660: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72  ath_info_cache_r
6670: 6d 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65  m(path, appfs_ge
6680: 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 6c 73  t_fsuid());...ls
6690: 65 65 6b 5f 72 65 74 20 3d 20 6c 73 65 65 6b 28  eek_ret = lseek(
66a0: 66 69 2d 3e 66 68 2c 20 6f 66 66 73 65 74 2c 20  fi->fh, offset, 
66b0: 53 45 45 4b 5f 53 45 54 29 3b 0a 09 69 66 20 28  SEEK_SET);..if (
66c0: 6c 73 65 65 6b 5f 72 65 74 20 21 3d 20 6f 66 66  lseek_ret != off
66d0: 73 65 74 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  set) {...return(
66e0: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 77 72 69 74  -EIO);..}...writ
66f0: 65 5f 72 65 74 20 3d 20 77 72 69 74 65 28 66 69  e_ret = write(fi
6700: 2d 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a 65 29  ->fh, buf, size)
6710: 3b 0a 0a 09 72 65 74 75 72 6e 28 77 72 69 74 65  ;...return(write
6720: 5f 72 65 74 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  _ret);.}..static
6730: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
6740: 6d 6b 6e 6f 64 28 63 6f 6e 73 74 20 63 68 61 72  mknod(const char
6750: 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d   *path, mode_t m
6760: 6f 64 65 2c 20 64 65 76 5f 74 20 64 65 76 69 63  ode, dev_t devic
6770: 65 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c  e) {..char *real
6780: 5f 70 61 74 68 3b 0a 09 69 6e 74 20 6d 6b 6e 6f  _path;..int mkno
6790: 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  d_ret;...APPFS_D
67a0: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
67b0: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
67c0: 61 74 68 29 3b 0a 0a 09 69 66 20 28 28 6d 6f 64  ath);...if ((mod
67d0: 65 20 26 20 53 5f 49 46 43 48 52 29 20 3d 3d 20  e & S_IFCHR) == 
67e0: 53 5f 49 46 43 48 52 29 20 7b 0a 09 09 72 65 74  S_IFCHR) {...ret
67f0: 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a  urn(-EPERM);..}.
6800: 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f  ..if ((mode & S_
6810: 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49 46 42 4c  IFBLK) == S_IFBL
6820: 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  K) {...return(-E
6830: 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c  PERM);..}...real
6840: 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72  _path = appfs_pr
6850: 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28  epare_to_create(
6860: 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c  path);..if (real
6870: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  _path == NULL) {
6880: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
6890: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  ..}...appfs_simu
68a0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74  late_user_fs_ent
68b0: 65 72 28 29 3b 0a 0a 09 6d 6b 6e 6f 64 5f 72 65  er();...mknod_re
68c0: 74 20 3d 20 6d 6b 6e 6f 64 28 72 65 61 6c 5f 70  t = mknod(real_p
68d0: 61 74 68 2c 20 6d 6f 64 65 2c 20 64 65 76 69 63  ath, mode, devic
68e0: 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75  e);...appfs_simu
68f0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61  late_user_fs_lea
6900: 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61  ve();...free(rea
6910: 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 6d  l_path);...if (m
6920: 6b 6e 6f 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  knod_ret != 0) {
6930: 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20  ...return(errno 
6940: 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  * -1);..}...retu
6950: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn(0);.}..static
6960: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
6970: 63 72 65 61 74 65 28 63 6f 6e 73 74 20 63 68 61  create(const cha
6980: 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20  r *path, mode_t 
6990: 6d 6f 64 65 2c 20 73 74 72 75 63 74 20 66 75 73  mode, struct fus
69a0: 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29  e_file_info *fi)
69b0: 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70   {..char *real_p
69c0: 61 74 68 3b 0a 09 69 6e 74 20 66 64 3b 0a 0a 09  ath;..int fd;...
69d0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
69e0: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
69f0: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69  ..)", path);...i
6a00: 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 43  f ((mode & S_IFC
6a10: 48 52 29 20 3d 3d 20 53 5f 49 46 43 48 52 29 20  HR) == S_IFCHR) 
6a20: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45 52  {...return(-EPER
6a30: 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 6d 6f  M);..}...if ((mo
6a40: 64 65 20 26 20 53 5f 49 46 42 4c 4b 29 20 3d 3d  de & S_IFBLK) ==
6a50: 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09 72 65   S_IFBLK) {...re
6a60: 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d  turn(-EPERM);..}
6a70: 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61  ...real_path = a
6a80: 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f  ppfs_prepare_to_
6a90: 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09 69  create(path);..i
6aa0: 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20  f (real_path == 
6ab0: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
6ac0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70  (-EIO);..}...app
6ad0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
6ae0: 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 66  _fs_enter();...f
6af0: 64 20 3d 20 63 72 65 61 74 28 72 65 61 6c 5f 70  d = creat(real_p
6b00: 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61 70  ath, mode);...ap
6b10: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65  pfs_simulate_use
6b20: 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09  r_fs_leave();...
6b30: 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b  free(real_path);
6b40: 0a 0a 09 69 66 20 28 66 64 20 3c 20 30 29 20 7b  ...if (fd < 0) {
6b50: 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20  ...return(errno 
6b60: 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 66 69 2d 3e  * -1);..}...fi->
6b70: 66 68 20 3d 20 66 64 3b 0a 0a 09 72 65 74 75 72  fh = fd;...retur
6b80: 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20  n(0);.}..static 
6b90: 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 74  int appfs_fuse_t
6ba0: 72 75 6e 63 61 74 65 28 63 6f 6e 73 74 20 63 68  runcate(const ch
6bb0: 61 72 20 2a 70 61 74 68 2c 20 6f 66 66 5f 74 20  ar *path, off_t 
6bc0: 73 69 7a 65 29 20 7b 0a 09 63 68 61 72 20 2a 72  size) {..char *r
6bd0: 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74  eal_path;..int t
6be0: 72 75 6e 63 61 74 65 5f 72 65 74 3b 0a 0a 09 41  runcate_ret;...A
6bf0: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
6c00: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
6c10: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 72 65  .)", path);...re
6c20: 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f  al_path = appfs_
6c30: 6c 6f 63 61 6c 70 61 74 68 28 70 61 74 68 29 3b  localpath(path);
6c40: 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20  ..if (real_path 
6c50: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
6c60: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09  urn(-EIO);..}...
6c70: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
6c80: 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74  nfo_cache_rm(pat
6c90: 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75  h, appfs_get_fsu
6ca0: 69 64 28 29 29 3b 0a 0a 09 61 70 70 66 73 5f 73  id());...appfs_s
6cb0: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
6cc0: 65 6e 74 65 72 28 29 3b 0a 0a 09 74 72 75 6e 63  enter();...trunc
6cd0: 61 74 65 5f 72 65 74 20 3d 20 74 72 75 6e 63 61  ate_ret = trunca
6ce0: 74 65 28 72 65 61 6c 5f 70 61 74 68 2c 20 73 69  te(real_path, si
6cf0: 7a 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d  ze);...appfs_sim
6d00: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65  ulate_user_fs_le
6d10: 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65  ave();...free(re
6d20: 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28  al_path);...if (
6d30: 74 72 75 6e 63 61 74 65 5f 72 65 74 20 21 3d 20  truncate_ret != 
6d40: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 65 72  0) {...return(er
6d50: 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09  rno * -1);..}...
6d60: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74  return(0);.}..st
6d70: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
6d80: 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72  use_unlink_rmdir
6d90: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
6da0: 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70  h) {..Tcl_Interp
6db0: 20 2a 69 6e 74 65 72 70 3b 0a 09 69 6e 74 20 74   *interp;..int t
6dc0: 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f  cl_ret;...APPFS_
6dd0: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
6de0: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
6df0: 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f 67  path);...appfs_g
6e00: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63  et_path_info_cac
6e10: 68 65 5f 66 6c 75 73 68 28 61 70 70 66 73 5f 67  he_flush(appfs_g
6e20: 65 74 5f 66 73 75 69 64 28 29 2c 20 2d 31 29 3b  et_fsuid(), -1);
6e30: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66  ...interp = appf
6e40: 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09  s_TclInterp();..
6e50: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
6e60: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  LL) {...return(-
6e70: 45 49 4f 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72  EIO);..}...tcl_r
6e80: 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45  et = appfs_Tcl_E
6e90: 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22  val(interp, 2, "
6ea0: 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c 69 6e 6b 70  ::appfs::unlinkp
6eb0: 61 74 68 22 2c 20 70 61 74 68 29 3b 0a 09 69 66  ath", path);..if
6ec0: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
6ed0: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
6ee0: 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 75  EBUG("::appfs::u
6ef0: 6e 6c 69 6e 6b 70 61 74 68 28 25 73 29 20 66 61  nlinkpath(%s) fa
6f00: 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09  iled.", path);..
6f10: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63  .APPFS_DEBUG("Tc
6f20: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c  l Error is: %s",
6f30: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
6f40: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a  sult(interp));..
6f50: 09 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  ..Tcl_Release(in
6f60: 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e  terp);....return
6f70: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 54 63 6c  (-EIO);..}...Tcl
6f80: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29  _Release(interp)
6f90: 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  ;...return(0);.}
6fa0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
6fb0: 66 73 5f 66 75 73 65 5f 6d 6b 64 69 72 28 63 6f  fs_fuse_mkdir(co
6fc0: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
6fd0: 6d 6f 64 65 5f 74 20 6d 6f 64 65 29 20 7b 0a 09  mode_t mode) {..
6fe0: 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b  char *real_path;
6ff0: 0a 09 69 6e 74 20 6d 6b 64 69 72 5f 72 65 74 3b  ..int mkdir_ret;
7000: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
7010: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73  Enter (path = %s
7020: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a  , ...)", path);.
7030: 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70  ..real_path = ap
7040: 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63  pfs_prepare_to_c
7050: 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09 69 66  reate(path);..if
7060: 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e   (real_path == N
7070: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
7080: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66  -EIO);..}...appf
7090: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  s_simulate_user_
70a0: 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 6d 6b  fs_enter();...mk
70b0: 64 69 72 5f 72 65 74 20 3d 20 6d 6b 64 69 72 28  dir_ret = mkdir(
70c0: 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 29  real_path, mode)
70d0: 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61  ;...appfs_simula
70e0: 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 65  te_user_fs_leave
70f0: 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f  ();...free(real_
7100: 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 6d 6b 64  path);...if (mkd
7110: 69 72 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ir_ret != 0) {..
7120: 09 69 66 20 28 65 72 72 6e 6f 20 21 3d 20 45 45  .if (errno != EE
7130: 58 49 53 54 29 20 7b 0a 09 09 09 72 65 74 75 72  XIST) {....retur
7140: 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09  n(errno * -1);..
7150: 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30  .}..}...return(0
7160: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
7170: 20 61 70 70 66 73 5f 66 75 73 65 5f 63 68 6d 6f   appfs_fuse_chmo
7180: 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  d(const char *pa
7190: 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 29  th, mode_t mode)
71a0: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
71b0: 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63  interp;..const c
71c0: 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a  har *real_path;.
71d0: 09 69 6e 74 20 74 63 6c 5f 72 65 74 2c 20 63 68  .int tcl_ret, ch
71e0: 6d 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53  mod_ret;...APPFS
71f0: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70  _DEBUG("Enter (p
7200: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c  ath = %s, ...)",
7210: 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 73 5f   path);...appfs_
7220: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61  get_path_info_ca
7230: 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70 70  che_rm(path, app
7240: 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b  fs_get_fsuid());
7250: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66  ...interp = appf
7260: 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09  s_TclInterp();..
7270: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
7280: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  LL) {...return(-
7290: 45 49 4f 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 50  EIO);..}...Tcl_P
72a0: 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b  reserve(interp);
72b0: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70  ...tcl_ret = app
72c0: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65  fs_Tcl_Eval(inte
72d0: 72 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a  rp, 3, "::appfs:
72e0: 3a 6f 70 65 6e 70 61 74 68 22 2c 20 70 61 74 68  :openpath", path
72f0: 2c 20 22 77 72 69 74 65 22 29 3b 0a 09 69 66 20  , "write");..if 
7300: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
7310: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
7320: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6f 70  BUG("::appfs::op
7330: 65 6e 70 61 74 68 28 25 73 2c 20 25 73 29 20 66  enpath(%s, %s) f
7340: 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 2c 20 22  ailed.", path, "
7350: 77 72 69 74 65 22 29 3b 0a 09 09 41 50 50 46 53  write");...APPFS
7360: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
7370: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
7380: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
7390: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 54 63 6c 5f  nterp));....Tcl_
73a0: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b  Release(interp);
73b0: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  ....return(-EIO)
73c0: 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68  ;..}...real_path
73d0: 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67   = Tcl_GetString
73e0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a  Result(interp);.
73f0: 0a 09 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e  ..Tcl_Release(in
7400: 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 72 65 61  terp);...if (rea
7410: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
7420: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
7430: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d  ;..}...appfs_sim
7440: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e  ulate_user_fs_en
7450: 74 65 72 28 29 3b 0a 0a 09 63 68 6d 6f 64 5f 72  ter();...chmod_r
7460: 65 74 20 3d 20 63 68 6d 6f 64 28 72 65 61 6c 5f  et = chmod(real_
7470: 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61  path, mode);...a
7480: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
7490: 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a  er_fs_leave();..
74a0: 09 72 65 74 75 72 6e 28 63 68 6d 6f 64 5f 72 65  .return(chmod_re
74b0: 74 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 53 51 4c  t);.}../*. * SQL
74c0: 69 74 65 33 20 6d 6f 64 65 3a 20 45 78 65 63 75  ite3 mode: Execu
74d0: 74 65 20 72 61 77 20 53 51 4c 20 61 6e 64 20 72  te raw SQL and r
74e0: 65 74 75 72 6e 20 73 75 63 63 65 73 73 20 6f 72  eturn success or
74f0: 20 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74 61   failure. */.sta
7500: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 73 71  tic int appfs_sq
7510: 6c 69 74 65 33 28 63 6f 6e 73 74 20 63 68 61 72  lite3(const char
7520: 20 2a 73 71 6c 29 20 7b 0a 09 54 63 6c 5f 49 6e   *sql) {..Tcl_In
7530: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63  terp *interp;..c
7540: 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 5f 72  onst char *sql_r
7550: 65 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74  et;..int tcl_ret
7560: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  ;...interp = app
7570: 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74  fs_create_TclInt
7580: 65 72 70 28 4e 55 4c 4c 29 3b 0a 09 69 66 20 28  erp(NULL);..if (
7590: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
75a0: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  {...fprintf(stde
75b0: 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63  rr, "Unable to c
75c0: 72 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65  reate a Tcl inte
75d0: 72 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69  rpreter.  Aborti
75e0: 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75  ng.\n");....retu
75f0: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f  rn(1);..}...tcl_
7600: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f  ret = appfs_Tcl_
7610: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 35 2c 20  Eval(interp, 5, 
7620: 22 3a 3a 61 70 70 66 73 3a 3a 64 62 22 2c 20 22  "::appfs::db", "
7630: 65 76 61 6c 22 2c 20 73 71 6c 2c 20 22 72 6f 77  eval", sql, "row
7640: 22 2c 20 22 75 6e 73 65 74 20 2d 6e 6f 63 6f 6d  ", "unset -nocom
7650: 70 6c 61 69 6e 20 72 6f 77 28 2a 29 3b 20 70 61  plain row(*); pa
7660: 72 72 61 79 20 72 6f 77 3b 20 70 75 74 73 20 5c  rray row; puts \
7670: 22 2d 2d 2d 2d 5c 22 22 29 3b 0a 09 73 71 6c 5f  "----\"");..sql_
7680: 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  ret = Tcl_GetStr
7690: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
76a0: 29 3b 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  );...if (tcl_ret
76b0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
76c0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
76d0: 22 5b 65 72 72 6f 72 5d 20 25 73 5c 6e 22 2c 20  "[error] %s\n", 
76e0: 73 71 6c 5f 72 65 74 29 3b 0a 0a 09 09 72 65 74  sql_ret);....ret
76f0: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 69 66 20  urn(1);..}...if 
7700: 28 73 71 6c 5f 72 65 74 20 26 26 20 73 71 6c 5f  (sql_ret && sql_
7710: 72 65 74 5b 30 5d 20 21 3d 20 27 5c 30 27 29 20  ret[0] != '\0') 
7720: 7b 0a 09 09 70 72 69 6e 74 66 28 22 25 73 5c 6e  {...printf("%s\n
7730: 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a 09 7d 0a  ", sql_ret);..}.
7740: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
7750: 2f 2a 0a 20 2a 20 54 63 6c 20 6d 6f 64 65 3a 20  /*. * Tcl mode: 
7760: 45 78 65 63 75 74 65 20 72 61 77 20 54 63 6c 20  Execute raw Tcl 
7770: 61 6e 64 20 72 65 74 75 72 6e 20 73 75 63 63 65  and return succe
7780: 73 73 20 6f 72 20 66 61 69 6c 75 72 65 0a 20 2a  ss or failure. *
7790: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  /.static int app
77a0: 66 73 5f 74 63 6c 28 63 6f 6e 73 74 20 63 68 61  fs_tcl(const cha
77b0: 72 20 2a 74 63 6c 29 20 7b 0a 09 54 63 6c 5f 49  r *tcl) {..Tcl_I
77c0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09  nterp *interp;..
77d0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c 5f  const char *tcl_
77e0: 72 65 73 75 6c 74 3b 0a 09 69 6e 74 20 74 63 6c  result;..int tcl
77f0: 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d  _ret;...interp =
7800: 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63   appfs_create_Tc
7810: 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 09  lInterp(NULL);..
7820: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55  if (interp == NU
7830: 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28  LL) {...fprintf(
7840: 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20  stderr, "Unable 
7850: 74 6f 20 63 72 65 61 74 65 20 61 20 54 63 6c 20  to create a Tcl 
7860: 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41 62  interpreter.  Ab
7870: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09  orting.\n");....
7880: 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09  return(1);..}...
7890: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76  tcl_ret = Tcl_Ev
78a0: 61 6c 28 69 6e 74 65 72 70 2c 20 74 63 6c 29 3b  al(interp, tcl);
78b0: 0a 09 74 63 6c 5f 72 65 73 75 6c 74 20 3d 20 54  ..tcl_result = T
78c0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
78d0: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66  lt(interp);...if
78e0: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
78f0: 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  _OK) {...fprintf
7900: 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72 6f 72  (stderr, "[error
7910: 5d 20 25 73 5c 6e 22 2c 20 74 63 6c 5f 72 65 73  ] %s\n", tcl_res
7920: 75 6c 74 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  ult);....return(
7930: 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 74 63 6c  1);..}...if (tcl
7940: 5f 72 65 73 75 6c 74 20 26 26 20 74 63 6c 5f 72  _result && tcl_r
7950: 65 73 75 6c 74 5b 30 5d 20 21 3d 20 27 5c 30 27  esult[0] != '\0'
7960: 29 20 7b 0a 09 09 70 72 69 6e 74 66 28 22 25 73  ) {...printf("%s
7970: 5c 6e 22 2c 20 74 63 6c 5f 72 65 73 75 6c 74 29  \n", tcl_result)
7980: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29  ;..}...return(0)
7990: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53  ;.}../*. * AppFS
79a0: 64 20 50 61 63 6b 61 67 65 20 66 6f 72 20 54 63  d Package for Tc
79b0: 6c 3a 0a 20 2a 20 20 20 20 20 20 20 20 20 42 72  l:. *         Br
79c0: 69 64 67 65 20 66 6f 72 20 49 2f 4f 20 6f 70 65  idge for I/O ope
79d0: 72 61 74 69 6f 6e 73 20 74 6f 20 72 65 71 75 65  rations to reque
79e0: 73 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61  st information a
79f0: 62 6f 75 74 20 74 68 65 20 63 75 72 72 65 6e 74  bout the current
7a00: 0a 20 2a 20 20 20 20 20 20 20 20 20 74 72 61 6e  . *         tran
7a10: 73 61 63 74 69 6f 6e 0a 20 2a 2f 0a 2f 2a 0a 20  saction. */./*. 
7a20: 2a 20 54 63 6c 20 69 6e 74 65 72 66 61 63 65 20  * Tcl interface 
7a30: 74 6f 20 67 65 74 20 74 68 65 20 68 6f 6d 65 20  to get the home 
7a40: 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20 74 68  directory for th
7a50: 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74 68  e user making th
7a60: 65 20 22 63 75 72 72 65 6e 74 22 0a 20 2a 20 46  e "current". * F
7a70: 55 53 45 20 49 2f 4f 20 72 65 71 75 65 73 74 0a  USE I/O request.
7a80: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74   */.static int t
7a90: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d  cl_appfs_get_hom
7aa0: 65 64 69 72 28 43 6c 69 65 6e 74 44 61 74 61 20  edir(ClientData 
7ab0: 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  cd, Tcl_Interp *
7ac0: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63  interp, int objc
7ad0: 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54  , Tcl_Obj *CONST
7ae0: 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 63 68 61 72   objv[]) {..char
7af0: 20 2a 68 6f 6d 65 64 69 72 3b 0a 09 54 63 6c 5f   *homedir;..Tcl_
7b00: 4f 62 6a 20 2a 68 6f 6d 65 64 69 72 5f 6f 62 6a  Obj *homedir_obj
7b10: 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a  ;..uid_t fsuid;.
7b20: 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64  .static __thread
7b30: 20 54 63 6c 5f 4f 62 6a 20 2a 6c 61 73 74 5f 68   Tcl_Obj *last_h
7b40: 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 4e 55 4c  omedir_obj = NUL
7b50: 4c 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72  L;..static __thr
7b60: 65 61 64 20 75 69 64 5f 74 20 6c 61 73 74 5f 66  ead uid_t last_f
7b70: 73 75 69 64 20 3d 20 2d 31 3b 0a 0a 20 20 20 20  suid = -1;..    
7b80: 20 20 20 20 69 66 20 28 6f 62 6a 63 20 21 3d 20      if (objc != 
7b90: 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20  1) {.           
7ba0: 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75       Tcl_WrongNu
7bb0: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
7bc0: 20 6f 62 6a 76 2c 20 4e 55 4c 4c 29 3b 0a 20 20   objv, NULL);.  
7bd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72 65                re
7be0: 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b  turn(TCL_ERROR);
7bf0: 0a 20 20 20 20 20 20 20 20 7d 0a 0a 09 66 73 75  .        }...fsu
7c00: 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66  id = appfs_get_f
7c10: 73 75 69 64 28 29 3b 0a 0a 09 69 66 20 28 66 73  suid();...if (fs
7c20: 75 69 64 20 3d 3d 20 6c 61 73 74 5f 66 73 75 69  uid == last_fsui
7c30: 64 20 26 26 20 6c 61 73 74 5f 68 6f 6d 65 64 69  d && last_homedi
7c40: 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b  r_obj != NULL) {
7c50: 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d  ...homedir_obj =
7c60: 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62   last_homedir_ob
7c70: 6a 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 68  j;..} else {...h
7c80: 6f 6d 65 64 69 72 20 3d 20 61 70 70 66 73 5f 67  omedir = appfs_g
7c90: 65 74 5f 68 6f 6d 65 64 69 72 28 61 70 70 66 73  et_homedir(appfs
7ca0: 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a  _get_fsuid());..
7cb0: 09 09 69 66 20 28 68 6f 6d 65 64 69 72 20 3d 3d  ..if (homedir ==
7cc0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74 75   NULL) {....retu
7cd0: 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09  rn(TCL_ERROR);..
7ce0: 09 7d 0a 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62  .}....homedir_ob
7cf0: 6a 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e  j = Tcl_NewStrin
7d00: 67 4f 62 6a 28 68 6f 6d 65 64 69 72 2c 20 2d 31  gObj(homedir, -1
7d10: 29 3b 0a 0a 09 09 66 72 65 65 28 68 6f 6d 65 64  );....free(homed
7d20: 69 72 29 3b 0a 0a 09 09 69 66 20 28 6c 61 73 74  ir);....if (last
7d30: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 21 3d 20  _homedir_obj != 
7d40: 4e 55 4c 4c 29 20 7b 0a 09 09 09 54 63 6c 5f 44  NULL) {....Tcl_D
7d50: 65 63 72 52 65 66 43 6f 75 6e 74 28 6c 61 73 74  ecrRefCount(last
7d60: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09  _homedir_obj);..
7d70: 09 7d 0a 0a 09 09 6c 61 73 74 5f 68 6f 6d 65 64  .}....last_homed
7d80: 69 72 5f 6f 62 6a 20 3d 20 68 6f 6d 65 64 69 72  ir_obj = homedir
7d90: 5f 6f 62 6a 3b 0a 09 09 6c 61 73 74 5f 66 73 75  _obj;...last_fsu
7da0: 69 64 20 3d 20 66 73 75 69 64 3b 0a 0a 09 09 54  id = fsuid;....T
7db0: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28  cl_IncrRefCount(
7dc0: 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a  last_homedir_obj
7dd0: 29 3b 0a 09 7d 0a 0a 20 20 20 20 20 20 20 09 54  );..}..       .T
7de0: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
7df0: 69 6e 74 65 72 70 2c 20 68 6f 6d 65 64 69 72 5f  interp, homedir_
7e00: 6f 62 6a 29 3b 0a 0a 20 20 20 20 20 20 20 20 72  obj);..        r
7e10: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d  eturn(TCL_OK);.}
7e20: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c  ..static int tcl
7e30: 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f  _appfs_simulate_
7e40: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 43 6c  user_fs_enter(Cl
7e50: 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c  ientData cd, Tcl
7e60: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
7e70: 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f   int objc, Tcl_O
7e80: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
7e90: 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c  ) {..appfs_simul
7ea0: 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65  ate_user_fs_ente
7eb0: 72 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43  r();...return(TC
7ec0: 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  L_OK);.}..static
7ed0: 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f 73   int tcl_appfs_s
7ee0: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f  imulate_user_fs_
7ef0: 6c 65 61 76 65 28 43 6c 69 65 6e 74 44 61 74 61  leave(ClientData
7f00: 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20   cd, Tcl_Interp 
7f10: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a  *interp, int obj
7f20: 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  c, Tcl_Obj *CONS
7f30: 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70 70  T objv[]) {..app
7f40: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  fs_simulate_user
7f50: 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 72  _fs_leave();...r
7f60: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d  eturn(TCL_OK);.}
7f70: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c  ..static int tcl
7f80: 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64  _appfs_get_fsuid
7f90: 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20  (ClientData cd, 
7fa0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
7fb0: 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63  rp, int objc, Tc
7fc0: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
7fd0: 76 5b 5d 29 20 7b 0a 09 75 69 64 5f 74 20 66 73  v[]) {..uid_t fs
7fe0: 75 69 64 3b 0a 0a 09 66 73 75 69 64 20 3d 20 61  uid;...fsuid = a
7ff0: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29  ppfs_get_fsuid()
8000: 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53  ;..       .Tcl_S
8010: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65  etObjResult(inte
8020: 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65 49  rp, Tcl_NewWideI
8030: 6e 74 4f 62 6a 28 66 73 75 69 64 29 29 3b 0a 0a  ntObj(fsuid));..
8040: 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b  .return(TCL_OK);
8050: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74  .}..static int t
8060: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 67  cl_appfs_get_fsg
8070: 69 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64  id(ClientData cd
8080: 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  , Tcl_Interp *in
8090: 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20  terp, int objc, 
80a0: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
80b0: 62 6a 76 5b 5d 29 20 7b 0a 09 67 69 64 5f 74 20  bjv[]) {..gid_t 
80c0: 66 73 67 69 64 3b 0a 0a 09 66 73 67 69 64 20 3d  fsgid;...fsgid =
80d0: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64   appfs_get_fsgid
80e0: 28 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c  ();..       .Tcl
80f0: 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e  _SetObjResult(in
8100: 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64  terp, Tcl_NewWid
8110: 65 49 6e 74 4f 62 6a 28 66 73 67 69 64 29 29 3b  eIntObj(fsgid));
8120: 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b  ...return(TCL_OK
8130: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74  );.}..static int
8140: 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 70   tcl_appfs_get_p
8150: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66  ath_info_cache_f
8160: 6c 75 73 68 28 43 6c 69 65 6e 74 44 61 74 61 20  lush(ClientData 
8170: 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  cd, Tcl_Interp *
8180: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63  interp, int objc
8190: 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54  , Tcl_Obj *CONST
81a0: 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 69 6e 74 20   objv[]) {..int 
81b0: 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 6e 65  tcl_ret;..int ne
81c0: 77 5f 73 69 7a 65 3b 0a 0a 09 6e 65 77 5f 73 69  w_size;...new_si
81d0: 7a 65 20 3d 20 2d 31 3b 0a 0a 09 69 66 20 28 6f  ze = -1;...if (o
81e0: 62 6a 63 20 3d 3d 20 32 29 20 7b 0a 09 09 74 63  bjc == 2) {...tc
81f0: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 49  l_ret = Tcl_GetI
8200: 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70  ntFromObj(interp
8210: 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26 6e 65 77 5f  , objv[1], &new_
8220: 73 69 7a 65 29 3b 0a 09 09 69 66 20 28 74 63 6c  size);...if (tcl
8230: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20  _ret != TCL_OK) 
8240: 7b 0a 09 09 09 72 65 74 75 72 6e 28 74 63 6c 5f  {....return(tcl_
8250: 72 65 74 29 3b 0a 09 09 7d 0a 09 7d 20 65 6c 73  ret);...}..} els
8260: 65 20 69 66 20 28 6f 62 6a 63 20 3e 20 32 20 7c  e if (objc > 2 |
8270: 7c 20 6f 62 6a 63 20 3c 20 31 29 20 7b 0a 20 20  | objc < 1) {.  
8280: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 63                Tc
8290: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69  l_WrongNumArgs(i
82a0: 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20  nterp, 1, objv, 
82b0: 22 3f 6e 65 77 5f 63 61 63 68 65 5f 73 69 7a 65  "?new_cache_size
82c0: 3f 22 29 3b 0a 09 09 72 65 74 75 72 6e 28 54 43  ?");...return(TC
82d0: 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09 61  L_ERROR);..}...a
82e0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e  ppfs_get_path_in
82f0: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d  fo_cache_flush(-
8300: 31 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a 09  1, new_size);...
8310: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a  return(TCL_OK);.
8320: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 41 70  }..static int Ap
8330: 70 66 73 64 5f 49 6e 69 74 28 54 63 6c 5f 49 6e  pfsd_Init(Tcl_In
8340: 74 65 72 70 20 2a 69 6e 74 65 72 70 29 20 7b 0a  terp *interp) {.
8350: 23 69 66 64 65 66 20 55 53 45 5f 54 43 4c 5f 53  #ifdef USE_TCL_S
8360: 54 55 42 53 0a 09 69 66 20 28 54 63 6c 5f 49 6e  TUBS..if (Tcl_In
8370: 69 74 53 74 75 62 73 28 69 6e 74 65 72 70 2c 20  itStubs(interp, 
8380: 54 43 4c 5f 56 45 52 53 49 4f 4e 2c 20 30 29 20  TCL_VERSION, 0) 
8390: 3d 3d 20 30 4c 29 20 7b 0a 09 09 72 65 74 75 72  == 0L) {...retur
83a0: 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d  n(TCL_ERROR);..}
83b0: 0a 23 65 6e 64 69 66 0a 0a 09 54 63 6c 5f 43 72  .#endif...Tcl_Cr
83c0: 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69  eateObjCommand(i
83d0: 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a  nterp, "appfsd::
83e0: 67 65 74 5f 68 6f 6d 65 64 69 72 22 2c 20 74 63  get_homedir", tc
83f0: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65  l_appfs_get_home
8400: 64 69 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29  dir, NULL, NULL)
8410: 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a  ;..Tcl_CreateObj
8420: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
8430: 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 66 73 75  "appfsd::get_fsu
8440: 69 64 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67  id", tcl_appfs_g
8450: 65 74 5f 66 73 75 69 64 2c 20 4e 55 4c 4c 2c 20  et_fsuid, NULL, 
8460: 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61  NULL);..Tcl_Crea
8470: 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74  teObjCommand(int
8480: 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65  erp, "appfsd::ge
8490: 74 5f 66 73 67 69 64 22 2c 20 74 63 6c 5f 61 70  t_fsgid", tcl_ap
84a0: 70 66 73 5f 67 65 74 5f 66 73 67 69 64 2c 20 4e  pfs_get_fsgid, N
84b0: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c  ULL, NULL);..Tcl
84c0: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e  _CreateObjComman
84d0: 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73  d(interp, "appfs
84e0: 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65 72  d::simulate_user
84f0: 5f 66 73 5f 65 6e 74 65 72 22 2c 20 74 63 6c 5f  _fs_enter", tcl_
8500: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75  appfs_simulate_u
8510: 73 65 72 5f 66 73 5f 65 6e 74 65 72 2c 20 4e 55  ser_fs_enter, NU
8520: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f  LL, NULL);..Tcl_
8530: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64  CreateObjCommand
8540: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64  (interp, "appfsd
8550: 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f  ::simulate_user_
8560: 66 73 5f 6c 65 61 76 65 22 2c 20 74 63 6c 5f 61  fs_leave", tcl_a
8570: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73  ppfs_simulate_us
8580: 65 72 5f 66 73 5f 6c 65 61 76 65 2c 20 4e 55 4c  er_fs_leave, NUL
8590: 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43  L, NULL);..Tcl_C
85a0: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28  reateObjCommand(
85b0: 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a  interp, "appfsd:
85c0: 3a 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63  :get_path_info_c
85d0: 61 63 68 65 5f 66 6c 75 73 68 22 2c 20 74 63 6c  ache_flush", tcl
85e0: 5f 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f  _appfs_get_path_
85f0: 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68  info_cache_flush
8600: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 0a  , NULL, NULL);..
8610: 09 54 63 6c 5f 50 6b 67 50 72 6f 76 69 64 65 28  .Tcl_PkgProvide(
8620: 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 22  interp, "appfsd"
8630: 2c 20 22 31 2e 30 22 29 3b 0a 0a 09 72 65 74 75  , "1.0");...retu
8640: 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 2f  rn(TCL_OK);.}../
8650: 2a 0a 20 2a 20 48 6f 74 2d 72 65 73 74 61 72 74  *. * Hot-restart
8660: 20 73 75 70 70 6f 72 74 0a 20 2a 2f 0a 2f 2a 20   support. */./* 
8670: 49 6e 69 74 69 61 74 65 20 61 20 68 6f 74 2d 72  Initiate a hot-r
8680: 65 73 74 61 72 74 20 2a 2f 0a 73 74 61 74 69 63  estart */.static
8690: 20 76 6f 69 64 20 61 70 70 66 73 5f 68 6f 74 5f   void appfs_hot_
86a0: 72 65 73 74 61 72 74 28 76 6f 69 64 29 20 7b 0a  restart(void) {.
86b0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 41 73  .APPFS_DEBUG("As
86c0: 6b 65 64 20 74 6f 20 69 6e 69 74 69 61 74 65 20  ked to initiate 
86d0: 68 6f 74 20 72 65 73 74 61 72 74 22 29 3b 0a 0a  hot restart");..
86e0: 09 61 70 70 66 73 5f 74 63 6c 5f 52 65 73 65 74  .appfs_tcl_Reset
86f0: 49 6e 74 65 72 70 73 28 29 3b 0a 09 61 70 70 66  Interps();..appf
8700: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f  s_get_path_info_
8710: 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 2c 20  cache_flush(-1, 
8720: 2d 31 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d  -1);...return;.}
8730: 0a 0a 2f 2a 0a 20 2a 20 53 69 67 6e 61 6c 20 68  ../*. * Signal h
8740: 61 6e 64 6c 65 72 0a 20 2a 20 20 20 20 20 20 20  andler. *       
8750: 20 20 53 49 47 48 55 50 20 69 6e 69 74 69 61 74    SIGHUP initiat
8760: 65 73 20 61 20 68 6f 74 20 72 65 73 74 61 72 74  es a hot restart
8770: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  . */.static void
8780: 20 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f 68 61   appfs_signal_ha
8790: 6e 64 6c 65 72 28 69 6e 74 20 73 69 67 29 20 7b  ndler(int sig) {
87a0: 0a 09 2f 2a 20 44 6f 20 6e 6f 74 20 68 61 6e 64  ../* Do not hand
87b0: 6c 65 20 73 69 67 6e 61 6c 73 20 75 6e 74 69 6c  le signals until
87c0: 20 46 55 53 45 20 68 61 73 20 62 65 65 6e 20 73   FUSE has been s
87d0: 74 61 72 74 65 64 20 2a 2f 0a 09 69 66 20 28 21  tarted */..if (!
87e0: 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74  appfs_fuse_start
87f0: 65 64 29 20 7b 0a 09 09 72 65 74 75 72 6e 3b 0a  ed) {...return;.
8800: 09 7d 0a 0a 09 2f 2a 20 52 65 71 75 65 73 74 20  .}.../* Request 
8810: 74 6f 20 70 65 72 66 6f 72 6d 20 61 20 22 68 6f  to perform a "ho
8820: 74 22 20 72 65 73 74 61 72 74 20 2a 2f 0a 09 69  t" restart */..i
8830: 66 20 28 73 69 67 20 3d 3d 20 53 49 47 48 55 50  f (sig == SIGHUP
8840: 29 20 7b 0a 09 09 61 70 70 66 73 5f 68 6f 74 5f  ) {...appfs_hot_
8850: 72 65 73 74 61 72 74 28 29 3b 0a 09 7d 0a 0a 09  restart();..}...
8860: 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  return;.}../*. *
8870: 20 46 55 53 45 20 6f 70 65 72 61 74 69 6f 6e 73   FUSE operations
8880: 20 73 74 72 75 63 74 75 72 65 0a 20 2a 2f 0a 73   structure. */.s
8890: 74 61 74 69 63 20 73 74 72 75 63 74 20 66 75 73  tatic struct fus
88a0: 65 5f 6f 70 65 72 61 74 69 6f 6e 73 20 61 70 70  e_operations app
88b0: 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 20 3d 20  fs_operations = 
88c0: 7b 0a 09 2e 67 65 74 61 74 74 72 20 20 20 3d 20  {...getattr   = 
88d0: 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74 61 74  appfs_fuse_getat
88e0: 74 72 2c 0a 09 2e 72 65 61 64 64 69 72 20 20 20  tr,...readdir   
88f0: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61  = appfs_fuse_rea
8900: 64 64 69 72 2c 0a 09 2e 72 65 61 64 6c 69 6e 6b  ddir,...readlink
8910: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72    = appfs_fuse_r
8920: 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f 70 65 6e 20  eadlink,...open 
8930: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
8940: 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65 6c 65 61 73  e_open,...releas
8950: 65 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  e   = appfs_fuse
8960: 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65 61 64 20 20  _close,...read  
8970: 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65      = appfs_fuse
8980: 5f 72 65 61 64 2c 0a 09 2e 77 72 69 74 65 20 20  _read,...write  
8990: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
89a0: 77 72 69 74 65 2c 0a 09 2e 6d 6b 6e 6f 64 20 20  write,...mknod  
89b0: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
89c0: 6d 6b 6e 6f 64 2c 0a 09 2e 63 72 65 61 74 65 20  mknod,...create 
89d0: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f     = appfs_fuse_
89e0: 63 72 65 61 74 65 2c 0a 09 2e 74 72 75 6e 63 61  create,...trunca
89f0: 74 65 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  te  = appfs_fuse
8a00: 5f 74 72 75 6e 63 61 74 65 2c 0a 09 2e 75 6e 6c  _truncate,...unl
8a10: 69 6e 6b 20 20 20 20 3d 20 61 70 70 66 73 5f 66  ink    = appfs_f
8a20: 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72  use_unlink_rmdir
8a30: 2c 0a 09 2e 72 6d 64 69 72 20 20 20 20 20 3d 20  ,...rmdir     = 
8a40: 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e  appfs_fuse_unlin
8a50: 6b 5f 72 6d 64 69 72 2c 0a 09 2e 6d 6b 64 69 72  k_rmdir,...mkdir
8a60: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
8a70: 65 5f 6d 6b 64 69 72 2c 0a 09 2e 63 68 6d 6f 64  e_mkdir,...chmod
8a80: 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73       = appfs_fus
8a90: 65 5f 63 68 6d 6f 64 2c 0a 7d 3b 0a 0a 2f 2a 0a  e_chmod,.};../*.
8aa0: 20 2a 20 46 55 53 45 20 6f 70 74 69 6f 6e 20 70   * FUSE option p
8ab0: 61 72 73 69 6e 67 20 63 61 6c 6c 62 61 63 6b 0a  arsing callback.
8ac0: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61   */.static int a
8ad0: 70 70 66 73 5f 66 75 73 65 5f 6f 70 74 5f 63 62  ppfs_fuse_opt_cb
8ae0: 28 76 6f 69 64 20 2a 64 61 74 61 2c 20 63 6f 6e  (void *data, con
8af0: 73 74 20 63 68 61 72 20 2a 61 72 67 2c 20 69 6e  st char *arg, in
8b00: 74 20 6b 65 79 2c 20 73 74 72 75 63 74 20 66 75  t key, struct fu
8b10: 73 65 5f 61 72 67 73 20 2a 6f 75 74 61 72 67 73  se_args *outargs
8b20: 29 20 7b 0a 09 73 74 61 74 69 63 20 69 6e 74 20  ) {..static int 
8b30: 73 65 65 6e 5f 63 61 63 68 65 64 69 72 20 3d 20  seen_cachedir = 
8b40: 30 3b 0a 0a 09 69 66 20 28 6b 65 79 20 3d 3d 20  0;...if (key == 
8b50: 46 55 53 45 5f 4f 50 54 5f 4b 45 59 5f 4e 4f 4e  FUSE_OPT_KEY_NON
8b60: 4f 50 54 20 26 26 20 73 65 65 6e 5f 63 61 63 68  OPT && seen_cach
8b70: 65 64 69 72 20 3d 3d 20 30 29 20 7b 0a 09 09 73  edir == 0) {...s
8b80: 65 65 6e 5f 63 61 63 68 65 64 69 72 20 3d 20 31  een_cachedir = 1
8b90: 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 63 68 65  ;....appfs_cache
8ba0: 64 69 72 20 3d 20 73 74 72 64 75 70 28 61 72 67  dir = strdup(arg
8bb0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b  );....return(0);
8bc0: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 31 29 3b  ..}...return(1);
8bd0: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 6e 74 72 79 20  .}../*. * Entry 
8be0: 70 6f 69 6e 74 20 69 6e 74 6f 20 74 68 69 73 20  point into this 
8bf0: 70 72 6f 67 72 61 6d 2e 0a 20 2a 2f 0a 69 6e 74  program.. */.int
8c00: 20 6d 61 69 6e 28 69 6e 74 20 61 72 67 63 2c 20   main(int argc, 
8c10: 63 68 61 72 20 2a 2a 61 72 67 76 29 20 7b 0a 09  char **argv) {..
8c20: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 74 65 73 74  Tcl_Interp *test
8c30: 5f 69 6e 74 65 72 70 3b 0a 09 63 68 61 72 20 2a  _interp;..char *
8c40: 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f  test_interp_erro
8c50: 72 3b 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f  r;..struct fuse_
8c60: 61 72 67 73 20 61 72 67 73 20 3d 20 46 55 53 45  args args = FUSE
8c70: 5f 41 52 47 53 5f 49 4e 49 54 28 61 72 67 63 2c  _ARGS_INIT(argc,
8c80: 20 61 72 67 76 29 3b 0a 09 69 6e 74 20 70 74 68   argv);..int pth
8c90: 72 65 61 64 5f 72 65 74 3b 0a 09 76 6f 69 64 20  read_ret;..void 
8ca0: 2a 73 69 67 6e 61 6c 5f 72 65 74 3b 0a 0a 09 2f  *signal_ret;.../
8cb0: 2a 0a 09 20 2a 20 53 6b 69 70 20 70 61 73 73 65  *.. * Skip passe
8cc0: 64 20 70 72 6f 67 72 61 6d 20 6e 61 6d 65 0a 09  d program name..
8cd0: 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d   */..if (argc ==
8ce0: 20 30 20 7c 7c 20 61 72 67 76 20 3d 3d 20 4e 55   0 || argv == NU
8cf0: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 31  LL) {...return(1
8d00: 29 3b 0a 09 7d 0a 09 61 72 67 63 2d 2d 3b 0a 09  );..}..argc--;..
8d10: 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09 20 2a  argv++;.../*.. *
8d20: 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69   Set global vari
8d30: 61 62 6c 65 73 2c 20 74 68 65 73 65 20 73 68 6f  ables, these sho
8d40: 75 6c 64 20 62 65 20 63 6f 6e 66 69 67 75 72 61  uld be configura
8d50: 74 69 6f 6e 20 6f 70 74 69 6f 6e 73 2e 0a 09 20  tion options... 
8d60: 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65 64  */..appfs_cached
8d70: 69 72 20 3d 20 41 50 50 46 53 5f 43 41 43 48 45  ir = APPFS_CACHE
8d80: 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65  DIR;.../*.. * Se
8d90: 74 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c  t global variabl
8da0: 65 20 66 6f 72 20 22 62 6f 6f 74 20 74 69 6d 65  e for "boot time
8db0: 22 20 74 6f 20 73 65 74 20 61 20 74 69 6d 65 20  " to set a time 
8dc0: 6f 6e 20 64 69 72 65 63 74 6f 72 69 65 73 0a 09  on directories..
8dd0: 20 2a 20 74 68 61 74 20 77 65 20 66 61 6b 65 2e   * that we fake.
8de0: 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 62 6f 6f  .. */..appfs_boo
8df0: 74 74 69 6d 65 20 3d 20 74 69 6d 65 28 4e 55 4c  ttime = time(NUL
8e00: 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 67  L);.../*.. * Reg
8e10: 69 73 74 65 72 20 22 73 68 61 31 22 20 61 6e 64  ister "sha1" and
8e20: 20 22 61 70 70 66 73 64 22 20 70 61 63 6b 61 67   "appfsd" packag
8e30: 65 20 77 69 74 68 20 6c 69 62 74 63 6c 20 73 6f  e with libtcl so
8e40: 20 74 68 61 74 20 61 6e 79 20 6e 65 77 0a 09 20   that any new.. 
8e50: 2a 20 69 6e 74 65 72 70 72 65 74 65 72 73 20 63  * interpreters c
8e60: 72 65 61 74 65 64 20 28 77 68 69 63 68 20 61 72  reated (which ar
8e70: 65 20 64 6f 6e 65 20 64 79 6e 61 6d 69 63 61 6c  e done dynamical
8e80: 6c 79 20 62 79 20 46 55 53 45 29 20 63 61 6e 20  ly by FUSE) can 
8e90: 68 61 76 65 0a 09 20 2a 20 74 68 65 20 61 70 70  have.. * the app
8ea0: 72 6f 70 72 69 61 74 65 20 63 6f 6e 66 69 67 75  ropriate configu
8eb0: 72 61 74 69 6f 6e 20 64 6f 6e 65 20 61 75 74 6f  ration done auto
8ec0: 6d 61 74 69 63 61 6c 6c 79 2e 0a 09 20 2a 2f 0a  matically... */.
8ed0: 09 54 63 6c 5f 53 74 61 74 69 63 50 61 63 6b 61  .Tcl_StaticPacka
8ee0: 67 65 28 4e 55 4c 4c 2c 20 22 73 68 61 31 22 2c  ge(NULL, "sha1",
8ef0: 20 53 68 61 31 5f 49 6e 69 74 2c 20 4e 55 4c 4c   Sha1_Init, NULL
8f00: 29 3b 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61  );..Tcl_StaticPa
8f10: 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 61 70 70  ckage(NULL, "app
8f20: 66 73 64 22 2c 20 41 70 70 66 73 64 5f 49 6e 69  fsd", Appfsd_Ini
8f30: 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09  t, NULL);.../*..
8f40: 20 2a 20 43 72 65 61 74 65 20 61 20 74 68 72 65   * Create a thre
8f50: 61 64 2d 73 70 65 63 69 66 69 63 2d 64 61 74 61  ad-specific-data
8f60: 20 28 54 53 44 29 20 6b 65 79 20 66 6f 72 20 65   (TSD) key for e
8f70: 61 63 68 20 74 68 72 65 61 64 20 74 6f 20 72 65  ach thread to re
8f80: 66 65 72 0a 09 20 2a 20 74 6f 20 69 74 73 20 6f  fer.. * to its o
8f90: 77 6e 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  wn Tcl interpret
8fa0: 65 72 2e 20 20 54 63 6c 20 69 6e 74 65 72 70 72  er.  Tcl interpr
8fb0: 65 74 65 72 73 20 6d 75 73 74 20 62 65 20 75 6e  eters must be un
8fc0: 69 71 75 65 20 70 65 72 0a 09 20 2a 20 74 68 72  ique per.. * thr
8fd0: 65 61 64 20 61 6e 64 20 6e 65 77 20 74 68 72 65  ead and new thre
8fe0: 61 64 73 20 61 72 65 20 64 79 6e 61 6d 69 63 61  ads are dynamica
8ff0: 6c 6c 79 20 63 72 65 61 74 65 64 20 62 79 20 46  lly created by F
9000: 55 53 45 2e 0a 09 20 2a 2f 0a 09 70 74 68 72 65  USE... */..pthre
9010: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  ad_ret = pthread
9020: 5f 6b 65 79 5f 63 72 65 61 74 65 28 26 69 6e 74  _key_create(&int
9030: 65 72 70 4b 65 79 2c 20 4e 55 4c 4c 29 3b 0a 09  erpKey, NULL);..
9040: 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20  if (pthread_ret 
9050: 21 3d 20 30 29 20 7b 0a 09 09 66 70 72 69 6e 74  != 0) {...fprint
9060: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
9070: 65 20 74 6f 20 63 72 65 61 74 65 20 54 53 44 20  e to create TSD 
9080: 6b 65 79 20 66 6f 72 20 54 63 6c 2e 20 20 41 62  key for Tcl.  Ab
9090: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09  orting.\n");....
90a0: 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09  return(1);..}...
90b0: 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61 6c 6c 79 20  /*.. * Manually 
90c0: 73 70 65 63 69 66 79 20 63 61 63 68 65 20 64 69  specify cache di
90d0: 72 65 63 74 6f 72 79 2c 20 77 69 74 68 6f 75 74  rectory, without
90e0: 20 46 55 53 45 20 63 61 6c 6c 62 61 63 6b 0a 09   FUSE callback..
90f0: 20 2a 20 54 68 69 73 20 6f 70 74 69 6f 6e 20 6f   * This option o
9100: 6e 6c 79 20 77 6f 72 6b 73 20 77 68 65 6e 20 6e  nly works when n
9110: 6f 74 20 75 73 69 6e 67 20 46 55 53 45 2c 20 73  ot using FUSE, s
9120: 69 6e 63 65 20 77 65 0a 09 20 2a 20 64 6f 20 6e  ince we.. * do n
9130: 6f 74 20 70 72 6f 63 65 73 73 20 69 74 20 77 69  ot process it wi
9140: 74 68 20 46 55 53 45 73 20 6f 70 74 69 6f 6e 20  th FUSEs option 
9150: 70 72 6f 63 65 73 73 69 6e 67 2e 0a 09 20 2a 2f  processing... */
9160: 0a 09 69 66 20 28 61 72 67 63 20 3e 3d 20 32 29  ..if (argc >= 2)
9170: 20 7b 0a 09 09 69 66 20 28 73 74 72 63 6d 70 28   {...if (strcmp(
9180: 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 63 61 63 68  argv[0], "--cach
9190: 65 64 69 72 22 29 20 3d 3d 20 30 29 20 7b 0a 09  edir") == 0) {..
91a0: 09 09 61 70 70 66 73 5f 63 61 63 68 65 64 69 72  ..appfs_cachedir
91b0: 20 3d 20 73 74 72 64 75 70 28 61 72 67 76 5b 31   = strdup(argv[1
91c0: 5d 29 3b 0a 0a 09 09 09 61 72 67 63 20 2d 3d 20  ]);.....argc -= 
91d0: 32 3b 0a 09 09 09 61 72 67 76 20 2b 3d 20 32 3b  2;....argv += 2;
91e0: 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  ...}..}.../*.. *
91f0: 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 2c 20 66   SQLite3 mode, f
9200: 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77 20 53  or running raw S
9210: 51 4c 20 61 67 61 69 6e 73 74 20 74 68 65 20 63  QL against the c
9220: 61 63 68 65 20 64 61 74 61 62 61 73 65 0a 09 20  ache database.. 
9230: 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20  */..if (argc == 
9240: 32 20 26 26 20 73 74 72 63 6d 70 28 61 72 67 76  2 && strcmp(argv
9250: 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69 74 65 33 22  [0], "--sqlite3"
9260: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74 75  ) == 0) {...retu
9270: 72 6e 28 61 70 70 66 73 5f 73 71 6c 69 74 65 33  rn(appfs_sqlite3
9280: 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 0a  (argv[1]));..}..
9290: 09 2f 2a 0a 09 20 2a 20 54 63 6c 20 6d 6f 64 65  ./*.. * Tcl mode
92a0: 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61  , for running ra
92b0: 77 20 54 63 6c 20 69 6e 20 74 68 65 20 73 61 6d  w Tcl in the sam
92c0: 65 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 41 70  e environment Ap
92d0: 70 46 53 64 20 77 6f 75 6c 64 0a 09 20 2a 20 72  pFSd would.. * r
92e0: 75 6e 20 63 6f 64 65 2e 0a 09 20 2a 2f 0a 09 69  un code... */..i
92f0: 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26 26 20  f (argc == 2 && 
9300: 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20  strcmp(argv[0], 
9310: 22 2d 2d 74 63 6c 22 29 20 3d 3d 20 30 29 20 7b  "--tcl") == 0) {
9320: 0a 09 09 72 65 74 75 72 6e 28 61 70 70 66 73 5f  ...return(appfs_
9330: 74 63 6c 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09  tcl(argv[1]));..
9340: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72 65 61 74  }.../*.. * Creat
9350: 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65  e a Tcl interpre
9360: 74 65 72 20 6a 75 73 74 20 74 6f 20 76 65 72 69  ter just to veri
9370: 66 79 20 74 68 61 74 20 74 68 69 6e 67 73 20 61  fy that things a
9380: 72 65 20 69 6e 20 77 6f 72 6b 69 6e 67 20 0a 09  re in working ..
9390: 20 2a 20 6f 72 64 65 72 20 62 65 66 6f 72 65 20   * order before 
93a0: 77 65 20 62 65 63 6f 6d 65 20 61 20 64 61 65 6d  we become a daem
93b0: 6f 6e 2e 0a 09 20 2a 2f 0a 09 74 65 73 74 5f 69  on... */..test_i
93c0: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72  nterp = appfs_cr
93d0: 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 26  eate_TclInterp(&
93e0: 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f  test_interp_erro
93f0: 72 29 3b 0a 09 69 66 20 28 74 65 73 74 5f 69 6e  r);..if (test_in
9400: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
9410: 09 09 69 66 20 28 74 65 73 74 5f 69 6e 74 65 72  ..if (test_inter
9420: 70 5f 65 72 72 6f 72 20 3d 3d 20 4e 55 4c 4c 29  p_error == NULL)
9430: 20 7b 0a 09 09 09 74 65 73 74 5f 69 6e 74 65 72   {....test_inter
9440: 70 5f 65 72 72 6f 72 20 3d 20 22 55 6e 6b 6e 6f  p_error = "Unkno
9450: 77 6e 20 65 72 72 6f 72 22 3b 0a 09 09 7d 0a 0a  wn error";...}..
9460: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
9470: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69  , "Unable to ini
9480: 74 69 61 6c 69 7a 65 20 54 63 6c 20 69 6e 74 65  tialize Tcl inte
9490: 72 70 72 65 74 65 72 20 66 6f 72 20 41 70 70 46  rpreter for AppF
94a0: 53 64 3a 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e  Sd:\n");...fprin
94b0: 74 66 28 73 74 64 65 72 72 2c 20 22 25 73 5c 6e  tf(stderr, "%s\n
94c0: 22 2c 20 74 65 73 74 5f 69 6e 74 65 72 70 5f 65  ", test_interp_e
94d0: 72 72 6f 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e  rror);....return
94e0: 28 31 29 3b 0a 09 7d 0a 09 54 63 6c 5f 44 65 6c  (1);..}..Tcl_Del
94f0: 65 74 65 49 6e 74 65 72 70 28 74 65 73 74 5f 69  eteInterp(test_i
9500: 6e 74 65 72 70 29 3b 0a 09 54 63 6c 5f 46 69 6e  nterp);..Tcl_Fin
9510: 61 6c 69 7a 65 4e 6f 74 69 66 69 65 72 28 4e 55  alizeNotifier(NU
9520: 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65  LL);.../*.. * Re
9530: 67 69 73 74 65 72 20 61 20 73 69 67 6e 61 6c 20  gister a signal 
9540: 68 61 6e 64 6c 65 72 20 66 6f 72 20 68 6f 74 2d  handler for hot-
9550: 72 65 73 74 61 72 74 20 72 65 71 75 65 73 74 73  restart requests
9560: 0a 09 20 2a 2f 0a 09 73 69 67 6e 61 6c 5f 72 65  .. */..signal_re
9570: 74 20 3d 20 73 69 67 6e 61 6c 28 53 49 47 48 55  t = signal(SIGHU
9580: 50 2c 20 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f  P, appfs_signal_
9590: 68 61 6e 64 6c 65 72 29 3b 0a 09 69 66 20 28 73  handler);..if (s
95a0: 69 67 6e 61 6c 5f 72 65 74 20 3d 3d 20 53 49 47  ignal_ret == SIG
95b0: 5f 45 52 52 29 20 7b 0a 09 09 66 70 72 69 6e 74  _ERR) {...fprint
95c0: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
95d0: 65 20 74 6f 20 69 6e 73 74 61 6c 6c 20 73 69 67  e to install sig
95e0: 6e 61 6c 20 68 61 6e 64 6c 65 72 20 66 6f 72 20  nal handler for 
95f0: 68 6f 74 2d 72 65 73 74 61 72 74 5c 6e 22 29 3b  hot-restart\n");
9600: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
9610: 72 2c 20 22 48 6f 74 2d 72 65 73 74 61 72 74 20  r, "Hot-restart 
9620: 77 69 6c 6c 20 6e 6f 74 20 62 65 20 61 76 61 69  will not be avai
9630: 6c 61 62 6c 65 2e 5c 6e 22 29 3b 0a 09 7d 0a 0a  lable.\n");..}..
9640: 09 2f 2a 0a 09 20 2a 20 41 64 64 20 46 55 53 45  ./*.. * Add FUSE
9650: 20 61 72 67 75 6d 65 6e 74 73 20 77 68 69 63 68   arguments which
9660: 20 77 65 20 61 6c 77 61 79 73 20 73 75 70 70 6c   we always suppl
9670: 79 0a 09 20 2a 2f 0a 09 66 75 73 65 5f 6f 70 74  y.. */..fuse_opt
9680: 5f 70 61 72 73 65 28 26 61 72 67 73 2c 20 4e 55  _parse(&args, NU
9690: 4c 4c 2c 20 4e 55 4c 4c 2c 20 61 70 70 66 73 5f  LL, NULL, appfs_
96a0: 66 75 73 65 5f 6f 70 74 5f 63 62 29 3b 0a 09 66  fuse_opt_cb);..f
96b0: 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28  use_opt_add_arg(
96c0: 26 61 72 67 73 2c 20 22 2d 6f 64 65 66 61 75 6c  &args, "-odefaul
96d0: 74 5f 70 65 72 6d 69 73 73 69 6f 6e 73 2c 66 73  t_permissions,fs
96e0: 6e 61 6d 65 3d 61 70 70 66 73 2c 73 75 62 74 79  name=appfs,subty
96f0: 70 65 3d 61 70 70 66 73 64 2c 75 73 65 5f 69 6e  pe=appfsd,use_in
9700: 6f 2c 6b 65 72 6e 65 6c 5f 63 61 63 68 65 2c 65  o,kernel_cache,e
9710: 6e 74 72 79 5f 74 69 6d 65 6f 75 74 3d 30 2c 61  ntry_timeout=0,a
9720: 74 74 72 5f 74 69 6d 65 6f 75 74 3d 30 2c 62 69  ttr_timeout=0,bi
9730: 67 5f 77 72 69 74 65 73 2c 69 6e 74 72 2c 68 61  g_writes,intr,ha
9740: 72 64 5f 72 65 6d 6f 76 65 22 29 3b 0a 0a 09 69  rd_remove");...i
9750: 66 20 28 67 65 74 75 69 64 28 29 20 3d 3d 20 30  f (getuid() == 0
9760: 29 20 7b 0a 09 09 66 75 73 65 5f 6f 70 74 5f 70  ) {...fuse_opt_p
9770: 61 72 73 65 28 26 61 72 67 73 2c 20 4e 55 4c 4c  arse(&args, NULL
9780: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09  , NULL, NULL);..
9790: 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72  .fuse_opt_add_ar
97a0: 67 28 26 61 72 67 73 2c 20 22 2d 6f 61 6c 6c 6f  g(&args, "-oallo
97b0: 77 5f 6f 74 68 65 72 22 29 3b 0a 09 7d 0a 0a 09  w_other");..}...
97c0: 2f 2a 0a 09 20 2a 20 45 6e 74 65 72 20 74 68 65  /*.. * Enter the
97d0: 20 46 55 53 45 20 6d 61 69 6e 20 6c 6f 6f 70 20   FUSE main loop 
97e0: 2d 2d 20 74 68 69 73 20 77 69 6c 6c 20 70 72 6f  -- this will pro
97f0: 63 65 73 73 20 61 6e 79 20 61 72 67 75 6d 65 6e  cess any argumen
9800: 74 73 0a 09 20 2a 20 61 6e 64 20 73 74 61 72 74  ts.. * and start
9810: 20 73 65 72 76 69 63 69 6e 67 20 72 65 71 75 65   servicing reque
9820: 73 74 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73  sts... */..appfs
9830: 5f 66 75 73 65 5f 73 74 61 72 74 65 64 20 3d 20  _fuse_started = 
9840: 31 3b 0a 09 72 65 74 75 72 6e 28 66 75 73 65 5f  1;..return(fuse_
9850: 6d 61 69 6e 28 61 72 67 73 2e 61 72 67 63 2c 20  main(args.argc, 
9860: 61 72 67 73 2e 61 72 67 76 2c 20 26 61 70 70 66  args.argv, &appf
9870: 73 5f 6f 70 65 72 61 74 69 6f 6e 73 2c 20 4e 55  s_operations, NU
9880: 4c 4c 29 29 3b 0a 7d 0a 20 0a                    LL));.}. .