Hex Artifact Content

Artifact 227a45ec34216a37ad36ed7ce2dd4374c9b3041b:


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 74 79 70 65 73  clude <sys/types
0030: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 70 74  .h>.#include <pt
0040: 68 72 65 61 64 2e 68 3e 0a 23 69 6e 63 6c 75 64  hread.h>.#includ
0050: 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e  e <string.h>.#in
0060: 63 6c 75 64 65 20 3c 73 74 64 61 72 67 2e 68 3e  clude <stdarg.h>
0070: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69  .#include <stdli
0080: 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 75  b.h>.#include <u
0090: 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c 75 64  nistd.h>.#includ
00a0: 65 20 3c 65 72 72 6e 6f 2e 68 3e 0a 23 69 6e 63  e <errno.h>.#inc
00b0: 6c 75 64 65 20 3c 66 63 6e 74 6c 2e 68 3e 0a 23  lude <fcntl.h>.#
00c0: 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68  include <stdio.h
00d0: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 66 75 73 65  >.#include <fuse
00e0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 70 77  .h>.#include <pw
00f0: 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 74  d.h>.#include <t
0100: 63 6c 2e 68 3e 0a 0a 2f 2a 0a 20 2a 20 44 65 66  cl.h>../*. * Def
0110: 61 75 6c 74 20 63 61 63 68 65 20 64 69 72 65 63  ault cache direc
0120: 74 6f 72 79 0a 20 2a 2f 0a 23 69 66 6e 64 65 66  tory. */.#ifndef
0130: 20 41 50 50 46 53 5f 43 41 43 48 45 44 49 52 0a   APPFS_CACHEDIR.
0140: 23 64 65 66 69 6e 65 20 41 50 50 46 53 5f 43 41  #define APPFS_CA
0150: 43 48 45 44 49 52 20 22 2f 76 61 72 2f 63 61 63  CHEDIR "/var/cac
0160: 68 65 2f 61 70 70 66 73 22 0a 23 65 6e 64 69 66  he/appfs".#endif
0170: 0a 0a 2f 2a 20 44 65 62 75 67 67 69 6e 67 20 6d  ../* Debugging m
0180: 61 63 72 6f 73 20 2a 2f 0a 23 69 66 64 65 66 20  acros */.#ifdef 
0190: 44 45 42 55 47 0a 23 64 65 66 69 6e 65 20 41 50  DEBUG.#define AP
01a0: 50 46 53 5f 44 45 42 55 47 28 78 2e 2e 2e 29 20  PFS_DEBUG(x...) 
01b0: 7b 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  { fprintf(stderr
01c0: 2c 20 22 5b 64 65 62 75 67 5d 20 25 73 3a 25 69  , "[debug] %s:%i
01d0: 3a 25 73 3a 20 22 2c 20 5f 5f 46 49 4c 45 5f 5f  :%s: ", __FILE__
01e0: 2c 20 5f 5f 4c 49 4e 45 5f 5f 2c 20 5f 5f 66 75  , __LINE__, __fu
01f0: 6e 63 5f 5f 29 3b 20 66 70 72 69 6e 74 66 28 73  nc__); fprintf(s
0200: 74 64 65 72 72 2c 20 78 29 3b 20 66 70 72 69 6e  tderr, x); fprin
0210: 74 66 28 73 74 64 65 72 72 2c 20 22 5c 6e 22 29  tf(stderr, "\n")
0220: 3b 20 7d 0a 23 65 6c 73 65 0a 23 64 65 66 69 6e  ; }.#else.#defin
0230: 65 20 41 50 50 46 53 5f 44 45 42 55 47 28 78 2e  e APPFS_DEBUG(x.
0240: 2e 2e 29 20 2f 2a 2a 2f 0a 23 65 6e 64 69 66 0a  ..) /**/.#endif.
0250: 0a 2f 2a 0a 20 2a 20 53 48 41 31 20 54 63 6c 20  ./*. * SHA1 Tcl 
0260: 50 61 63 6b 61 67 65 20 69 6e 69 74 69 61 6c 69  Package initiali
0270: 7a 65 72 2c 20 66 72 6f 6d 20 73 68 61 31 2e 6f  zer, from sha1.o
0280: 0a 20 2a 2f 0a 69 6e 74 20 53 68 61 31 5f 49 6e  . */.int Sha1_In
0290: 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  it(Tcl_Interp *i
02a0: 6e 74 65 72 70 29 3b 0a 0a 2f 2a 0a 20 2a 20 54  nterp);../*. * T
02b0: 68 72 65 61 64 20 53 70 65 63 69 66 69 63 20 44  hread Specific D
02c0: 61 74 61 20 28 54 53 44 29 20 66 6f 72 20 54 63  ata (TSD) for Tc
02d0: 6c 20 49 6e 74 65 72 70 72 65 74 65 72 20 66 6f  l Interpreter fo
02e0: 72 20 74 68 65 20 63 75 72 72 65 6e 74 20 74 68  r the current th
02f0: 72 65 61 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20  read. */.static 
0300: 70 74 68 72 65 61 64 5f 6b 65 79 5f 74 20 69 6e  pthread_key_t in
0310: 74 65 72 70 4b 65 79 3b 0a 0a 2f 2a 0a 20 2a 20  terpKey;../*. * 
0320: 47 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73  Global variables
0330: 2c 20 6e 65 65 64 65 64 20 66 6f 72 20 61 6c 6c  , needed for all
0340: 20 74 68 72 65 61 64 73 20 62 75 74 20 6f 6e 6c   threads but onl
0350: 79 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 62 65  y initialized be
0360: 66 6f 72 65 20 61 6e 79 0a 20 2a 20 46 55 53 45  fore any. * FUSE
0370: 20 74 68 72 65 61 64 73 20 61 72 65 20 63 72 65   threads are cre
0380: 61 74 65 64 0a 20 2a 2f 0a 63 6f 6e 73 74 20 63  ated. */.const c
0390: 68 61 72 20 2a 61 70 70 66 73 5f 63 61 63 68 65  har *appfs_cache
03a0: 64 69 72 3b 0a 74 69 6d 65 5f 74 20 61 70 70 66  dir;.time_t appf
03b0: 73 5f 62 6f 6f 74 74 69 6d 65 3b 0a 69 6e 74 20  s_boottime;.int 
03c0: 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74  appfs_fuse_start
03d0: 65 64 20 3d 20 30 3b 0a 0a 2f 2a 0a 20 2a 20 41  ed = 0;../*. * A
03e0: 70 70 46 53 20 50 61 74 68 20 54 79 70 65 3a 20  ppFS Path Type: 
03f0: 20 44 65 73 63 72 69 62 65 73 20 74 68 65 20 74   Describes the t
0400: 79 70 65 20 6f 66 20 70 61 74 68 20 61 20 67 69  ype of path a gi
0410: 76 65 6e 20 66 69 6c 65 20 69 73 0a 20 2a 2f 0a  ven file is. */.
0420: 74 79 70 65 64 65 66 20 65 6e 75 6d 20 7b 0a 09  typedef enum {..
0430: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49  APPFS_PATHTYPE_I
0440: 4e 56 41 4c 49 44 2c 0a 09 41 50 50 46 53 5f 50  NVALID,..APPFS_P
0450: 41 54 48 54 59 50 45 5f 46 49 4c 45 2c 0a 09 41  ATHTYPE_FILE,..A
0460: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49  PPFS_PATHTYPE_DI
0470: 52 45 43 54 4f 52 59 2c 0a 09 41 50 50 46 53 5f  RECTORY,..APPFS_
0480: 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b  PATHTYPE_SYMLINK
0490: 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50  ,..APPFS_PATHTYP
04a0: 45 5f 53 4f 43 4b 45 54 2c 0a 09 41 50 50 46 53  E_SOCKET,..APPFS
04b0: 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 2c 0a  _PATHTYPE_FIFO,.
04c0: 7d 20 61 70 70 66 73 5f 70 61 74 68 74 79 70 65  } appfs_pathtype
04d0: 5f 74 3b 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53  _t;../*. * AppFS
04e0: 20 50 61 74 68 20 49 6e 66 6f 72 6d 61 74 69 6f   Path Informatio
04f0: 6e 3a 0a 20 2a 20 20 20 20 20 20 20 20 20 43 6f  n:. *         Co
0500: 6d 70 6c 65 74 65 6c 79 20 64 65 73 63 72 69 62  mpletely describ
0510: 65 73 20 61 20 73 70 65 63 69 66 69 63 20 70 61  es a specific pa
0520: 74 68 2c 20 68 6f 77 20 69 74 20 73 68 6f 75 6c  th, how it shoul
0530: 64 20 62 65 20 72 65 74 75 72 6e 65 64 20 74 6f  d be returned to
0540: 0a 20 2a 20 20 20 20 20 20 20 20 20 74 6f 20 74  . *         to t
0550: 68 65 20 6b 65 72 6e 65 6c 0a 20 2a 2f 0a 73 74  he kernel. */.st
0560: 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69  ruct appfs_pathi
0570: 6e 66 6f 20 7b 0a 09 61 70 70 66 73 5f 70 61 74  nfo {..appfs_pat
0580: 68 74 79 70 65 5f 74 20 74 79 70 65 3b 0a 09 74  htype_t type;..t
0590: 69 6d 65 5f 74 20 74 69 6d 65 3b 0a 09 63 68 61  ime_t time;..cha
05a0: 72 20 68 6f 73 74 6e 61 6d 65 5b 32 35 36 5d 3b  r hostname[256];
05b0: 0a 09 69 6e 74 20 70 61 63 6b 61 67 65 64 3b 0a  ..int packaged;.
05c0: 09 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c  .unsigned long l
05d0: 6f 6e 67 20 69 6e 6f 64 65 3b 0a 09 75 6e 69 6f  ong inode;..unio
05e0: 6e 20 7b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09  n {...struct {..
05f0: 09 09 69 6e 74 20 63 68 69 6c 64 63 6f 75 6e 74  ..int childcount
0600: 3b 0a 09 09 7d 20 64 69 72 3b 0a 09 09 73 74 72  ;...} dir;...str
0610: 75 63 74 20 7b 0a 09 09 09 69 6e 74 20 65 78 65  uct {....int exe
0620: 63 75 74 61 62 6c 65 3b 0a 09 09 09 6f 66 66 5f  cutable;....off_
0630: 74 20 73 69 7a 65 3b 0a 09 09 7d 20 66 69 6c 65  t size;...} file
0640: 3b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09 09  ;...struct {....
0650: 6f 66 66 5f 74 20 73 69 7a 65 3b 0a 09 09 09 63  off_t size;....c
0660: 68 61 72 20 73 6f 75 72 63 65 5b 32 35 36 5d 3b  har source[256];
0670: 0a 09 09 7d 20 73 79 6d 6c 69 6e 6b 3b 0a 09 7d  ...} symlink;..}
0680: 20 74 79 70 65 69 6e 66 6f 3b 0a 7d 3b 0a 0a 2f   typeinfo;.};../
0690: 2a 0a 20 2a 20 43 72 65 61 74 65 20 61 20 6e 65  *. * Create a ne
06a0: 77 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  w Tcl interprete
06b0: 72 20 61 6e 64 20 63 6f 6d 70 6c 65 74 65 6c 79  r and completely
06c0: 20 69 6e 69 74 69 61 6c 69 7a 65 20 69 74 0a 20   initialize it. 
06d0: 2a 2f 0a 73 74 61 74 69 63 20 54 63 6c 5f 49 6e  */.static Tcl_In
06e0: 74 65 72 70 20 2a 61 70 70 66 73 5f 63 72 65 61  terp *appfs_crea
06f0: 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 63 68 61  te_TclInterp(cha
0700: 72 20 2a 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67  r **error_string
0710: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
0720: 2a 69 6e 74 65 72 70 3b 0a 09 69 6e 74 20 74 63  *interp;..int tc
0730: 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  l_ret;...APPFS_D
0740: 45 42 55 47 28 22 43 72 65 61 74 69 6e 67 20 6e  EBUG("Creating n
0750: 65 77 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74  ew Tcl interpret
0760: 65 72 20 66 6f 72 20 54 49 44 20 3d 20 30 78 25  er for TID = 0x%
0770: 6c 6c 78 22 2c 20 28 75 6e 73 69 67 6e 65 64 20  llx", (unsigned 
0780: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 70 74 68 72 65  long long) pthre
0790: 61 64 5f 73 65 6c 66 28 29 29 3b 0a 0a 09 69 6e  ad_self());...in
07a0: 74 65 72 70 20 3d 20 54 63 6c 5f 43 72 65 61 74  terp = Tcl_Creat
07b0: 65 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28  eInterp();..if (
07c0: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20  interp == NULL) 
07d0: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  {...fprintf(stde
07e0: 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63  rr, "Unable to c
07f0: 72 65 61 74 65 20 54 63 6c 20 49 6e 74 65 72 70  reate Tcl Interp
0800: 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69 6e 67  reter.  Aborting
0810: 2e 5c 6e 22 29 3b 0a 0a 09 09 69 66 20 28 65 72  .\n");....if (er
0820: 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09  ror_string) {...
0830: 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d  .*error_string =
0840: 20 73 74 72 64 75 70 28 22 55 6e 61 62 6c 65 20   strdup("Unable 
0850: 74 6f 20 63 72 65 61 74 65 20 54 63 6c 20 69 6e  to create Tcl in
0860: 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 09 09  terpreter.");...
0870: 7d 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c  }....return(NULL
0880: 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20  );..}...tcl_ret 
0890: 3d 20 54 63 6c 5f 49 6e 69 74 28 69 6e 74 65 72  = Tcl_Init(inter
08a0: 70 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  p);..if (tcl_ret
08b0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
08c0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
08d0: 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69  "Unable to initi
08e0: 61 6c 69 7a 65 20 54 63 6c 2e 20 20 41 62 6f 72  alize Tcl.  Abor
08f0: 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66 70 72  ting.\n");...fpr
0900: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54 63  intf(stderr, "Tc
0910: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e  l Error is: %s\n
0920: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
0930: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
0940: 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73 74  ....if (error_st
0950: 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f  ring) {....*erro
0960: 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75  r_string = strdu
0970: 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  p(Tcl_GetStringR
0980: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
0990: 09 09 7d 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74  ..}....Tcl_Delet
09a0: 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b  eInterp(interp);
09b0: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
09c0: 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d  ;..}...tcl_ret =
09d0: 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70   Tcl_Eval(interp
09e0: 2c 20 22 70 61 63 6b 61 67 65 20 69 66 6e 65 65  , "package ifnee
09f0: 64 65 64 20 73 68 61 31 20 31 2e 30 20 5b 6c 69  ded sha1 1.0 [li
0a00: 73 74 20 6c 6f 61 64 20 7b 7d 20 73 68 61 31 5d  st load {} sha1]
0a10: 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ");..if (tcl_ret
0a20: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
0a30: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
0a40: 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69  "Unable to initi
0a50: 61 6c 69 7a 65 20 54 63 6c 20 53 48 41 31 2e 20  alize Tcl SHA1. 
0a60: 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a   Aborting.\n");.
0a70: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
0a80: 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  , "Tcl Error is:
0a90: 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53   %s\n", Tcl_GetS
0aa0: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
0ab0: 72 70 29 29 3b 0a 0a 09 09 69 66 20 28 65 72 72  rp));....if (err
0ac0: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09  or_string) {....
0ad0: 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20  *error_string = 
0ae0: 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74  strdup(Tcl_GetSt
0af0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
0b00: 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f  p));...}....Tcl_
0b10: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
0b20: 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  erp);....return(
0b30: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f  NULL);..}...tcl_
0b40: 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69  ret = Tcl_Eval(i
0b50: 6e 74 65 72 70 2c 20 22 70 61 63 6b 61 67 65 20  nterp, "package 
0b60: 69 66 6e 65 65 64 65 64 20 61 70 70 66 73 64 20  ifneeded appfsd 
0b70: 31 2e 30 20 5b 6c 69 73 74 20 6c 6f 61 64 20 7b  1.0 [list load {
0b80: 7d 20 61 70 70 66 73 64 5d 22 29 3b 0a 09 69 66  } appfsd]");..if
0b90: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
0ba0: 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  _OK) {...fprintf
0bb0: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
0bc0: 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54   to initialize T
0bd0: 63 6c 20 41 70 70 46 53 20 50 61 63 6b 61 67 65  cl AppFS Package
0be0: 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29  .  Aborting.\n")
0bf0: 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  ;...fprintf(stde
0c00: 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69  rr, "Tcl Error i
0c10: 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65  s: %s\n", Tcl_Ge
0c20: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e  tStringResult(in
0c30: 74 65 72 70 29 29 3b 0a 0a 09 09 69 66 20 28 65  terp));....if (e
0c40: 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09  rror_string) {..
0c50: 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20  ..*error_string 
0c60: 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74  = strdup(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 09 09 7d 0a 0a 09 09 54 63  erp));...}....Tc
0c90: 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69  l_DeleteInterp(i
0ca0: 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72  nterp);....retur
0cb0: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a  n(NULL);..}.../*
0cc0: 0a 09 20 2a 20 4c 6f 61 64 20 74 68 65 20 22 61  .. * Load the "a
0cd0: 70 70 66 73 64 2e 74 63 6c 22 20 73 63 72 69 70  ppfsd.tcl" scrip
0ce0: 74 2c 20 77 68 69 63 68 20 69 73 20 22 63 6f 6d  t, which is "com
0cf0: 70 69 6c 65 64 22 20 69 6e 74 6f 20 61 20 43 20  piled" into a C 
0d00: 68 65 61 64 65 72 0a 09 20 2a 20 73 6f 20 74 68  header.. * so th
0d10: 61 74 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 6e  at it does not n
0d20: 65 65 64 20 74 6f 20 65 78 69 73 74 20 6f 6e 20  eed to exist on 
0d30: 74 68 65 20 66 69 6c 65 73 79 73 74 65 6d 20 61  the filesystem a
0d40: 6e 64 20 63 61 6e 20 62 65 0a 09 20 2a 20 64 69  nd can be.. * di
0d50: 72 65 63 74 6c 79 20 65 76 61 6c 75 61 74 65 64  rectly evaluated
0d60: 2e 0a 09 20 2a 2f 0a 09 74 63 6c 5f 72 65 74 20  ... */..tcl_ret 
0d70: 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  = Tcl_Eval(inter
0d80: 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64 65 20 22  p, "".#include "
0d90: 61 70 70 66 73 64 2e 74 63 6c 2e 68 22 0a 09 22  appfsd.tcl.h".."
0da0: 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74  ");..if (tcl_ret
0db0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09   != TCL_OK) {...
0dc0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
0dd0: 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69  "Unable to initi
0de0: 61 6c 69 7a 65 20 54 63 6c 20 41 70 70 46 53 20  alize Tcl AppFS 
0df0: 73 63 72 69 70 74 2e 20 20 41 62 6f 72 74 69 6e  script.  Abortin
0e00: 67 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74  g.\n");...fprint
0e10: 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45  f(stderr, "Tcl E
0e20: 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20  rror is: %s\n", 
0e30: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
0e40: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09  ult(interp));...
0e50: 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e  .if (error_strin
0e60: 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73  g) {....*error_s
0e70: 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54  tring = strdup(T
0e80: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75  cl_GetStringResu
0e90: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 7d  lt(interp));...}
0ea0: 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e  ....Tcl_DeleteIn
0eb0: 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09  terp(interp);...
0ec0: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
0ed0: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65 74 20 67  }.../*.. * Set g
0ee0: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20  lobal variables 
0ef0: 66 72 6f 6d 20 43 20 74 6f 20 54 63 6c 0a 09 20  from C to Tcl.. 
0f00: 2a 2f 0a 09 69 66 20 28 54 63 6c 5f 53 65 74 56  */..if (Tcl_SetV
0f10: 61 72 28 69 6e 74 65 72 70 2c 20 22 3a 3a 61 70  ar(interp, "::ap
0f20: 70 66 73 3a 3a 63 61 63 68 65 64 69 72 22 2c 20  pfs::cachedir", 
0f30: 61 70 70 66 73 5f 63 61 63 68 65 64 69 72 2c 20  appfs_cachedir, 
0f40: 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e 4c 59 29  TCL_GLOBAL_ONLY)
0f50: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70   == NULL) {...fp
0f60: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55  rintf(stderr, "U
0f70: 6e 61 62 6c 65 20 74 6f 20 73 65 74 20 63 61 63  nable to set cac
0f80: 68 65 20 64 69 72 65 63 74 6f 72 79 2e 20 20 54  he directory.  T
0f90: 68 69 73 20 73 68 6f 75 6c 64 20 6e 65 76 65 72  his should never
0fa0: 20 66 61 69 6c 2e 5c 6e 22 29 3b 0a 0a 09 09 69   fail.\n");....i
0fb0: 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29  f (error_string)
0fc0: 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73 74 72   {....*error_str
0fd0: 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c  ing = strdup(Tcl
0fe0: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74  _GetStringResult
0ff0: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 7d 0a 0a  (interp));...}..
1000: 09 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65  ..Tcl_DeleteInte
1010: 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72  rp(interp);....r
1020: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
1030: 0a 09 2f 2a 0a 09 20 2a 20 49 6e 69 74 69 61 6c  ../*.. * Initial
1040: 69 7a 65 20 74 68 65 20 22 61 70 70 66 73 64 2e  ize the "appfsd.
1050: 74 63 6c 22 20 65 6e 76 69 72 6f 6e 6d 65 6e 74  tcl" environment
1060: 2c 20 77 68 69 63 68 20 6d 75 73 74 20 62 65 20  , which must be 
1070: 64 6f 6e 65 20 61 66 74 65 72 0a 09 20 2a 20 67  done after.. * g
1080: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20  lobal variables 
1090: 61 72 65 20 73 65 74 2e 0a 09 20 2a 2f 0a 09 74  are set... */..t
10a0: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61  cl_ret = Tcl_Eva
10b0: 6c 28 69 6e 74 65 72 70 2c 20 22 3a 3a 61 70 70  l(interp, "::app
10c0: 66 73 3a 3a 69 6e 69 74 22 29 3b 0a 09 69 66 20  fs::init");..if 
10d0: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
10e0: 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28  OK) {...fprintf(
10f0: 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20  stderr, "Unable 
1100: 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63  to initialize Tc
1110: 6c 20 41 70 70 46 53 20 73 63 72 69 70 74 20 28  l AppFS script (
1120: 3a 3a 61 70 70 66 73 3a 3a 69 6e 69 74 29 2e 20  ::appfs::init). 
1130: 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a   Aborting.\n");.
1140: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
1150: 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  , "Tcl Error is:
1160: 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53   %s\n", Tcl_GetS
1170: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65  tringResult(inte
1180: 72 70 29 29 3b 0a 0a 09 09 69 66 20 28 65 72 72  rp));....if (err
1190: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09  or_string) {....
11a0: 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20  *error_string = 
11b0: 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74  strdup(Tcl_GetSt
11c0: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
11d0: 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f  p));...}....Tcl_
11e0: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
11f0: 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  erp);....return(
1200: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  NULL);..}.../*..
1210: 20 2a 20 48 69 64 65 20 73 6f 6d 65 20 54 63 6c   * Hide some Tcl
1220: 20 63 6f 6d 6d 61 6e 64 73 20 74 68 61 74 20 77   commands that w
1230: 65 20 64 6f 20 6e 6f 74 20 63 61 72 65 20 74 6f  e do not care to
1240: 20 75 73 65 20 61 6e 64 20 77 68 69 63 68 20 6d   use and which m
1250: 61 79 0a 09 20 2a 20 73 6c 6f 77 20 64 6f 77 6e  ay.. * slow down
1260: 20 72 75 6e 2d 74 69 6d 65 20 6f 70 65 72 61 74   run-time operat
1270: 69 6f 6e 73 2e 0a 09 20 2a 2f 0a 09 54 63 6c 5f  ions... */..Tcl_
1280: 48 69 64 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  HideCommand(inte
1290: 72 70 2c 20 22 61 75 74 6f 5f 6c 6f 61 64 5f 69  rp, "auto_load_i
12a0: 6e 64 65 78 22 2c 20 22 61 75 74 6f 5f 6c 6f 61  ndex", "auto_loa
12b0: 64 5f 69 6e 64 65 78 22 29 3b 0a 09 54 63 6c 5f  d_index");..Tcl_
12c0: 48 69 64 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  HideCommand(inte
12d0: 72 70 2c 20 22 75 6e 6b 6e 6f 77 6e 22 2c 20 22  rp, "unknown", "
12e0: 75 6e 6b 6e 6f 77 6e 22 29 3b 0a 0a 09 2f 2a 0a  unknown");.../*.
12f0: 09 20 2a 20 52 65 74 75 72 6e 20 74 68 65 20 63  . * Return the c
1300: 6f 6d 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61  ompletely initia
1310: 6c 69 7a 65 64 20 69 6e 74 65 72 70 72 65 74 65  lized interprete
1320: 72 0a 09 20 2a 2f 0a 09 72 65 74 75 72 6e 28 69  r.. */..return(i
1330: 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  nterp);.}../*. *
1340: 20 52 65 74 75 72 6e 20 74 68 65 20 74 68 72 65   Return the thre
1350: 61 64 2d 73 70 65 63 69 66 69 63 20 54 63 6c 20  ad-specific Tcl 
1360: 69 6e 74 65 72 70 72 65 74 65 72 2c 20 63 72 65  interpreter, cre
1370: 61 74 69 6e 67 20 69 74 20 69 66 20 6e 65 65 64  ating it if need
1380: 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 54 63  ed. */.static Tc
1390: 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70 66 73 5f  l_Interp *appfs_
13a0: 54 63 6c 49 6e 74 65 72 70 28 76 6f 69 64 29 20  TclInterp(void) 
13b0: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
13c0: 6e 74 65 72 70 3b 0a 09 69 6e 74 20 70 74 68 72  nterp;..int pthr
13d0: 65 61 64 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72  ead_ret;...inter
13e0: 70 20 3d 20 70 74 68 72 65 61 64 5f 67 65 74 73  p = pthread_gets
13f0: 70 65 63 69 66 69 63 28 69 6e 74 65 72 70 4b 65  pecific(interpKe
1400: 79 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  y);..if (interp 
1410: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 6e 74  == NULL) {...int
1420: 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61  erp = appfs_crea
1430: 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c  te_TclInterp(NUL
1440: 4c 29 3b 0a 0a 09 09 69 66 20 28 69 6e 74 65 72  L);....if (inter
1450: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09  p == NULL) {....
1460: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09  return(NULL);...
1470: 7d 0a 0a 09 09 70 74 68 72 65 61 64 5f 72 65 74  }....pthread_ret
1480: 20 3d 20 70 74 68 72 65 61 64 5f 73 65 74 73 70   = pthread_setsp
1490: 65 63 69 66 69 63 28 69 6e 74 65 72 70 4b 65 79  ecific(interpKey
14a0: 2c 20 69 6e 74 65 72 70 29 3b 0a 09 09 69 66 20  , interp);...if 
14b0: 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20  (pthread_ret != 
14c0: 30 29 20 7b 0a 09 09 09 54 63 6c 5f 44 65 6c 65  0) {....Tcl_Dele
14d0: 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29  teInterp(interp)
14e0: 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 4e 55 4c  ;.....return(NUL
14f0: 4c 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74  L);...}..}...ret
1500: 75 72 6e 28 69 6e 74 65 72 70 29 3b 0a 7d 0a 0a  urn(interp);.}..
1510: 2f 2a 0a 20 2a 20 45 76 61 6c 75 61 74 65 20 61  /*. * Evaluate a
1520: 20 54 63 6c 20 73 63 72 69 70 74 20 63 6f 6e 73   Tcl script cons
1530: 74 72 75 63 74 65 64 20 62 79 20 63 6f 6e 63 61  tructed by conca
1540: 74 65 6e 61 74 69 6e 67 20 61 20 62 75 6e 63 68  tenating a bunch
1550: 20 6f 66 20 43 20 73 74 72 69 6e 67 73 0a 20 2a   of C strings. *
1560: 20 74 6f 67 65 74 68 65 72 2e 0a 20 2a 2f 0a 73   together.. */.s
1570: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f  tatic int appfs_
1580: 54 63 6c 5f 45 76 61 6c 28 54 63 6c 5f 49 6e 74  Tcl_Eval(Tcl_Int
1590: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74  erp *interp, int
15a0: 20 6f 62 6a 63 2c 20 63 6f 6e 73 74 20 63 68 61   objc, const cha
15b0: 72 20 2a 63 6d 64 2c 20 2e 2e 2e 29 20 7b 0a 09  r *cmd, ...) {..
15c0: 54 63 6c 5f 4f 62 6a 20 2a 2a 6f 62 6a 76 3b 0a  Tcl_Obj **objv;.
15d0: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 72 67  .const char *arg
15e0: 3b 0a 09 76 61 5f 6c 69 73 74 20 61 72 67 70 3b  ;..va_list argp;
15f0: 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 09 69  ..int retval;..i
1600: 6e 74 20 69 3b 0a 0a 09 69 66 20 28 69 6e 74 65  nt i;...if (inte
1610: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
1620: 72 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52  return(TCL_ERROR
1630: 29 3b 0a 09 7d 0a 0a 09 6f 62 6a 76 20 3d 20 28  );..}...objv = (
1640: 76 6f 69 64 20 2a 29 20 63 6b 61 6c 6c 6f 63 28  void *) ckalloc(
1650: 73 69 7a 65 6f 66 28 2a 6f 62 6a 76 29 20 2a 20  sizeof(*objv) * 
1660: 6f 62 6a 63 29 3b 0a 09 6f 62 6a 76 5b 30 5d 20  objc);..objv[0] 
1670: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f  = Tcl_NewStringO
1680: 62 6a 28 63 6d 64 2c 20 2d 31 29 3b 0a 09 54 63  bj(cmd, -1);..Tc
1690: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 6f  l_IncrRefCount(o
16a0: 62 6a 76 5b 30 5d 29 3b 0a 0a 09 76 61 5f 73 74  bjv[0]);...va_st
16b0: 61 72 74 28 61 72 67 70 2c 20 63 6d 64 29 3b 0a  art(argp, cmd);.
16c0: 09 66 6f 72 20 28 69 20 3d 20 31 3b 20 69 20 3c  .for (i = 1; i <
16d0: 20 6f 62 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09 09   objc; i++) {...
16e0: 61 72 67 20 3d 20 76 61 5f 61 72 67 28 61 72 67  arg = va_arg(arg
16f0: 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 29  p, const char *)
1700: 3b 0a 09 09 6f 62 6a 76 5b 69 5d 20 3d 20 54 63  ;...objv[i] = Tc
1710: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 61  l_NewStringObj(a
1720: 72 67 2c 20 2d 31 29 3b 0a 09 09 54 63 6c 5f 49  rg, -1);...Tcl_I
1730: 6e 63 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76  ncrRefCount(objv
1740: 5b 69 5d 29 3b 0a 09 7d 0a 09 76 61 5f 65 6e 64  [i]);..}..va_end
1750: 28 61 72 67 70 29 3b 0a 0a 09 72 65 74 76 61 6c  (argp);...retval
1760: 20 3d 20 54 63 6c 5f 45 76 61 6c 4f 62 6a 76 28   = Tcl_EvalObjv(
1770: 69 6e 74 65 72 70 2c 20 6f 62 6a 63 2c 20 6f 62  interp, objc, ob
1780: 6a 76 2c 20 30 29 3b 0a 0a 09 66 6f 72 20 28 69  jv, 0);...for (i
1790: 20 3d 20 30 3b 20 69 20 3c 20 6f 62 6a 63 3b 20   = 0; i < objc; 
17a0: 69 2b 2b 29 20 7b 0a 09 09 54 63 6c 5f 44 65 63  i++) {...Tcl_Dec
17b0: 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 69  rRefCount(objv[i
17c0: 5d 29 3b 0a 09 7d 0a 0a 09 63 6b 66 72 65 65 28  ]);..}...ckfree(
17d0: 28 76 6f 69 64 20 2a 29 20 6f 62 6a 76 29 3b 0a  (void *) objv);.
17e0: 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20  ..if (retval != 
17f0: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
1800: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 63 6f 6d  S_DEBUG("Tcl com
1810: 6d 61 6e 64 20 66 61 69 6c 65 64 2c 20 3a 3a 65  mand failed, ::e
1820: 72 72 6f 72 49 6e 66 6f 20 63 6f 6e 74 61 69 6e  rrorInfo contain
1830: 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65  s: %s\n", Tcl_Ge
1840: 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 3a 3a  tVar(interp, "::
1850: 65 72 72 6f 72 49 6e 66 6f 22 2c 20 30 29 29 3b  errorInfo", 0));
1860: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74  ..}...return(ret
1870: 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44  val);.}../*. * D
1880: 65 74 65 72 6d 69 6e 65 20 74 68 65 20 55 49 44  etermine the UID
1890: 20 66 6f 72 20 74 68 65 20 75 73 65 72 20 6d 61   for the user ma
18a0: 6b 69 6e 67 20 74 68 65 20 63 75 72 72 65 6e 74  king the current
18b0: 20 46 55 53 45 20 66 69 6c 65 73 79 73 74 65 6d   FUSE filesystem
18c0: 20 72 65 71 75 65 73 74 2e 0a 20 2a 20 54 68 69   request.. * Thi
18d0: 73 20 77 69 6c 6c 20 62 65 20 75 73 65 64 20 74  s will be used t
18e0: 6f 20 6c 6f 6f 6b 75 70 20 74 68 65 20 75 73 65  o lookup the use
18f0: 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  r's home directo
1900: 72 79 20 73 6f 20 77 65 20 63 61 6e 20 73 65 61  ry so we can sea
1910: 72 63 68 20 66 6f 72 0a 20 2a 20 6c 6f 63 61 6c  rch for. * local
1920: 6c 79 20 6d 6f 64 69 66 69 65 64 20 66 69 6c 65  ly modified file
1930: 73 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 75 69  s.. */.static ui
1940: 64 5f 74 20 61 70 70 66 73 5f 67 65 74 5f 66 73  d_t appfs_get_fs
1950: 75 69 64 28 76 6f 69 64 29 20 7b 0a 09 73 74 72  uid(void) {..str
1960: 75 63 74 20 66 75 73 65 5f 63 6f 6e 74 65 78 74  uct fuse_context
1970: 20 2a 63 74 78 3b 0a 0a 09 69 66 20 28 21 61 70   *ctx;...if (!ap
1980: 70 66 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64  pfs_fuse_started
1990: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 67 65 74  ) {...return(get
19a0: 75 69 64 28 29 29 3b 0a 09 7d 0a 0a 09 63 74 78  uid());..}...ctx
19b0: 20 3d 20 66 75 73 65 5f 67 65 74 5f 63 6f 6e 74   = fuse_get_cont
19c0: 65 78 74 28 29 3b 0a 09 69 66 20 28 63 74 78 20  ext();..if (ctx 
19d0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20  == NULL) {.../* 
19e0: 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 6f 6b 75 70  Unable to lookup
19f0: 20 75 73 65 72 20 66 6f 72 20 73 6f 6d 65 20 72   user for some r
1a00: 65 61 73 6f 6e 20 2a 2f 0a 09 09 2f 2a 20 52 65  eason */.../* Re
1a10: 74 75 72 6e 20 61 6e 20 75 6e 70 72 69 76 69 6c  turn an unprivil
1a20: 65 67 65 64 20 75 73 65 72 20 49 44 20 2a 2f 0a  eged user ID */.
1a30: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
1a40: 0a 09 72 65 74 75 72 6e 28 63 74 78 2d 3e 75 69  ..return(ctx->ui
1a50: 64 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 4c 6f 6f  d);.}../*. * Loo
1a60: 6b 20 75 70 20 74 68 65 20 68 6f 6d 65 20 64 69  k up the home di
1a70: 72 65 63 74 6f 72 79 20 66 6f 72 20 61 20 67 69  rectory for a gi
1a80: 76 65 6e 20 55 49 44 0a 20 2a 20 20 20 20 20 20  ven UID. *      
1a90: 20 20 52 65 74 75 72 6e 73 20 61 20 43 20 73 74    Returns a C st
1aa0: 72 69 6e 67 20 63 6f 6e 74 61 69 6e 69 6e 67 20  ring containing 
1ab0: 74 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20  the user's home 
1ac0: 64 69 72 65 63 74 6f 72 79 20 6f 72 20 4e 55 4c  directory or NUL
1ad0: 4c 20 69 66 0a 20 2a 20 20 20 20 20 20 20 20 74  L if. *        t
1ae0: 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64  he user's home d
1af0: 69 72 65 63 74 6f 72 79 20 64 6f 65 73 20 6e 6f  irectory does no
1b00: 74 20 65 78 69 73 74 20 6f 72 20 69 73 20 6e 6f  t exist or is no
1b10: 74 20 63 6f 72 72 65 63 74 6c 79 0a 20 2a 20 20  t correctly. *  
1b20: 20 20 20 20 20 20 63 6f 6e 66 69 67 75 72 65 64        configured
1b30: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72  . */.static char
1b40: 20 2a 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65   *appfs_get_home
1b50: 64 69 72 28 75 69 64 5f 74 20 66 73 75 69 64 29  dir(uid_t fsuid)
1b60: 20 7b 0a 09 73 74 72 75 63 74 20 70 61 73 73 77   {..struct passw
1b70: 64 20 65 6e 74 72 79 2c 20 2a 72 65 73 75 6c 74  d entry, *result
1b80: 3b 0a 09 73 74 72 75 63 74 20 73 74 61 74 20 73  ;..struct stat s
1b90: 74 62 75 66 3b 0a 09 63 68 61 72 20 62 75 66 5b  tbuf;..char buf[
1ba0: 31 30 32 34 5d 2c 20 2a 72 65 74 76 61 6c 3b 0a  1024], *retval;.
1bb0: 09 69 6e 74 20 67 70 75 5f 72 65 74 2c 20 73 74  .int gpu_ret, st
1bc0: 61 74 5f 72 65 74 3b 0a 0a 09 67 70 75 5f 72 65  at_ret;...gpu_re
1bd0: 74 20 3d 20 67 65 74 70 77 75 69 64 5f 72 28 66  t = getpwuid_r(f
1be0: 73 75 69 64 2c 20 26 65 6e 74 72 79 2c 20 62 75  suid, &entry, bu
1bf0: 66 2c 20 73 69 7a 65 6f 66 28 62 75 66 29 2c 20  f, sizeof(buf), 
1c00: 26 72 65 73 75 6c 74 29 3b 0a 09 69 66 20 28 67  &result);..if (g
1c10: 70 75 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  pu_ret != 0) {..
1c20: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67 65  .APPFS_DEBUG("ge
1c30: 74 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e  tpwuid_r(%llu, .
1c40: 2e 2e 29 20 72 65 74 75 72 6e 65 64 20 69 6e 20  ..) returned in 
1c50: 66 61 69 6c 75 72 65 22 2c 20 28 75 6e 73 69 67  failure", (unsig
1c60: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66  ned long long) f
1c70: 73 75 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e  suid);....return
1c80: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20  (NULL);..}...if 
1c90: 28 72 65 73 75 6c 74 20 3d 3d 20 4e 55 4c 4c 29  (result == NULL)
1ca0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47   {...APPFS_DEBUG
1cb0: 28 22 67 65 74 70 77 75 69 64 5f 72 28 25 6c 6c  ("getpwuid_r(%ll
1cc0: 75 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64  u, ...) returned
1cd0: 20 4e 55 4c 4c 20 72 65 73 75 6c 74 22 2c 20 28   NULL result", (
1ce0: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
1cf0: 6e 67 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72  ng) fsuid);....r
1d00: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
1d10: 0a 09 69 66 20 28 72 65 73 75 6c 74 2d 3e 70 77  ..if (result->pw
1d20: 5f 64 69 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  _dir == NULL) {.
1d30: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67  ..APPFS_DEBUG("g
1d40: 65 74 70 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20  etpwuid_r(%llu, 
1d50: 2e 2e 2e 29 20 72 65 74 75 72 6e 65 64 20 4e 55  ...) returned NU
1d60: 4c 4c 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  LL home director
1d70: 79 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f  y", (unsigned lo
1d80: 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b  ng long) fsuid);
1d90: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
1da0: 3b 0a 09 7d 0a 0a 09 73 74 61 74 5f 72 65 74 20  ;..}...stat_ret 
1db0: 3d 20 73 74 61 74 28 72 65 73 75 6c 74 2d 3e 70  = stat(result->p
1dc0: 77 5f 64 69 72 2c 20 26 73 74 62 75 66 29 3b 0a  w_dir, &stbuf);.
1dd0: 09 69 66 20 28 73 74 61 74 5f 72 65 74 20 21 3d  .if (stat_ret !=
1de0: 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45   0) {...APPFS_DE
1df0: 42 55 47 28 22 73 74 61 74 28 25 73 29 20 72 65  BUG("stat(%s) re
1e00: 74 75 72 6e 65 64 20 69 6e 20 66 61 69 6c 75 72  turned in failur
1e10: 65 22 2c 20 72 65 73 75 6c 74 2d 3e 70 77 5f 64  e", result->pw_d
1e20: 69 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e  ir);....return(N
1e30: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 73  ULL);..}...if (s
1e40: 74 62 75 66 2e 73 74 5f 75 69 64 20 21 3d 20 66  tbuf.st_uid != f
1e50: 73 75 69 64 29 20 7b 0a 09 09 41 50 50 46 53 5f  suid) {...APPFS_
1e60: 44 45 42 55 47 28 22 55 49 44 20 6d 69 73 2d 6d  DEBUG("UID mis-m
1e70: 61 74 63 68 20 6f 6e 20 75 73 65 72 20 25 6c 6c  atch on user %ll
1e80: 75 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f  u's home directo
1e90: 72 79 20 28 25 73 29 2e 20 20 49 74 27 73 20 6f  ry (%s).  It's o
1ea0: 77 6e 65 64 20 62 79 20 25 6c 6c 75 2e 22 2c 0a  wned by %llu.",.
1eb0: 09 09 20 20 20 20 28 75 6e 73 69 67 6e 65 64 20  ..    (unsigned 
1ec0: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64  long long) fsuid
1ed0: 2c 0a 09 09 20 20 20 20 72 65 73 75 6c 74 2d 3e  ,...    result->
1ee0: 70 77 5f 64 69 72 2c 0a 09 09 20 20 20 20 28 75  pw_dir,...    (u
1ef0: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e  nsigned long lon
1f00: 67 29 20 73 74 62 75 66 2e 73 74 5f 75 69 64 0a  g) stbuf.st_uid.
1f10: 09 09 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e  ..);....return(N
1f20: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 76 61  ULL);..}...retva
1f30: 6c 20 3d 20 73 74 72 64 75 70 28 72 65 73 75 6c  l = strdup(resul
1f40: 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09 72 65  t->pw_dir);...re
1f50: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a  turn(retval);.}.
1f60: 0a 2f 2a 0a 20 2a 20 54 63 6c 20 69 6e 74 65 72  ./*. * Tcl inter
1f70: 66 61 63 65 20 74 6f 20 67 65 74 20 74 68 65 20  face to get the 
1f80: 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20 66  home directory f
1f90: 6f 72 20 74 68 65 20 75 73 65 72 20 6d 61 6b 69  or the user maki
1fa0: 6e 67 20 74 68 65 20 22 63 75 72 72 65 6e 74 22  ng the "current"
1fb0: 0a 20 2a 20 46 55 53 45 20 49 2f 4f 20 72 65 71  . * FUSE I/O req
1fc0: 75 65 73 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20  uest. */.static 
1fd0: 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f 67 65  int tcl_appfs_ge
1fe0: 74 5f 68 6f 6d 65 64 69 72 28 43 6c 69 65 6e 74  t_homedir(Client
1ff0: 44 61 74 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74  Data cd, Tcl_Int
2000: 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74  erp *interp, int
2010: 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a   objc, Tcl_Obj *
2020: 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a  CONST objv[]) {.
2030: 09 63 68 61 72 20 2a 68 6f 6d 65 64 69 72 3b 0a  .char *homedir;.
2040: 0a 20 20 20 20 20 20 20 20 69 66 20 28 6f 62 6a  .        if (obj
2050: 63 20 21 3d 20 31 29 20 7b 0a 20 20 20 20 20 20  c != 1) {.      
2060: 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f 57 72            Tcl_Wr
2070: 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72  ongNumArgs(inter
2080: 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 4e 55 4c 4c  p, 1, objv, NULL
2090: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  );.             
20a0: 20 20 20 72 65 74 75 72 6e 28 54 43 4c 5f 45 52     return(TCL_ER
20b0: 52 4f 52 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a  ROR);.        }.
20c0: 0a 09 68 6f 6d 65 64 69 72 20 3d 20 61 70 70 66  ..homedir = appf
20d0: 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 61 70  s_get_homedir(ap
20e0: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29  pfs_get_fsuid())
20f0: 3b 0a 0a 09 69 66 20 28 68 6f 6d 65 64 69 72 20  ;...if (homedir 
2100: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
2110: 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a  urn(TCL_ERROR);.
2120: 09 7d 0a 0a 20 20 20 20 20 20 20 20 54 63 6c 5f  .}..        Tcl_
2130: 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  SetObjResult(int
2140: 65 72 70 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69  erp, Tcl_NewStri
2150: 6e 67 4f 62 6a 28 68 6f 6d 65 64 69 72 2c 20 2d  ngObj(homedir, -
2160: 31 29 29 3b 0a 0a 09 66 72 65 65 28 68 6f 6d 65  1));...free(home
2170: 64 69 72 29 3b 0a 0a 20 20 20 20 20 20 20 20 72  dir);..        r
2180: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d  eturn(TCL_OK);.}
2190: 0a 0a 2f 2a 0a 20 2a 20 47 65 6e 65 72 61 74 65  ../*. * Generate
21a0: 20 61 6e 20 69 6e 6f 64 65 20 66 6f 72 20 61 20   an inode for a 
21b0: 67 69 76 65 6e 20 70 61 74 68 2e 20 20 54 68 65  given path.  The
21c0: 20 69 6e 6f 64 65 20 73 68 6f 75 6c 64 20 62 65   inode should be
21d0: 20 63 6f 6d 70 75 74 65 64 20 69 6e 20 73 75 63   computed in suc
21e0: 68 0a 20 2a 20 61 20 77 61 79 20 74 68 61 74 20  h. * a way that 
21f0: 69 74 20 69 73 20 75 6e 6c 69 6b 65 6c 79 20 74  it is unlikely t
2200: 6f 20 62 65 20 64 75 70 6c 69 63 61 74 65 64 20  o be duplicated 
2210: 61 6e 64 20 72 65 6d 61 69 6e 73 20 74 68 65 20  and remains the 
2220: 73 61 6d 65 20 66 6f 72 20 61 20 67 69 76 65 6e  same for a given
2230: 0a 20 2a 20 66 69 6c 65 0a 20 2a 2f 0a 73 74 61  . * file. */.sta
2240: 74 69 63 20 6c 6f 6e 67 20 6c 6f 6e 67 20 61 70  tic long long ap
2250: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f  pfs_get_path_ino
2260: 64 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  de(const char *p
2270: 61 74 68 29 20 7b 0a 09 6c 6f 6e 67 20 6c 6f 6e  ath) {..long lon
2280: 67 20 72 65 74 76 61 6c 3b 0a 09 63 6f 6e 73 74  g retval;..const
2290: 20 63 68 61 72 20 2a 70 3b 0a 0a 09 72 65 74 76   char *p;...retv
22a0: 61 6c 20 3d 20 31 30 3b 0a 0a 09 66 6f 72 20 28  al = 10;...for (
22b0: 70 20 3d 20 70 61 74 68 3b 20 2a 70 3b 20 70 2b  p = path; *p; p+
22c0: 2b 29 20 7b 0a 09 09 72 65 74 76 61 6c 20 25 3d  +) {...retval %=
22d0: 20 34 32 39 30 39 36 30 32 39 30 55 4c 4c 3b 0a   4290960290ULL;.
22e0: 09 09 72 65 74 76 61 6c 20 2b 3d 20 2a 70 3b 0a  ..retval += *p;.
22f0: 09 09 72 65 74 76 61 6c 20 3c 3c 3d 20 37 3b 0a  ..retval <<= 7;.
2300: 09 7d 0a 0a 09 72 65 74 76 61 6c 20 2b 3d 20 31  .}...retval += 1
2310: 30 3b 0a 09 72 65 74 76 61 6c 20 25 3d 20 34 32  0;..retval %= 42
2320: 39 34 39 36 37 32 39 36 55 4c 4c 3b 0a 0a 09 72  94967296ULL;...r
2330: 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d  eturn(retval);.}
2340: 0a 0a 2f 2a 20 47 65 74 20 69 6e 66 6f 72 6d 61  ../* Get informa
2350: 74 69 6f 6e 20 61 62 6f 75 74 20 61 20 70 61 74  tion about a pat
2360: 68 2c 20 61 6e 64 20 6f 70 74 69 6f 6e 61 6c 6c  h, and optionall
2370: 79 20 6c 69 73 74 20 63 68 69 6c 64 72 65 6e 20  y list children 
2380: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  */.static int ap
2390: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66  pfs_get_path_inf
23a0: 6f 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61  o(const char *pa
23b0: 74 68 2c 20 73 74 72 75 63 74 20 61 70 70 66 73  th, struct appfs
23c0: 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61 74 68 69  _pathinfo *pathi
23d0: 6e 66 6f 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65  nfo) {..Tcl_Inte
23e0: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c  rp *interp;..Tcl
23f0: 5f 4f 62 6a 20 2a 61 74 74 72 73 5f 64 69 63 74  _Obj *attrs_dict
2400: 2c 20 2a 61 74 74 72 5f 76 61 6c 75 65 3b 0a 09  , *attr_value;..
2410: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 74 74 72  const char *attr
2420: 5f 76 61 6c 75 65 5f 73 74 72 3b 0a 09 54 63 6c  _value_str;..Tcl
2430: 5f 57 69 64 65 49 6e 74 20 61 74 74 72 5f 76 61  _WideInt attr_va
2440: 6c 75 65 5f 77 69 64 65 3b 0a 09 69 6e 74 20 61  lue_wide;..int a
2450: 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a 09  ttr_value_int;..
2460: 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64 20  static __thread 
2470: 54 63 6c 5f 4f 62 6a 20 2a 61 74 74 72 5f 6b 65  Tcl_Obj *attr_ke
2480: 79 5f 74 79 70 65 20 3d 20 4e 55 4c 4c 2c 20 2a  y_type = NULL, *
2490: 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20 3d  attr_key_perms =
24a0: 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79   NULL, *attr_key
24b0: 5f 73 69 7a 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61  _size = NULL, *a
24c0: 74 74 72 5f 6b 65 79 5f 74 69 6d 65 20 3d 20 4e  ttr_key_time = N
24d0: 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 73  ULL, *attr_key_s
24e0: 6f 75 72 63 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61  ource = NULL, *a
24f0: 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75  ttr_key_childcou
2500: 6e 74 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72  nt = NULL, *attr
2510: 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 20 3d 20  _key_packaged = 
2520: 4e 55 4c 4c 3b 0a 09 69 6e 74 20 74 63 6c 5f 72  NULL;..int tcl_r
2530: 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61  et;...interp = a
2540: 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29  ppfs_TclInterp()
2550: 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ;..if (interp ==
2560: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
2570: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 74 63  n(-EIO);..}...tc
2580: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
2590: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32  l_Eval(interp, 2
25a0: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61  , "::appfs::geta
25b0: 74 74 72 22 2c 20 70 61 74 68 29 3b 0a 09 69 66  ttr", path);..if
25c0: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
25d0: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  _OK) {...APPFS_D
25e0: 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67  EBUG("::appfs::g
25f0: 65 74 61 74 74 72 28 25 73 29 20 66 61 69 6c 65  etattr(%s) faile
2600: 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41 50  d.", path);...AP
2610: 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45  PFS_DEBUG("Tcl E
2620: 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63  rror is: %s", Tc
2630: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c  l_GetStringResul
2640: 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72  t(interp));....r
2650: 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a  eturn(-ENOENT);.
2660: 09 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 6b 65  .}...if (attr_ke
2670: 79 5f 74 79 70 65 20 3d 3d 20 4e 55 4c 4c 29 20  y_type == NULL) 
2680: 7b 0a 09 09 61 74 74 72 5f 6b 65 79 5f 74 79 70  {...attr_key_typ
2690: 65 20 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65  e       = Tcl_Ne
26a0: 77 53 74 72 69 6e 67 4f 62 6a 28 22 74 79 70 65  wStringObj("type
26b0: 22 2c 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b  ", -1);...attr_k
26c0: 65 79 5f 70 65 72 6d 73 20 20 20 20 20 20 3d 20  ey_perms      = 
26d0: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
26e0: 28 22 70 65 72 6d 73 22 2c 20 2d 31 29 3b 0a 09  ("perms", -1);..
26f0: 09 61 74 74 72 5f 6b 65 79 5f 73 69 7a 65 20 20  .attr_key_size  
2700: 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74       = Tcl_NewSt
2710: 72 69 6e 67 4f 62 6a 28 22 73 69 7a 65 22 2c 20  ringObj("size", 
2720: 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79 5f  -1);...attr_key_
2730: 74 69 6d 65 20 20 20 20 20 20 20 3d 20 54 63 6c  time       = Tcl
2740: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 74  _NewStringObj("t
2750: 69 6d 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74 74  ime", -1);...att
2760: 72 5f 6b 65 79 5f 73 6f 75 72 63 65 20 20 20 20  r_key_source    
2770: 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67   = Tcl_NewString
2780: 4f 62 6a 28 22 73 6f 75 72 63 65 22 2c 20 2d 31  Obj("source", -1
2790: 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79 5f 63 68  );...attr_key_ch
27a0: 69 6c 64 63 6f 75 6e 74 20 3d 20 54 63 6c 5f 4e  ildcount = Tcl_N
27b0: 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 63 68 69  ewStringObj("chi
27c0: 6c 64 63 6f 75 6e 74 22 2c 20 2d 31 29 3b 0a 09  ldcount", -1);..
27d0: 09 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67  .attr_key_packag
27e0: 65 64 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74  ed   = Tcl_NewSt
27f0: 72 69 6e 67 4f 62 6a 28 22 70 61 63 6b 61 67 65  ringObj("package
2800: 64 22 2c 20 2d 31 29 3b 0a 09 7d 0a 0a 09 61 74  d", -1);..}...at
2810: 74 72 73 5f 64 69 63 74 20 3d 20 54 63 6c 5f 47  trs_dict = Tcl_G
2820: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65  etObjResult(inte
2830: 72 70 29 3b 0a 09 74 63 6c 5f 72 65 74 20 3d 20  rp);..tcl_ret = 
2840: 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69  Tcl_DictObjGet(i
2850: 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63  nterp, attrs_dic
2860: 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74 79 70 65  t, attr_key_type
2870: 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a  , &attr_value);.
2880: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20  .if (tcl_ret != 
2890: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46  TCL_OK) {...APPF
28a0: 53 5f 44 45 42 55 47 28 22 5b 64 69 63 74 20 67  S_DEBUG("[dict g
28b0: 65 74 20 5c 22 74 79 70 65 5c 22 5d 20 66 61 69  et \"type\"] fai
28c0: 6c 65 64 22 29 3b 0a 09 09 41 50 50 46 53 5f 44  led");...APPFS_D
28d0: 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20  EBUG("Tcl Error 
28e0: 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74  is: %s", Tcl_Get
28f0: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
2900: 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e  erp));....return
2910: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 69 66 20  (-EIO);..}...if 
2920: 28 61 74 74 72 5f 76 61 6c 75 65 20 3d 3d 20 4e  (attr_value == N
2930: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
2940: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 70 61 74 68  -EIO);..}...path
2950: 69 6e 66 6f 2d 3e 70 61 63 6b 61 67 65 64 20 3d  info->packaged =
2960: 20 30 3b 0a 09 70 61 74 68 69 6e 66 6f 2d 3e 69   0;..pathinfo->i
2970: 6e 6f 64 65 20 3d 20 61 70 70 66 73 5f 67 65 74  node = appfs_get
2980: 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 61 74 68  _path_inode(path
2990: 29 3b 0a 0a 09 61 74 74 72 5f 76 61 6c 75 65 5f  );...attr_value_
29a0: 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  str = Tcl_GetStr
29b0: 69 6e 67 28 61 74 74 72 5f 76 61 6c 75 65 29 3b  ing(attr_value);
29c0: 0a 09 73 77 69 74 63 68 20 28 61 74 74 72 5f 76  ..switch (attr_v
29d0: 61 6c 75 65 5f 73 74 72 5b 30 5d 29 20 7b 0a 09  alue_str[0]) {..
29e0: 09 63 61 73 65 20 27 64 27 3a 20 2f 2a 20 64 69  .case 'd': /* di
29f0: 72 65 63 74 6f 72 79 20 2a 2f 0a 09 09 09 70 61  rectory */....pa
2a00: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41  thinfo->type = A
2a10: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49  PPFS_PATHTYPE_DI
2a20: 52 45 43 54 4f 52 59 3b 0a 09 09 09 70 61 74 68  RECTORY;....path
2a30: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64  info->typeinfo.d
2a40: 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20  ir.childcount = 
2a50: 30 3b 0a 0a 09 09 09 54 63 6c 5f 44 69 63 74 4f  0;.....Tcl_DictO
2a60: 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74  bjGet(interp, at
2a70: 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b  trs_dict, attr_k
2a80: 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 2c 20 26  ey_childcount, &
2a90: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09  attr_value);....
2aa0: 69 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21  if (attr_value !
2ab0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 74 63  = NULL) {.....tc
2ac0: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 57  l_ret = Tcl_GetW
2ad0: 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e 55  ideIntFromObj(NU
2ae0: 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c 20  LL, attr_value, 
2af0: 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65  &attr_value_wide
2b00: 29 3b 0a 09 09 09 09 69 66 20 28 74 63 6c 5f 72  );.....if (tcl_r
2b10: 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et == TCL_OK) {.
2b20: 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74  .....pathinfo->t
2b30: 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c  ypeinfo.dir.chil
2b40: 64 63 6f 75 6e 74 20 3d 20 61 74 74 72 5f 76 61  dcount = attr_va
2b50: 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09 09 7d 0a  lue_wide;.....}.
2b60: 09 09 09 7d 0a 0a 09 09 09 62 72 65 61 6b 3b 0a  ...}.....break;.
2b70: 09 09 63 61 73 65 20 27 66 27 3a 20 2f 2a 20 66  ..case 'f': /* f
2b80: 69 6c 65 20 2a 2f 0a 09 09 09 70 61 74 68 69 6e  ile */....pathin
2b90: 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53  fo->type = APPFS
2ba0: 5f 50 41 54 48 54 59 50 45 5f 46 49 4c 45 3b 0a  _PATHTYPE_FILE;.
2bb0: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
2bc0: 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20  einfo.file.size 
2bd0: 3d 20 30 3b 0a 09 09 09 70 61 74 68 69 6e 66 6f  = 0;....pathinfo
2be0: 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e  ->typeinfo.file.
2bf0: 65 78 65 63 75 74 61 62 6c 65 20 3d 20 30 3b 0a  executable = 0;.
2c00: 0a 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47  ....Tcl_DictObjG
2c10: 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73  et(interp, attrs
2c20: 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f  _dict, attr_key_
2c30: 73 69 7a 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  size, &attr_valu
2c40: 65 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72 5f  e);....if (attr_
2c50: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b  value != NULL) {
2c60: 0a 09 09 09 09 74 63 6c 5f 72 65 74 20 3d 20 54  .....tcl_ret = T
2c70: 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f  cl_GetWideIntFro
2c80: 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f  mObj(NULL, attr_
2c90: 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c  value, &attr_val
2ca0: 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 09 69 66  ue_wide);.....if
2cb0: 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c   (tcl_ret == TCL
2cc0: 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 70 61 74 68  _OK) {......path
2cd0: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66  info->typeinfo.f
2ce0: 69 6c 65 2e 73 69 7a 65 20 3d 20 61 74 74 72 5f  ile.size = attr_
2cf0: 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 09 09  value_wide;.....
2d00: 7d 0a 09 09 09 7d 0a 0a 09 09 09 54 63 6c 5f 44  }....}.....Tcl_D
2d10: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70  ictObjGet(interp
2d20: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74  , attrs_dict, at
2d30: 74 72 5f 6b 65 79 5f 70 65 72 6d 73 2c 20 26 61  tr_key_perms, &a
2d40: 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 69  ttr_value);....i
2d50: 66 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d  f (attr_value !=
2d60: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 61 74 74   NULL) {.....att
2d70: 72 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63  r_value_str = Tc
2d80: 6c 5f 47 65 74 53 74 72 69 6e 67 28 61 74 74 72  l_GetString(attr
2d90: 5f 76 61 6c 75 65 29 3b 0a 09 09 09 09 69 66 20  _value);.....if 
2da0: 28 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5b  (attr_value_str[
2db0: 30 5d 20 3d 3d 20 27 78 27 29 20 7b 0a 09 09 09  0] == 'x') {....
2dc0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65  ..pathinfo->type
2dd0: 69 6e 66 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74  info.file.execut
2de0: 61 62 6c 65 20 3d 20 31 3b 0a 09 09 09 09 7d 0a  able = 1;.....}.
2df0: 09 09 09 7d 0a 09 09 09 62 72 65 61 6b 3b 0a 09  ...}....break;..
2e00: 09 63 61 73 65 20 27 73 27 3a 20 2f 2a 20 73 79  .case 's': /* sy
2e10: 6d 6c 69 6e 6b 20 2a 2f 0a 09 09 09 70 61 74 68  mlink */....path
2e20: 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50  info->type = APP
2e30: 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c  FS_PATHTYPE_SYML
2e40: 49 4e 4b 3b 0a 09 09 09 70 61 74 68 69 6e 66 6f  INK;....pathinfo
2e50: 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69  ->typeinfo.symli
2e60: 6e 6b 2e 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09  nk.size = 0;....
2e70: 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e  pathinfo->typein
2e80: 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63  fo.symlink.sourc
2e90: 65 5b 30 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09 09  e[0] = '\0';....
2ea0: 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28  .Tcl_DictObjGet(
2eb0: 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69  interp, attrs_di
2ec0: 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 73 6f 75  ct, attr_key_sou
2ed0: 72 63 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65  rce, &attr_value
2ee0: 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72 5f 76  );....if (attr_v
2ef0: 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a  alue != NULL) {.
2f00: 09 09 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73  ....attr_value_s
2f10: 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  tr = Tcl_GetStri
2f20: 6e 67 46 72 6f 6d 4f 62 6a 28 61 74 74 72 5f 76  ngFromObj(attr_v
2f30: 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  alue, &attr_valu
2f40: 65 5f 69 6e 74 29 3b 20 0a 0a 09 09 09 09 69 66  e_int); ......if
2f50: 20 28 28 61 74 74 72 5f 76 61 6c 75 65 5f 69 6e   ((attr_value_in
2f60: 74 20 2b 20 31 29 20 3c 3d 20 73 69 7a 65 6f 66  t + 1) <= sizeof
2f70: 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69  (pathinfo->typei
2f80: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72  nfo.symlink.sour
2f90: 63 65 29 29 20 7b 0a 09 09 09 09 09 70 61 74 68  ce)) {......path
2fa0: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73  info->typeinfo.s
2fb0: 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20 61 74  ymlink.size = at
2fc0: 74 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a 09 09  tr_value_int;...
2fd0: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70  ...pathinfo->typ
2fe0: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f  einfo.symlink.so
2ff0: 75 72 63 65 5b 61 74 74 72 5f 76 61 6c 75 65 5f  urce[attr_value_
3000: 69 6e 74 5d 20 3d 20 27 5c 30 27 3b 0a 0a 09 09  int] = '\0';....
3010: 09 09 09 6d 65 6d 63 70 79 28 70 61 74 68 69 6e  ...memcpy(pathin
3020: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  fo->typeinfo.sym
3030: 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c 20 61 74 74  link.source, att
3040: 72 5f 76 61 6c 75 65 5f 73 74 72 2c 20 61 74 74  r_value_str, att
3050: 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 0a 09 09  r_value_int);...
3060: 09 09 7d 0a 09 09 09 7d 0a 09 09 09 62 72 65 61  ..}....}....brea
3070: 6b 3b 0a 09 09 63 61 73 65 20 27 70 27 3a 20 2f  k;...case 'p': /
3080: 2a 20 70 69 70 65 2f 66 69 66 6f 20 2a 2f 0a 09  * pipe/fifo */..
3090: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20  ..break;...case 
30a0: 27 53 27 3a 20 2f 2a 20 55 4e 49 58 20 64 6f 6d  'S': /* UNIX dom
30b0: 61 69 6e 20 73 6f 63 6b 65 74 20 2a 2f 0a 09 09  ain socket */...
30c0: 09 62 72 65 61 6b 3b 0a 09 09 64 65 66 61 75 6c  .break;...defaul
30d0: 74 3a 0a 09 09 09 72 65 74 75 72 6e 28 2d 45 49  t:....return(-EI
30e0: 4f 29 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 44 69 63  O);..}...Tcl_Dic
30f0: 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20  tObjGet(interp, 
3100: 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72  attrs_dict, attr
3110: 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 2c 20 26  _key_packaged, &
3120: 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a 09 69 66  attr_value);..if
3130: 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20   (attr_value != 
3140: 4e 55 4c 4c 29 20 7b 0a 09 09 70 61 74 68 69 6e  NULL) {...pathin
3150: 66 6f 2d 3e 70 61 63 6b 61 67 65 64 20 3d 20 31  fo->packaged = 1
3160: 3b 0a 09 7d 0a 0a 09 54 63 6c 5f 44 69 63 74 4f  ;..}...Tcl_DictO
3170: 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74  bjGet(interp, at
3180: 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b  trs_dict, attr_k
3190: 65 79 5f 74 69 6d 65 2c 20 26 61 74 74 72 5f 76  ey_time, &attr_v
31a0: 61 6c 75 65 29 3b 0a 09 69 66 20 28 61 74 74 72  alue);..if (attr
31b0: 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20  _value != NULL) 
31c0: 7b 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63  {...tcl_ret = Tc
31d0: 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f 6d  l_GetWideIntFrom
31e0: 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f 76  Obj(NULL, attr_v
31f0: 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c 75  alue, &attr_valu
3200: 65 5f 77 69 64 65 29 3b 0a 09 09 69 66 20 28 74  e_wide);...if (t
3210: 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c 5f 4f 4b  cl_ret == TCL_OK
3220: 29 20 7b 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d  ) {....pathinfo-
3230: 3e 74 69 6d 65 20 3d 20 61 74 74 72 5f 76 61 6c  >time = attr_val
3240: 75 65 5f 77 69 64 65 3b 0a 09 09 7d 0a 09 7d 20  ue_wide;...}..} 
3250: 65 6c 73 65 20 7b 0a 09 09 70 61 74 68 69 6e 66  else {...pathinf
3260: 6f 2d 3e 74 69 6d 65 20 3d 20 30 3b 0a 09 7d 0a  o->time = 0;..}.
3270: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
3280: 73 74 61 74 69 63 20 63 68 61 72 20 2a 61 70 70  static char *app
3290: 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72  fs_prepare_to_cr
32a0: 65 61 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20  eate(const char 
32b0: 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e  *path) {..Tcl_In
32c0: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63  terp *interp;..c
32d0: 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f  onst char *real_
32e0: 70 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72  path;..int tcl_r
32f0: 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61  et;...interp = a
3300: 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29  ppfs_TclInterp()
3310: 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ;..if (interp ==
3320: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
3330: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63  n(NULL);..}...tc
3340: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63  l_ret = appfs_Tc
3350: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32  l_Eval(interp, 2
3360: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 70 72 65 70  , "::appfs::prep
3370: 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 22 2c 20  are_to_create", 
3380: 70 61 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f  path);..if (tcl_
3390: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
33a0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
33b0: 3a 3a 61 70 70 66 73 3a 3a 70 72 65 70 61 72 65  ::appfs::prepare
33c0: 5f 74 6f 5f 63 72 65 61 74 65 28 25 73 29 20 66  _to_create(%s) f
33d0: 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a  ailed.", path);.
33e0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54  ..APPFS_DEBUG("T
33f0: 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22  cl Error is: %s"
3400: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  , Tcl_GetStringR
3410: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a  esult(interp));.
3420: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
3430: 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20  ..}...real_path 
3440: 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52  = Tcl_GetStringR
3450: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09  esult(interp);..
3460: 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d  if (real_path ==
3470: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
3480: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65  n(NULL);..}...re
3490: 74 75 72 6e 28 73 74 72 64 75 70 28 72 65 61 6c  turn(strdup(real
34a0: 5f 70 61 74 68 29 29 3b 0a 7d 0a 0a 73 74 61 74  _path));.}..stat
34b0: 69 63 20 63 68 61 72 20 2a 61 70 70 66 73 5f 6c  ic char *appfs_l
34c0: 6f 63 61 6c 70 61 74 68 28 63 6f 6e 73 74 20 63  ocalpath(const c
34d0: 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54 63  har *path) {..Tc
34e0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
34f0: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72  ;..const char *r
3500: 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74  eal_path;..int t
3510: 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70  cl_ret;...interp
3520: 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65   = appfs_TclInte
3530: 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72  rp();..if (inter
3540: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  p == NULL) {...r
3550: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
3560: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66  ..tcl_ret = appf
3570: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  s_Tcl_Eval(inter
3580: 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  p, 2, "::appfs::
3590: 6c 6f 63 61 6c 70 61 74 68 22 2c 20 70 61 74 68  localpath", path
35a0: 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  );..if (tcl_ret 
35b0: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41  != TCL_OK) {...A
35c0: 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70  PPFS_DEBUG("::ap
35d0: 70 66 73 3a 3a 6c 6f 63 61 6c 70 61 74 68 28 25  pfs::localpath(%
35e0: 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74  s) failed.", pat
35f0: 68 29 3b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  h);...APPFS_DEBU
3600: 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a  G("Tcl Error is:
3610: 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72   %s", Tcl_GetStr
3620: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
3630: 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  ));....return(NU
3640: 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70  LL);..}...real_p
3650: 61 74 68 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  ath = Tcl_GetStr
3660: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
3670: 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74  );..if (real_pat
3680: 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  h == NULL) {...r
3690: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
36a0: 0a 09 72 65 74 75 72 6e 28 73 74 72 64 75 70 28  ..return(strdup(
36b0: 72 65 61 6c 5f 70 61 74 68 29 29 3b 0a 7d 0a 0a  real_path));.}..
36c0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
36d0: 5f 66 75 73 65 5f 72 65 61 64 6c 69 6e 6b 28 63  _fuse_readlink(c
36e0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
36f0: 20 63 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65   char *buf, size
3700: 5f 74 20 73 69 7a 65 29 20 7b 0a 09 73 74 72 75  _t size) {..stru
3710: 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66  ct appfs_pathinf
3720: 6f 20 70 61 74 68 69 6e 66 6f 3b 0a 09 69 6e 74  o pathinfo;..int
3730: 20 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 41   retval = 0;...A
3740: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65  PPFS_DEBUG("Ente
3750: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e  r (path = %s, ..
3760: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 70 61  .)", path);...pa
3770: 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41 50  thinfo.type = AP
3780: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56  PFS_PATHTYPE_INV
3790: 41 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20 3d  ALID;...retval =
37a0: 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f   appfs_get_path_
37b0: 69 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68  info(path, &path
37c0: 69 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65 74 76  info);..if (retv
37d0: 61 6c 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74  al != 0) {...ret
37e0: 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d 0a  urn(retval);..}.
37f0: 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 74  ..if (pathinfo.t
3800: 79 70 65 20 21 3d 20 41 50 50 46 53 5f 50 41 54  ype != APPFS_PAT
3810: 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 29 20 7b  HTYPE_SYMLINK) {
3820: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4e 56 41  ...return(-EINVA
3830: 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 73 74  L);..}...if ((st
3840: 72 6c 65 6e 28 70 61 74 68 69 6e 66 6f 2e 74 79  rlen(pathinfo.ty
3850: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73  peinfo.symlink.s
3860: 6f 75 72 63 65 29 20 2b 20 31 29 20 3e 20 73 69  ource) + 1) > si
3870: 7a 65 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  ze) {...return(-
3880: 45 4e 41 4d 45 54 4f 4f 4c 4f 4e 47 29 3b 0a 09  ENAMETOOLONG);..
3890: 7d 0a 0a 09 6d 65 6d 63 70 79 28 62 75 66 2c 20  }...memcpy(buf, 
38a0: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66  pathinfo.typeinf
38b0: 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65  o.symlink.source
38c0: 2c 20 73 74 72 6c 65 6e 28 70 61 74 68 69 6e 66  , strlen(pathinf
38d0: 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69  o.typeinfo.symli
38e0: 6e 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31 29 3b  nk.source) + 1);
38f0: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a  ...return(0);.}.
3900: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
3910: 73 5f 66 75 73 65 5f 67 65 74 61 74 74 72 28 63  s_fuse_getattr(c
3920: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c  onst char *path,
3930: 20 73 74 72 75 63 74 20 73 74 61 74 20 2a 73 74   struct stat *st
3940: 62 75 66 29 20 7b 0a 09 73 74 72 75 63 74 20 61  buf) {..struct a
3950: 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61  ppfs_pathinfo pa
3960: 74 68 69 6e 66 6f 3b 0a 09 69 6e 74 20 72 65 74  thinfo;..int ret
3970: 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20  val;...retval = 
3980: 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  0;...APPFS_DEBUG
3990: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
39a0: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
39b0: 3b 0a 0a 09 70 61 74 68 69 6e 66 6f 2e 74 79 70  ;...pathinfo.typ
39c0: 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59  e = APPFS_PATHTY
39d0: 50 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a 09 72 65  PE_INVALID;...re
39e0: 74 76 61 6c 20 3d 20 61 70 70 66 73 5f 67 65 74  tval = appfs_get
39f0: 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61 74 68 2c  _path_info(path,
3a00: 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a 09 69 66   &pathinfo);..if
3a10: 20 28 72 65 74 76 61 6c 20 21 3d 20 30 29 20 7b   (retval != 0) {
3a20: 0a 09 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c  ...return(retval
3a30: 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 73 65 74 28 73  );..}...memset(s
3a40: 74 62 75 66 2c 20 30 2c 20 73 69 7a 65 6f 66 28  tbuf, 0, sizeof(
3a50: 73 74 72 75 63 74 20 73 74 61 74 29 29 3b 0a 0a  struct stat));..
3a60: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 74 69 6d 65  .stbuf->st_mtime
3a70: 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65   = pathinfo.time
3a80: 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 63 74 69  ;..stbuf->st_cti
3a90: 6d 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69  me = pathinfo.ti
3aa0: 6d 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 61  me;..stbuf->st_a
3ab0: 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e  time = pathinfo.
3ac0: 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74  time;..stbuf->st
3ad0: 5f 69 6e 6f 20 20 20 3d 20 70 61 74 68 69 6e 66  _ino   = pathinf
3ae0: 6f 2e 69 6e 6f 64 65 3b 0a 09 73 74 62 75 66 2d  o.inode;..stbuf-
3af0: 3e 73 74 5f 6d 6f 64 65 20 20 3d 20 30 3b 0a 09  >st_mode  = 0;..
3b00: 73 74 62 75 66 2d 3e 73 74 5f 75 69 64 20 20 20  stbuf->st_uid   
3b10: 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69  = appfs_get_fsui
3b20: 64 28 29 3b 0a 0a 09 73 77 69 74 63 68 20 28 70  d();...switch (p
3b30: 61 74 68 69 6e 66 6f 2e 74 79 70 65 29 20 7b 0a  athinfo.type) {.
3b40: 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54  ..case APPFS_PAT
3b50: 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3a  HTYPE_DIRECTORY:
3b60: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f  ....stbuf->st_mo
3b70: 64 65 20 3d 20 53 5f 49 46 44 49 52 20 7c 20 30  de = S_IFDIR | 0
3b80: 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73  555;....stbuf->s
3b90: 74 5f 6e 6c 69 6e 6b 20 3d 20 32 20 2b 20 70 61  t_nlink = 2 + pa
3ba0: 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e  thinfo.typeinfo.
3bb0: 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 3b 0a  dir.childcount;.
3bc0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65  ...break;...case
3bd0: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
3be0: 46 49 4c 45 3a 0a 09 09 09 69 66 20 28 70 61 74  FILE:....if (pat
3bf0: 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66  hinfo.typeinfo.f
3c00: 69 6c 65 2e 65 78 65 63 75 74 61 62 6c 65 29 20  ile.executable) 
3c10: 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f  {.....stbuf->st_
3c20: 6d 6f 64 65 20 3d 20 53 5f 49 46 52 45 47 20 7c  mode = S_IFREG |
3c30: 20 30 35 35 35 3b 0a 09 09 09 7d 20 65 6c 73 65   0555;....} else
3c40: 20 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74   {.....stbuf->st
3c50: 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 52 45 47 20  _mode = S_IFREG 
3c60: 7c 20 30 34 34 34 3b 0a 09 09 09 7d 0a 0a 09 09  | 0444;....}....
3c70: 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b  .stbuf->st_nlink
3c80: 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e   = 1;....stbuf->
3c90: 73 74 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e  st_size = pathin
3ca0: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65  fo.typeinfo.file
3cb0: 2e 73 69 7a 65 3b 0a 09 09 09 62 72 65 61 6b 3b  .size;....break;
3cc0: 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 41  ...case APPFS_PA
3cd0: 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3a 0a  THTYPE_SYMLINK:.
3ce0: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ...stbuf->st_mod
3cf0: 65 20 3d 20 53 5f 49 46 4c 4e 4b 20 7c 20 30 35  e = S_IFLNK | 05
3d00: 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74  55;....stbuf->st
3d10: 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73  _nlink = 1;....s
3d20: 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20  tbuf->st_size = 
3d30: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66  pathinfo.typeinf
3d40: 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 3b 0a  o.symlink.size;.
3d50: 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65  ...break;...case
3d60: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f   APPFS_PATHTYPE_
3d70: 53 4f 43 4b 45 54 3a 0a 09 09 63 61 73 65 20 41  SOCKET:...case A
3d80: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49  PPFS_PATHTYPE_FI
3d90: 46 4f 3a 0a 09 09 63 61 73 65 20 41 50 50 46 53  FO:...case APPFS
3da0: 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49  _PATHTYPE_INVALI
3db0: 44 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20 2d  D:....retval = -
3dc0: 45 4e 4f 45 4e 54 3b 0a 0a 09 09 09 62 72 65 61  ENOENT;.....brea
3dd0: 6b 3b 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68  k;..}...if (path
3de0: 69 6e 66 6f 2e 70 61 63 6b 61 67 65 64 29 20 7b  info.packaged) {
3df0: 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64  ...stbuf->st_mod
3e00: 65 20 7c 3d 20 30 32 32 32 3b 0a 09 7d 0a 0a 09  e |= 0222;..}...
3e10: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a  return(retval);.
3e20: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
3e30: 70 66 73 5f 66 75 73 65 5f 72 65 61 64 64 69 72  pfs_fuse_readdir
3e40: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
3e50: 68 2c 20 76 6f 69 64 20 2a 62 75 66 2c 20 66 75  h, void *buf, fu
3e60: 73 65 5f 66 69 6c 6c 5f 64 69 72 5f 74 20 66 69  se_fill_dir_t fi
3e70: 6c 6c 65 72 2c 20 6f 66 66 5f 74 20 6f 66 66 73  ller, off_t offs
3e80: 65 74 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f  et, struct fuse_
3e90: 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b  file_info *fi) {
3ea0: 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  ..Tcl_Interp *in
3eb0: 74 65 72 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a  terp;..Tcl_Obj *
3ec0: 2a 63 68 69 6c 64 72 65 6e 3b 0a 09 69 6e 74 20  *children;..int 
3ed0: 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c 20  children_count, 
3ee0: 69 64 78 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65  idx;..int tcl_re
3ef0: 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47  t;...APPFS_DEBUG
3f00: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20  ("Enter (path = 
3f10: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29  %s, ...)", path)
3f20: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70  ;...interp = app
3f30: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a  fs_TclInterp();.
3f40: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e  .if (interp == N
3f50: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
3f60: 30 29 3b 0a 09 7d 0a 0a 09 66 69 6c 6c 65 72 28  0);..}...filler(
3f70: 62 75 66 2c 20 22 2e 22 2c 20 4e 55 4c 4c 2c 20  buf, ".", NULL, 
3f80: 30 29 3b 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c  0);..filler(buf,
3f90: 20 22 2e 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b   "..", NULL, 0);
3fa0: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70  ...tcl_ret = app
3fb0: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65  fs_Tcl_Eval(inte
3fc0: 72 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a  rp, 2, "::appfs:
3fd0: 3a 67 65 74 63 68 69 6c 64 72 65 6e 22 2c 20 70  :getchildren", p
3fe0: 61 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72  ath);..if (tcl_r
3ff0: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
4000: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a  ..APPFS_DEBUG(":
4010: 3a 61 70 70 66 73 3a 3a 67 65 74 63 68 69 6c 64  :appfs::getchild
4020: 72 65 6e 28 25 73 29 20 66 61 69 6c 65 64 2e 22  ren(%s) failed."
4030: 2c 20 70 61 74 68 29 3b 0a 09 09 41 50 50 46 53  , path);...APPFS
4040: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f  _DEBUG("Tcl Erro
4050: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47  r is: %s", Tcl_G
4060: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
4070: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75  nterp));....retu
4080: 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f  rn(0);..}...tcl_
4090: 72 65 74 20 3d 20 54 63 6c 5f 4c 69 73 74 4f 62  ret = Tcl_ListOb
40a0: 6a 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e 74  jGetElements(int
40b0: 65 72 70 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52  erp, Tcl_GetObjR
40c0: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 26  esult(interp), &
40d0: 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c 20  children_count, 
40e0: 26 63 68 69 6c 64 72 65 6e 29 3b 0a 09 69 66 20  &children);..if 
40f0: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f  (tcl_ret != TCL_
4100: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
4110: 42 55 47 28 22 50 61 72 73 69 6e 67 20 6c 69 73  BUG("Parsing lis
4120: 74 20 6f 66 20 63 68 69 6c 64 72 65 6e 20 6f 6e  t of children on
4130: 20 70 61 74 68 20 25 73 20 66 61 69 6c 65 64 2e   path %s failed.
4140: 22 2c 20 70 61 74 68 29 3b 0a 09 09 41 50 50 46  ", path);...APPF
4150: 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72  S_DEBUG("Tcl Err
4160: 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f  or is: %s", Tcl_
4170: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
4180: 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74  interp));....ret
4190: 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 66 6f 72  urn(0);..}...for
41a0: 20 28 69 64 78 20 3d 20 30 3b 20 69 64 78 20 3c   (idx = 0; idx <
41b0: 20 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 3b   children_count;
41c0: 20 69 64 78 2b 2b 29 20 7b 0a 09 09 66 69 6c 6c   idx++) {...fill
41d0: 65 72 28 62 75 66 2c 20 54 63 6c 5f 47 65 74 53  er(buf, Tcl_GetS
41e0: 74 72 69 6e 67 28 63 68 69 6c 64 72 65 6e 5b 69  tring(children[i
41f0: 64 78 5d 29 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a  dx]), NULL, 0);.
4200: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  .}...return(0);.
4210: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  }..static int ap
4220: 70 66 73 5f 66 75 73 65 5f 6f 70 65 6e 28 63 6f  pfs_fuse_open(co
4230: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
4240: 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65  struct fuse_file
4250: 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63  _info *fi) {..Tc
4260: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
4270: 3b 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f  ;..struct appfs_
4280: 70 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66  pathinfo pathinf
4290: 6f 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a  o;..const char *
42a0: 72 65 61 6c 5f 70 61 74 68 2c 20 2a 6d 6f 64 65  real_path, *mode
42b0: 3b 0a 09 69 6e 74 20 67 70 69 5f 72 65 74 2c 20  ;..int gpi_ret, 
42c0: 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 66 68  tcl_ret;..int fh
42d0: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28  ;...APPFS_DEBUG(
42e0: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25  "Enter (path = %
42f0: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b  s, ...)", path);
4300: 0a 0a 09 67 70 69 5f 72 65 74 20 3d 20 61 70 70  ...gpi_ret = app
4310: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f  fs_get_path_info
4320: 28 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f  (path, &pathinfo
4330: 29 3b 0a 0a 09 69 66 20 28 28 66 69 2d 3e 66 6c  );...if ((fi->fl
4340: 61 67 73 20 26 20 28 4f 5f 57 52 4f 4e 4c 59 7c  ags & (O_WRONLY|
4350: 4f 5f 43 52 45 41 54 29 29 20 3d 3d 20 28 4f 5f  O_CREAT)) == (O_
4360: 43 52 45 41 54 7c 4f 5f 57 52 4f 4e 4c 59 29 29  CREAT|O_WRONLY))
4370: 20 7b 0a 09 09 2f 2a 20 54 68 65 20 66 69 6c 65   {.../* The file
4380: 20 77 69 6c 6c 20 62 65 20 63 72 65 61 74 65 64   will be created
4390: 20 69 66 20 69 74 20 64 6f 65 73 20 6e 6f 74 20   if it does not 
43a0: 65 78 69 73 74 20 2a 2f 0a 09 09 69 66 20 28 67  exist */...if (g
43b0: 70 69 5f 72 65 74 20 21 3d 20 30 20 26 26 20 67  pi_ret != 0 && g
43c0: 70 69 5f 72 65 74 20 21 3d 20 2d 45 4e 4f 45 4e  pi_ret != -ENOEN
43d0: 54 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 67  T) {....return(g
43e0: 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09  pi_ret);...}....
43f0: 6d 6f 64 65 20 3d 20 22 63 72 65 61 74 65 22 3b  mode = "create";
4400: 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 2f 2a 20  ..} else {.../* 
4410: 54 68 65 20 66 69 6c 65 20 6d 75 73 74 20 61 6c  The file must al
4420: 72 65 61 64 79 20 65 78 69 73 74 20 2a 2f 0a 09  ready exist */..
4430: 09 69 66 20 28 67 70 69 5f 72 65 74 20 21 3d 20  .if (gpi_ret != 
4440: 30 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 67  0) {....return(g
4450: 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09  pi_ret);...}....
4460: 6d 6f 64 65 20 3d 20 22 22 3b 0a 0a 09 09 69 66  mode = "";....if
4470: 20 28 28 66 69 2d 3e 66 6c 61 67 73 20 26 20 4f   ((fi->flags & O
4480: 5f 57 52 4f 4e 4c 59 29 20 3d 3d 20 4f 5f 57 52  _WRONLY) == O_WR
4490: 4f 4e 4c 59 29 20 7b 0a 09 09 09 6d 6f 64 65 20  ONLY) {....mode 
44a0: 3d 20 22 77 72 69 74 65 22 3b 0a 09 09 7d 0a 09  = "write";...}..
44b0: 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f  }...if (pathinfo
44c0: 2e 74 79 70 65 20 3d 3d 20 41 50 50 46 53 5f 50  .type == APPFS_P
44d0: 41 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52  ATHTYPE_DIRECTOR
44e0: 59 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  Y) {...return(-E
44f0: 49 53 44 49 52 29 3b 0a 09 7d 0a 0a 09 69 6e 74  ISDIR);..}...int
4500: 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49  erp = appfs_TclI
4510: 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e  nterp();..if (in
4520: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
4530: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
4540: 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61  .}...tcl_ret = a
4550: 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e  ppfs_Tcl_Eval(in
4560: 74 65 72 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66  terp, 3, "::appf
4570: 73 3a 3a 6f 70 65 6e 70 61 74 68 22 2c 20 70 61  s::openpath", pa
4580: 74 68 2c 20 6d 6f 64 65 29 3b 0a 09 69 66 20 28  th, mode);..if (
4590: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
45a0: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
45b0: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65  UG("::appfs::ope
45c0: 6e 70 61 74 68 28 25 73 2c 20 25 73 29 20 66 61  npath(%s, %s) fa
45d0: 69 6c 65 64 2e 22 2c 20 70 61 74 68 2c 20 6d 6f  iled.", path, mo
45e0: 64 65 29 3b 0a 09 09 41 50 50 46 53 5f 44 45 42  de);...APPFS_DEB
45f0: 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73  UG("Tcl Error is
4600: 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74  : %s", Tcl_GetSt
4610: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
4620: 70 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d  p));....return(-
4630: 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f  EIO);..}...real_
4640: 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74 53 74  path = Tcl_GetSt
4650: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
4660: 70 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 61  p);..if (real_pa
4670: 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  th == NULL) {...
4680: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
4690: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
46a0: 54 72 61 6e 73 6c 61 74 65 64 20 72 65 71 75 65  Translated reque
46b0: 73 74 20 74 6f 20 6f 70 65 6e 20 25 73 20 74 6f  st to open %s to
46c0: 20 6f 70 65 6e 69 6e 67 20 25 73 20 28 6d 6f 64   opening %s (mod
46d0: 65 20 3d 20 5c 22 25 73 5c 22 29 22 2c 20 70 61  e = \"%s\")", pa
46e0: 74 68 2c 20 72 65 61 6c 5f 70 61 74 68 2c 20 6d  th, real_path, m
46f0: 6f 64 65 29 3b 0a 0a 09 66 68 20 3d 20 6f 70 65  ode);...fh = ope
4700: 6e 28 72 65 61 6c 5f 70 61 74 68 2c 20 66 69 2d  n(real_path, fi-
4710: 3e 66 6c 61 67 73 2c 20 30 36 30 30 29 3b 0a 09  >flags, 0600);..
4720: 69 66 20 28 66 68 20 3c 20 30 29 20 7b 0a 09 09  if (fh < 0) {...
4730: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d  return(-EIO);..}
4740: 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66 68 3b 0a  ...fi->fh = fh;.
4750: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
4760: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
4770: 5f 66 75 73 65 5f 63 6c 6f 73 65 28 63 6f 6e 73  _fuse_close(cons
4780: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74  t char *path, st
4790: 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69  ruct fuse_file_i
47a0: 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 69 6e 74 20  nfo *fi) {..int 
47b0: 63 6c 6f 73 65 5f 72 65 74 3b 0a 0a 09 63 6c 6f  close_ret;...clo
47c0: 73 65 5f 72 65 74 20 3d 20 63 6c 6f 73 65 28 66  se_ret = close(f
47d0: 69 2d 3e 66 68 29 3b 0a 09 69 66 20 28 63 6c 6f  i->fh);..if (clo
47e0: 73 65 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  se_ret != 0) {..
47f0: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
4800: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  }...return(0);.}
4810: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
4820: 66 73 5f 66 75 73 65 5f 72 65 61 64 28 63 6f 6e  fs_fuse_read(con
4830: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 63  st char *path, c
4840: 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74  har *buf, size_t
4850: 20 73 69 7a 65 2c 20 6f 66 66 5f 74 20 6f 66 66   size, off_t off
4860: 73 65 74 2c 20 73 74 72 75 63 74 20 66 75 73 65  set, struct fuse
4870: 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20  _file_info *fi) 
4880: 7b 0a 09 6f 66 66 5f 74 20 6c 73 65 65 6b 5f 72  {..off_t lseek_r
4890: 65 74 3b 0a 09 73 73 69 7a 65 5f 74 20 72 65 61  et;..ssize_t rea
48a0: 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  d_ret;...APPFS_D
48b0: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
48c0: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
48d0: 61 74 68 29 3b 0a 0a 09 6c 73 65 65 6b 5f 72 65  ath);...lseek_re
48e0: 74 20 3d 20 6c 73 65 65 6b 28 66 69 2d 3e 66 68  t = lseek(fi->fh
48f0: 2c 20 6f 66 66 73 65 74 2c 20 53 45 45 4b 5f 53  , offset, SEEK_S
4900: 45 54 29 3b 0a 09 69 66 20 28 6c 73 65 65 6b 5f  ET);..if (lseek_
4910: 72 65 74 20 21 3d 20 6f 66 66 73 65 74 29 20 7b  ret != offset) {
4920: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
4930: 0a 09 7d 0a 0a 09 72 65 61 64 5f 72 65 74 20 3d  ..}...read_ret =
4940: 20 72 65 61 64 28 66 69 2d 3e 66 68 2c 20 62 75   read(fi->fh, bu
4950: 66 2c 20 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75  f, size);...retu
4960: 72 6e 28 72 65 61 64 5f 72 65 74 29 3b 0a 7d 0a  rn(read_ret);.}.
4970: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66  .static int appf
4980: 73 5f 66 75 73 65 5f 77 72 69 74 65 28 63 6f 6e  s_fuse_write(con
4990: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 63  st char *path, c
49a0: 6f 6e 73 74 20 63 68 61 72 20 2a 62 75 66 2c 20  onst char *buf, 
49b0: 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f 66 66  size_t size, off
49c0: 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63  _t offset, struc
49d0: 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f  t fuse_file_info
49e0: 20 2a 66 69 29 20 7b 0a 09 6f 66 66 5f 74 20 6c   *fi) {..off_t l
49f0: 73 65 65 6b 5f 72 65 74 3b 0a 09 73 73 69 7a 65  seek_ret;..ssize
4a00: 5f 74 20 77 72 69 74 65 5f 72 65 74 3b 0a 0a 09  _t write_ret;...
4a10: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74  APPFS_DEBUG("Ent
4a20: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e  er (path = %s, .
4a30: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 6c  ..)", path);...l
4a40: 73 65 65 6b 5f 72 65 74 20 3d 20 6c 73 65 65 6b  seek_ret = lseek
4a50: 28 66 69 2d 3e 66 68 2c 20 6f 66 66 73 65 74 2c  (fi->fh, offset,
4a60: 20 53 45 45 4b 5f 53 45 54 29 3b 0a 09 69 66 20   SEEK_SET);..if 
4a70: 28 6c 73 65 65 6b 5f 72 65 74 20 21 3d 20 6f 66  (lseek_ret != of
4a80: 66 73 65 74 29 20 7b 0a 09 09 72 65 74 75 72 6e  fset) {...return
4a90: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 77 72 69  (-EIO);..}...wri
4aa0: 74 65 5f 72 65 74 20 3d 20 77 72 69 74 65 28 66  te_ret = write(f
4ab0: 69 2d 3e 66 68 2c 20 62 75 66 2c 20 73 69 7a 65  i->fh, buf, size
4ac0: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 77 72 69 74  );...return(writ
4ad0: 65 5f 72 65 74 29 3b 0a 7d 0a 0a 73 74 61 74 69  e_ret);.}..stati
4ae0: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65  c int appfs_fuse
4af0: 5f 6d 6b 6e 6f 64 28 63 6f 6e 73 74 20 63 68 61  _mknod(const cha
4b00: 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20  r *path, mode_t 
4b10: 6d 6f 64 65 2c 20 64 65 76 5f 74 20 64 65 76 69  mode, dev_t devi
4b20: 63 65 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 61  ce) {..char *rea
4b30: 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 6d 6b 6e  l_path;..int mkn
4b40: 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f  od_ret;...APPFS_
4b50: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
4b60: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
4b70: 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 28 6d 6f  path);...if ((mo
4b80: 64 65 20 26 20 53 5f 49 46 43 48 52 29 20 3d 3d  de & S_IFCHR) ==
4b90: 20 53 5f 49 46 43 48 52 29 20 7b 0a 09 09 72 65   S_IFCHR) {...re
4ba0: 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d  turn(-EPERM);..}
4bb0: 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53  ...if ((mode & S
4bc0: 5f 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49 46 42  _IFBLK) == S_IFB
4bd0: 4c 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d  LK) {...return(-
4be0: 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61  EPERM);..}...rea
4bf0: 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70  l_path = appfs_p
4c00: 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65  repare_to_create
4c10: 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61  (path);..if (rea
4c20: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20  l_path == NULL) 
4c30: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  {...return(-EIO)
4c40: 3b 0a 09 7d 0a 0a 09 6d 6b 6e 6f 64 5f 72 65 74  ;..}...mknod_ret
4c50: 20 3d 20 6d 6b 6e 6f 64 28 72 65 61 6c 5f 70 61   = mknod(real_pa
4c60: 74 68 2c 20 6d 6f 64 65 2c 20 64 65 76 69 63 65  th, mode, device
4c70: 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70  );...free(real_p
4c80: 61 74 68 29 3b 0a 0a 09 69 66 20 28 6d 6b 6e 6f  ath);...if (mkno
4c90: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  d_ret != 0) {...
4ca0: 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d  return(errno * -
4cb0: 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  1);..}...return(
4cc0: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e  0);.}..static in
4cd0: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 63 72 65  t appfs_fuse_cre
4ce0: 61 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ate(const char *
4cf0: 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64  path, mode_t mod
4d00: 65 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66  e, struct fuse_f
4d10: 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a  ile_info *fi) {.
4d20: 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68  .char *real_path
4d30: 3b 0a 09 69 6e 74 20 66 64 3b 0a 0a 09 41 50 50  ;..int fd;...APP
4d40: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20  FS_DEBUG("Enter 
4d50: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29  (path = %s, ...)
4d60: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69 66 20 28  ", path);...if (
4d70: 28 6d 6f 64 65 20 26 20 53 5f 49 46 43 48 52 29  (mode & S_IFCHR)
4d80: 20 3d 3d 20 53 5f 49 46 43 48 52 29 20 7b 0a 09   == S_IFCHR) {..
4d90: 09 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b  .return(-EPERM);
4da0: 0a 09 7d 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20  ..}...if ((mode 
4db0: 26 20 53 5f 49 46 42 4c 4b 29 20 3d 3d 20 53 5f  & S_IFBLK) == S_
4dc0: 49 46 42 4c 4b 29 20 7b 0a 09 09 72 65 74 75 72  IFBLK) {...retur
4dd0: 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09  n(-EPERM);..}...
4de0: 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66  real_path = appf
4df0: 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65  s_prepare_to_cre
4e00: 61 74 65 28 70 61 74 68 29 3b 0a 09 69 66 20 28  ate(path);..if (
4e10: 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c  real_path == NUL
4e20: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  L) {...return(-E
4e30: 49 4f 29 3b 0a 09 7d 0a 0a 09 66 64 20 3d 20 63  IO);..}...fd = c
4e40: 72 65 61 74 28 72 65 61 6c 5f 70 61 74 68 2c 20  reat(real_path, 
4e50: 6d 6f 64 65 29 3b 0a 0a 09 66 72 65 65 28 72 65  mode);...free(re
4e60: 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28  al_path);...if (
4e70: 66 64 20 3c 20 30 29 20 7b 0a 09 09 72 65 74 75  fd < 0) {...retu
4e80: 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a  rn(errno * -1);.
4e90: 09 7d 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66 64  .}...fi->fh = fd
4ea0: 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  ;...return(0);.}
4eb0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
4ec0: 66 73 5f 66 75 73 65 5f 74 72 75 6e 63 61 74 65  fs_fuse_truncate
4ed0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
4ee0: 68 2c 20 6f 66 66 5f 74 20 73 69 7a 65 29 20 7b  h, off_t size) {
4ef0: 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74  ..char *real_pat
4f00: 68 3b 0a 09 69 6e 74 20 74 72 75 6e 63 61 74 65  h;..int truncate
4f10: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
4f20: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
4f30: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
4f40: 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68  th);...real_path
4f50: 20 3d 20 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61   = appfs_localpa
4f60: 74 68 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72  th(path);..if (r
4f70: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c  eal_path == NULL
4f80: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49  ) {...return(-EI
4f90: 4f 29 3b 0a 09 7d 0a 0a 09 74 72 75 6e 63 61 74  O);..}...truncat
4fa0: 65 5f 72 65 74 20 3d 20 74 72 75 6e 63 61 74 65  e_ret = truncate
4fb0: 28 72 65 61 6c 5f 70 61 74 68 2c 20 73 69 7a 65  (real_path, size
4fc0: 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70  );...free(real_p
4fd0: 61 74 68 29 3b 0a 0a 09 69 66 20 28 74 72 75 6e  ath);...if (trun
4fe0: 63 61 74 65 5f 72 65 74 20 21 3d 20 30 29 20 7b  cate_ret != 0) {
4ff0: 0a 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20  ...return(errno 
5000: 2a 20 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  * -1);..}...retu
5010: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63  rn(0);.}..static
5020: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
5030: 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72 28 63 6f 6e  unlink_rmdir(con
5040: 73 74 20 63 68 61 72 20 2a 70 61 74 68 29 20 7b  st char *path) {
5050: 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  ..Tcl_Interp *in
5060: 74 65 72 70 3b 0a 09 69 6e 74 20 74 63 6c 5f 72  terp;..int tcl_r
5070: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  et;...APPFS_DEBU
5080: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
5090: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
50a0: 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70  );...interp = ap
50b0: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  pfs_TclInterp();
50c0: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
50d0: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
50e0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 74 63 6c  (-EIO);..}...tcl
50f0: 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c  _ret = appfs_Tcl
5100: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c  _Eval(interp, 2,
5110: 20 22 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c 69 6e   "::appfs::unlin
5120: 6b 70 61 74 68 22 2c 20 70 61 74 68 29 3b 0a 09  kpath", path);..
5130: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
5140: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53  CL_OK) {...APPFS
5150: 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a  _DEBUG("::appfs:
5160: 3a 75 6e 6c 69 6e 6b 70 61 74 68 28 25 73 29 20  :unlinkpath(%s) 
5170: 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b  failed.", path);
5180: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
5190: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
51a0: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
51b0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
51c0: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29  ....return(-EIO)
51d0: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29  ;..}...return(0)
51e0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
51f0: 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b 64 69 72  appfs_fuse_mkdir
5200: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
5210: 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 29 20  h, mode_t mode) 
5220: 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61  {..char *real_pa
5230: 74 68 3b 0a 09 69 6e 74 20 6d 6b 64 69 72 5f 72  th;..int mkdir_r
5240: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  et;...APPFS_DEBU
5250: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d  G("Enter (path =
5260: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68   %s, ...)", path
5270: 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d  );...real_path =
5280: 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74   appfs_prepare_t
5290: 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a  o_create(path);.
52a0: 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d  .if (real_path =
52b0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
52c0: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 6d  rn(-EIO);..}...m
52d0: 6b 64 69 72 5f 72 65 74 20 3d 20 6d 6b 64 69 72  kdir_ret = mkdir
52e0: 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65  (real_path, mode
52f0: 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c 5f 70  );...free(real_p
5300: 61 74 68 29 3b 0a 0a 09 69 66 20 28 6d 6b 64 69  ath);...if (mkdi
5310: 72 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  r_ret != 0) {...
5320: 69 66 20 28 65 72 72 6e 6f 20 21 3d 20 45 45 58  if (errno != EEX
5330: 49 53 54 29 20 7b 0a 09 09 09 72 65 74 75 72 6e  IST) {....return
5340: 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 09  (errno * -1);...
5350: 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29  }..}...return(0)
5360: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  ;.}..static int 
5370: 61 70 70 66 73 5f 66 75 73 65 5f 63 68 6d 6f 64  appfs_fuse_chmod
5380: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74  (const char *pat
5390: 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 29 20  h, mode_t mode) 
53a0: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
53b0: 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68  nterp;..const ch
53c0: 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09  ar *real_path;..
53d0: 69 6e 74 20 74 63 6c 5f 72 65 74 2c 20 63 68 6d  int tcl_ret, chm
53e0: 6f 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f  od_ret;...APPFS_
53f0: 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61  DEBUG("Enter (pa
5400: 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20  th = %s, ...)", 
5410: 70 61 74 68 29 3b 0a 0a 09 69 6e 74 65 72 70 20  path);...interp 
5420: 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72  = appfs_TclInter
5430: 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  p();..if (interp
5440: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65   == NULL) {...re
5450: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a  turn(-EIO);..}..
5460: 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73  .tcl_ret = appfs
5470: 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70  _Tcl_Eval(interp
5480: 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 6f  , 3, "::appfs::o
5490: 70 65 6e 70 61 74 68 22 2c 20 70 61 74 68 2c 20  penpath", path, 
54a0: 22 77 72 69 74 65 22 29 3b 0a 09 69 66 20 28 74  "write");..if (t
54b0: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
54c0: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55  ) {...APPFS_DEBU
54d0: 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e  G("::appfs::open
54e0: 70 61 74 68 28 25 73 2c 20 25 73 29 20 66 61 69  path(%s, %s) fai
54f0: 6c 65 64 2e 22 2c 20 70 61 74 68 2c 20 22 77 72  led.", path, "wr
5500: 69 74 65 22 29 3b 0a 09 09 41 50 50 46 53 5f 44  ite");...APPFS_D
5510: 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20  EBUG("Tcl Error 
5520: 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74  is: %s", Tcl_Get
5530: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
5540: 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e  erp));....return
5550: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65 61  (-EIO);..}...rea
5560: 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74  l_path = Tcl_Get
5570: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
5580: 65 72 70 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f  erp);..if (real_
5590: 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  path == NULL) {.
55a0: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a  ..return(-EIO);.
55b0: 09 7d 0a 0a 09 63 68 6d 6f 64 5f 72 65 74 20 3d  .}...chmod_ret =
55c0: 20 63 68 6d 6f 64 28 72 65 61 6c 5f 70 61 74 68   chmod(real_path
55d0: 2c 20 6d 6f 64 65 29 3b 0a 0a 09 72 65 74 75 72  , mode);...retur
55e0: 6e 28 63 68 6d 6f 64 5f 72 65 74 29 3b 0a 7d 0a  n(chmod_ret);.}.
55f0: 0a 2f 2a 0a 20 2a 20 53 51 4c 69 74 65 33 20 6d  ./*. * SQLite3 m
5600: 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72 61 77  ode: Execute raw
5610: 20 53 51 4c 20 61 6e 64 20 72 65 74 75 72 6e 20   SQL and return 
5620: 73 75 63 63 65 73 73 20 6f 72 20 66 61 69 6c 75  success or failu
5630: 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  re. */.static in
5640: 74 20 61 70 70 66 73 5f 73 71 6c 69 74 65 33 28  t appfs_sqlite3(
5650: 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 29  const char *sql)
5660: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
5670: 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63  interp;..const c
5680: 68 61 72 20 2a 73 71 6c 5f 72 65 74 3b 0a 09 69  har *sql_ret;..i
5690: 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e  nt tcl_ret;...in
56a0: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65  terp = appfs_cre
56b0: 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55  ate_TclInterp(NU
56c0: 4c 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70  LL);..if (interp
56d0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 70   == NULL) {...fp
56e0: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55  rintf(stderr, "U
56f0: 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20  nable to create 
5700: 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  a Tcl interprete
5710: 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22  r.  Aborting.\n"
5720: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b  );....return(1);
5730: 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20  ..}...tcl_ret = 
5740: 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69  appfs_Tcl_Eval(i
5750: 6e 74 65 72 70 2c 20 35 2c 20 22 3a 3a 61 70 70  nterp, 5, "::app
5760: 66 73 3a 3a 64 62 22 2c 20 22 65 76 61 6c 22 2c  fs::db", "eval",
5770: 20 73 71 6c 2c 20 22 72 6f 77 22 2c 20 22 75 6e   sql, "row", "un
5780: 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20  set -nocomplain 
5790: 72 6f 77 28 2a 29 3b 20 70 61 72 72 61 79 20 72  row(*); parray r
57a0: 6f 77 3b 20 70 75 74 73 20 5c 22 2d 2d 2d 2d 5c  ow; puts \"----\
57b0: 22 22 29 3b 0a 09 73 71 6c 5f 72 65 74 20 3d 20  "");..sql_ret = 
57c0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
57d0: 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 69  ult(interp);...i
57e0: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43  f (tcl_ret != TC
57f0: 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74  L_OK) {...fprint
5800: 66 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72 6f  f(stderr, "[erro
5810: 72 5d 20 25 73 5c 6e 22 2c 20 73 71 6c 5f 72 65  r] %s\n", sql_re
5820: 74 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29  t);....return(1)
5830: 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 71 6c 5f 72  ;..}...if (sql_r
5840: 65 74 20 26 26 20 73 71 6c 5f 72 65 74 5b 30 5d  et && sql_ret[0]
5850: 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09 70 72   != '\0') {...pr
5860: 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 73 71 6c  intf("%s\n", sql
5870: 5f 72 65 74 29 3b 0a 09 7d 0a 0a 09 72 65 74 75  _ret);..}...retu
5880: 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  rn(0);.}../*. * 
5890: 54 63 6c 20 6d 6f 64 65 3a 20 45 78 65 63 75 74  Tcl mode: Execut
58a0: 65 20 72 61 77 20 54 63 6c 20 61 6e 64 20 72 65  e raw Tcl and re
58b0: 74 75 72 6e 20 73 75 63 63 65 73 73 20 6f 72 20  turn success or 
58c0: 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74 61 74  failure. */.stat
58d0: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 74 63 6c  ic int appfs_tcl
58e0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c  (const char *tcl
58f0: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20  ) {..Tcl_Interp 
5900: 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20  *interp;..const 
5910: 63 68 61 72 20 2a 74 63 6c 5f 72 65 73 75 6c 74  char *tcl_result
5920: 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a  ;..int tcl_ret;.
5930: 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73  ..interp = appfs
5940: 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72  _create_TclInter
5950: 70 28 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 69 6e  p(NULL);..if (in
5960: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  terp == NULL) {.
5970: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
5980: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65  , "Unable to cre
5990: 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70  ate a Tcl interp
59a0: 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69 6e 67  reter.  Aborting
59b0: 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  .\n");....return
59c0: 28 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65  (1);..}...tcl_re
59d0: 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74  t = Tcl_Eval(int
59e0: 65 72 70 2c 20 74 63 6c 29 3b 0a 09 74 63 6c 5f  erp, tcl);..tcl_
59f0: 72 65 73 75 6c 74 20 3d 20 54 63 6c 5f 47 65 74  result = Tcl_Get
5a00: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
5a10: 65 72 70 29 3b 0a 0a 09 69 66 20 28 74 63 6c 5f  erp);...if (tcl_
5a20: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b  ret != TCL_OK) {
5a30: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
5a40: 72 2c 20 22 5b 65 72 72 6f 72 5d 20 25 73 5c 6e  r, "[error] %s\n
5a50: 22 2c 20 74 63 6c 5f 72 65 73 75 6c 74 29 3b 0a  ", tcl_result);.
5a60: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
5a70: 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 73 75 6c  ...if (tcl_resul
5a80: 74 20 26 26 20 74 63 6c 5f 72 65 73 75 6c 74 5b  t && tcl_result[
5a90: 30 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09  0] != '\0') {...
5aa0: 70 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 74  printf("%s\n", t
5ab0: 63 6c 5f 72 65 73 75 6c 74 29 3b 0a 09 7d 0a 0a  cl_result);..}..
5ac0: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f  .return(0);.}../
5ad0: 2a 0a 20 2a 20 41 70 70 46 53 64 20 50 61 63 6b  *. * AppFSd Pack
5ae0: 61 67 65 20 66 6f 72 20 54 63 6c 3a 0a 20 2a 20  age for Tcl:. * 
5af0: 20 20 20 20 20 20 20 20 42 72 69 64 67 65 20 66          Bridge f
5b00: 6f 72 20 49 2f 4f 20 6f 70 65 72 61 74 69 6f 6e  or I/O operation
5b10: 73 20 74 6f 20 72 65 71 75 65 73 74 20 69 6e 66  s to request inf
5b20: 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 74  ormation about t
5b30: 68 65 20 63 75 72 72 65 6e 74 0a 20 2a 20 20 20  he current. *   
5b40: 20 20 20 20 20 20 74 72 61 6e 73 61 63 74 69 6f        transactio
5b50: 6e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  n. */.static int
5b60: 20 41 70 70 66 73 64 5f 49 6e 69 74 28 54 63 6c   Appfsd_Init(Tcl
5b70: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29  _Interp *interp)
5b80: 20 7b 0a 23 69 66 64 65 66 20 55 53 45 5f 54 43   {.#ifdef USE_TC
5b90: 4c 5f 53 54 55 42 53 0a 09 69 66 20 28 54 63 6c  L_STUBS..if (Tcl
5ba0: 5f 49 6e 69 74 53 74 75 62 73 28 69 6e 74 65 72  _InitStubs(inter
5bb0: 70 2c 20 54 43 4c 5f 56 45 52 53 49 4f 4e 2c 20  p, TCL_VERSION, 
5bc0: 30 29 20 3d 3d 20 30 4c 29 20 7b 0a 09 09 72 65  0) == 0L) {...re
5bd0: 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b  turn(TCL_ERROR);
5be0: 0a 09 7d 0a 23 65 6e 64 69 66 0a 0a 09 54 63 6c  ..}.#endif...Tcl
5bf0: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e  _CreateObjComman
5c00: 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73  d(interp, "appfs
5c10: 64 3a 3a 67 65 74 5f 68 6f 6d 65 64 69 72 22 2c  d::get_homedir",
5c20: 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68   tcl_appfs_get_h
5c30: 6f 6d 65 64 69 72 2c 20 4e 55 4c 4c 2c 20 4e 55  omedir, NULL, NU
5c40: 4c 4c 29 3b 0a 0a 09 54 63 6c 5f 50 6b 67 50 72  LL);...Tcl_PkgPr
5c50: 6f 76 69 64 65 28 69 6e 74 65 72 70 2c 20 22 61  ovide(interp, "a
5c60: 70 70 66 73 64 22 2c 20 22 31 2e 30 22 29 3b 0a  ppfsd", "1.0");.
5c70: 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29  ..return(TCL_OK)
5c80: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 46 55 53 45 20  ;.}../*. * FUSE 
5c90: 6f 70 65 72 61 74 69 6f 6e 73 20 73 74 72 75 63  operations struc
5ca0: 74 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20  ture. */.static 
5cb0: 73 74 72 75 63 74 20 66 75 73 65 5f 6f 70 65 72  struct fuse_oper
5cc0: 61 74 69 6f 6e 73 20 61 70 70 66 73 5f 6f 70 65  ations appfs_ope
5cd0: 72 61 74 69 6f 6e 73 20 3d 20 7b 0a 09 2e 67 65  rations = {...ge
5ce0: 74 61 74 74 72 20 20 20 3d 20 61 70 70 66 73 5f  tattr   = appfs_
5cf0: 66 75 73 65 5f 67 65 74 61 74 74 72 2c 0a 09 2e  fuse_getattr,...
5d00: 72 65 61 64 64 69 72 20 20 20 3d 20 61 70 70 66  readdir   = appf
5d10: 73 5f 66 75 73 65 5f 72 65 61 64 64 69 72 2c 0a  s_fuse_readdir,.
5d20: 09 2e 72 65 61 64 6c 69 6e 6b 20 20 3d 20 61 70  ..readlink  = ap
5d30: 70 66 73 5f 66 75 73 65 5f 72 65 61 64 6c 69 6e  pfs_fuse_readlin
5d40: 6b 2c 0a 09 2e 6f 70 65 6e 20 20 20 20 20 20 3d  k,...open      =
5d50: 20 61 70 70 66 73 5f 66 75 73 65 5f 6f 70 65 6e   appfs_fuse_open
5d60: 2c 0a 09 2e 72 65 6c 65 61 73 65 20 20 20 3d 20  ,...release   = 
5d70: 61 70 70 66 73 5f 66 75 73 65 5f 63 6c 6f 73 65  appfs_fuse_close
5d80: 2c 0a 09 2e 72 65 61 64 20 20 20 20 20 20 3d 20  ,...read      = 
5d90: 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 2c  appfs_fuse_read,
5da0: 0a 09 2e 77 72 69 74 65 20 20 20 20 20 3d 20 61  ...write     = a
5db0: 70 70 66 73 5f 66 75 73 65 5f 77 72 69 74 65 2c  ppfs_fuse_write,
5dc0: 0a 09 2e 6d 6b 6e 6f 64 20 20 20 20 20 3d 20 61  ...mknod     = a
5dd0: 70 70 66 73 5f 66 75 73 65 5f 6d 6b 6e 6f 64 2c  ppfs_fuse_mknod,
5de0: 0a 09 2e 63 72 65 61 74 65 20 20 20 20 3d 20 61  ...create    = a
5df0: 70 70 66 73 5f 66 75 73 65 5f 63 72 65 61 74 65  ppfs_fuse_create
5e00: 2c 0a 09 2e 74 72 75 6e 63 61 74 65 20 20 3d 20  ,...truncate  = 
5e10: 61 70 70 66 73 5f 66 75 73 65 5f 74 72 75 6e 63  appfs_fuse_trunc
5e20: 61 74 65 2c 0a 09 2e 75 6e 6c 69 6e 6b 20 20 20  ate,...unlink   
5e30: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e   = appfs_fuse_un
5e40: 6c 69 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 72 6d  link_rmdir,...rm
5e50: 64 69 72 20 20 20 20 20 3d 20 61 70 70 66 73 5f  dir     = appfs_
5e60: 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69  fuse_unlink_rmdi
5e70: 72 2c 0a 09 2e 6d 6b 64 69 72 20 20 20 20 20 3d  r,...mkdir     =
5e80: 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b 64 69   appfs_fuse_mkdi
5e90: 72 2c 0a 09 2e 63 68 6d 6f 64 20 20 20 20 20 3d  r,...chmod     =
5ea0: 20 61 70 70 66 73 5f 66 75 73 65 5f 63 68 6d 6f   appfs_fuse_chmo
5eb0: 64 2c 0a 7d 3b 0a 0a 2f 2a 0a 20 2a 20 46 55 53  d,.};../*. * FUS
5ec0: 45 20 6f 70 74 69 6f 6e 20 70 61 72 73 69 6e 67  E option parsing
5ed0: 20 63 61 6c 6c 62 61 63 6b 0a 20 2a 2f 0a 73 74   callback. */.st
5ee0: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66  atic int appfs_f
5ef0: 75 73 65 5f 6f 70 74 5f 63 62 28 76 6f 69 64 20  use_opt_cb(void 
5f00: 2a 64 61 74 61 2c 20 63 6f 6e 73 74 20 63 68 61  *data, const cha
5f10: 72 20 2a 61 72 67 2c 20 69 6e 74 20 6b 65 79 2c  r *arg, int key,
5f20: 20 73 74 72 75 63 74 20 66 75 73 65 5f 61 72 67   struct fuse_arg
5f30: 73 20 2a 6f 75 74 61 72 67 73 29 20 7b 0a 09 73  s *outargs) {..s
5f40: 74 61 74 69 63 20 69 6e 74 20 73 65 65 6e 5f 63  tatic int seen_c
5f50: 61 63 68 65 64 69 72 20 3d 20 30 3b 0a 0a 09 69  achedir = 0;...i
5f60: 66 20 28 6b 65 79 20 3d 3d 20 46 55 53 45 5f 4f  f (key == FUSE_O
5f70: 50 54 5f 4b 45 59 5f 4e 4f 4e 4f 50 54 20 26 26  PT_KEY_NONOPT &&
5f80: 20 73 65 65 6e 5f 63 61 63 68 65 64 69 72 20 3d   seen_cachedir =
5f90: 3d 20 30 29 20 7b 0a 09 09 73 65 65 6e 5f 63 61  = 0) {...seen_ca
5fa0: 63 68 65 64 69 72 20 3d 20 31 3b 0a 0a 09 09 61  chedir = 1;....a
5fb0: 70 70 66 73 5f 63 61 63 68 65 64 69 72 20 3d 20  ppfs_cachedir = 
5fc0: 73 74 72 64 75 70 28 61 72 67 29 3b 0a 0a 09 09  strdup(arg);....
5fd0: 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09  return(0);..}...
5fe0: 72 65 74 75 72 6e 28 31 29 3b 0a 7d 0a 0a 2f 2a  return(1);.}../*
5ff0: 0a 20 2a 20 45 6e 74 72 79 20 70 6f 69 6e 74 20  . * Entry point 
6000: 69 6e 74 6f 20 74 68 69 73 20 70 72 6f 67 72 61  into this progra
6010: 6d 2e 0a 20 2a 2f 0a 69 6e 74 20 6d 61 69 6e 28  m.. */.int main(
6020: 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a  int argc, char *
6030: 2a 61 72 67 76 29 20 7b 0a 09 54 63 6c 5f 49 6e  *argv) {..Tcl_In
6040: 74 65 72 70 20 2a 74 65 73 74 5f 69 6e 74 65 72  terp *test_inter
6050: 70 3b 0a 09 63 68 61 72 20 2a 74 65 73 74 5f 69  p;..char *test_i
6060: 6e 74 65 72 70 5f 65 72 72 6f 72 3b 0a 09 73 74  nterp_error;..st
6070: 72 75 63 74 20 66 75 73 65 5f 61 72 67 73 20 61  ruct fuse_args a
6080: 72 67 73 20 3d 20 46 55 53 45 5f 41 52 47 53 5f  rgs = FUSE_ARGS_
6090: 49 4e 49 54 28 61 72 67 63 2c 20 61 72 67 76 29  INIT(argc, argv)
60a0: 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72  ;..int pthread_r
60b0: 65 74 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53 6b 69  et;.../*.. * Ski
60c0: 70 20 70 61 73 73 65 64 20 70 72 6f 67 72 61 6d  p passed program
60d0: 20 6e 61 6d 65 0a 09 20 2a 2f 0a 09 69 66 20 28   name.. */..if (
60e0: 61 72 67 63 20 3d 3d 20 30 20 7c 7c 20 61 72 67  argc == 0 || arg
60f0: 76 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72  v == NULL) {...r
6100: 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 09 61 72  eturn(1);..}..ar
6110: 67 63 2d 2d 3b 0a 09 61 72 67 76 2b 2b 3b 0a 0a  gc--;..argv++;..
6120: 09 2f 2a 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62  ./*.. * Set glob
6130: 61 6c 20 76 61 72 69 61 62 6c 65 73 2c 20 74 68  al variables, th
6140: 65 73 65 20 73 68 6f 75 6c 64 20 62 65 20 63 6f  ese should be co
6150: 6e 66 69 67 75 72 61 74 69 6f 6e 20 6f 70 74 69  nfiguration opti
6160: 6f 6e 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73  ons... */..appfs
6170: 5f 63 61 63 68 65 64 69 72 20 3d 20 41 50 50 46  _cachedir = APPF
6180: 53 5f 43 41 43 48 45 44 49 52 3b 0a 0a 09 2f 2a  S_CACHEDIR;.../*
6190: 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20  .. * Set global 
61a0: 76 61 72 69 61 62 6c 65 20 66 6f 72 20 22 62 6f  variable for "bo
61b0: 6f 74 20 74 69 6d 65 22 20 74 6f 20 73 65 74 20  ot time" to set 
61c0: 61 20 74 69 6d 65 20 6f 6e 20 64 69 72 65 63 74  a time on direct
61d0: 6f 72 69 65 73 0a 09 20 2a 20 74 68 61 74 20 77  ories.. * that w
61e0: 65 20 66 61 6b 65 2e 0a 09 20 2a 2f 0a 09 61 70  e fake... */..ap
61f0: 70 66 73 5f 62 6f 6f 74 74 69 6d 65 20 3d 20 74  pfs_boottime = t
6200: 69 6d 65 28 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a  ime(NULL);.../*.
6210: 09 20 2a 20 52 65 67 69 73 74 65 72 20 22 73 68  . * Register "sh
6220: 61 31 22 20 61 6e 64 20 22 61 70 70 66 73 64 22  a1" and "appfsd"
6230: 20 70 61 63 6b 61 67 65 20 77 69 74 68 20 6c 69   package with li
6240: 62 74 63 6c 20 73 6f 20 74 68 61 74 20 61 6e 79  btcl so that any
6250: 20 6e 65 77 0a 09 20 2a 20 69 6e 74 65 72 70 72   new.. * interpr
6260: 65 74 65 72 73 20 63 72 65 61 74 65 64 20 28 77  eters created (w
6270: 68 69 63 68 20 61 72 65 20 64 6f 6e 65 20 64 79  hich are done dy
6280: 6e 61 6d 69 63 61 6c 6c 79 20 62 79 20 46 55 53  namically by FUS
6290: 45 29 20 63 61 6e 20 68 61 76 65 0a 09 20 2a 20  E) can have.. * 
62a0: 74 68 65 20 61 70 70 72 6f 70 72 69 61 74 65 20  the appropriate 
62b0: 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 64 6f  configuration do
62c0: 6e 65 20 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79  ne automatically
62d0: 2e 0a 09 20 2a 2f 0a 09 54 63 6c 5f 53 74 61 74  ... */..Tcl_Stat
62e0: 69 63 50 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20  icPackage(NULL, 
62f0: 22 73 68 61 31 22 2c 20 53 68 61 31 5f 49 6e 69  "sha1", Sha1_Ini
6300: 74 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 53  t, NULL);..Tcl_S
6310: 74 61 74 69 63 50 61 63 6b 61 67 65 28 4e 55 4c  taticPackage(NUL
6320: 4c 2c 20 22 61 70 70 66 73 64 22 2c 20 41 70 70  L, "appfsd", App
6330: 66 73 64 5f 49 6e 69 74 2c 20 4e 55 4c 4c 29 3b  fsd_Init, NULL);
6340: 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72 65 61 74 65  .../*.. * Create
6350: 20 61 20 74 68 72 65 61 64 2d 73 70 65 63 69 66   a thread-specif
6360: 69 63 2d 64 61 74 61 20 28 54 53 44 29 20 6b 65  ic-data (TSD) ke
6370: 79 20 66 6f 72 20 65 61 63 68 20 74 68 72 65 61  y for each threa
6380: 64 20 74 6f 20 72 65 66 65 72 0a 09 20 2a 20 74  d to refer.. * t
6390: 6f 20 69 74 73 20 6f 77 6e 20 54 63 6c 20 69 6e  o its own Tcl in
63a0: 74 65 72 70 72 65 74 65 72 2e 20 20 54 63 6c 20  terpreter.  Tcl 
63b0: 69 6e 74 65 72 70 72 65 74 65 72 73 20 6d 75 73  interpreters mus
63c0: 74 20 62 65 20 75 6e 69 71 75 65 20 70 65 72 0a  t be unique per.
63d0: 09 20 2a 20 74 68 72 65 61 64 20 61 6e 64 20 6e  . * thread and n
63e0: 65 77 20 74 68 72 65 61 64 73 20 61 72 65 20 64  ew threads are d
63f0: 79 6e 61 6d 69 63 61 6c 6c 79 20 63 72 65 61 74  ynamically creat
6400: 65 64 20 62 79 20 46 55 53 45 2e 0a 09 20 2a 2f  ed by FUSE... */
6410: 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20  ..pthread_ret = 
6420: 70 74 68 72 65 61 64 5f 6b 65 79 5f 63 72 65 61  pthread_key_crea
6430: 74 65 28 26 69 6e 74 65 72 70 4b 65 79 2c 20 4e  te(&interpKey, N
6440: 55 4c 4c 29 3b 0a 09 69 66 20 28 70 74 68 72 65  ULL);..if (pthre
6450: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  ad_ret != 0) {..
6460: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
6470: 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61   "Unable to crea
6480: 74 65 20 54 53 44 20 6b 65 79 20 66 6f 72 20 54  te TSD key for T
6490: 63 6c 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e  cl.  Aborting.\n
64a0: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29  ");....return(1)
64b0: 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4d 61  ;..}.../*.. * Ma
64c0: 6e 75 61 6c 6c 79 20 73 70 65 63 69 66 79 20 63  nually specify c
64d0: 61 63 68 65 20 64 69 72 65 63 74 6f 72 79 2c 20  ache directory, 
64e0: 77 69 74 68 6f 75 74 20 46 55 53 45 20 63 61 6c  without FUSE cal
64f0: 6c 62 61 63 6b 0a 09 20 2a 20 54 68 69 73 20 6f  lback.. * This o
6500: 70 74 69 6f 6e 20 6f 6e 6c 79 20 77 6f 72 6b 73  ption only works
6510: 20 77 68 65 6e 20 6e 6f 74 20 75 73 69 6e 67 20   when not using 
6520: 46 55 53 45 2c 20 73 69 6e 63 65 20 77 65 0a 09  FUSE, since we..
6530: 20 2a 20 64 6f 20 6e 6f 74 20 70 72 6f 63 65 73   * do not proces
6540: 73 20 69 74 20 77 69 74 68 20 46 55 53 45 73 20  s it with FUSEs 
6550: 6f 70 74 69 6f 6e 20 70 72 6f 63 65 73 73 69 6e  option processin
6560: 67 2e 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72 67  g... */..if (arg
6570: 63 20 3e 3d 20 32 29 20 7b 0a 09 09 69 66 20 28  c >= 2) {...if (
6580: 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20  strcmp(argv[0], 
6590: 22 2d 2d 63 61 63 68 65 64 69 72 22 29 20 3d 3d  "--cachedir") ==
65a0: 20 30 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63   0) {....appfs_c
65b0: 61 63 68 65 64 69 72 20 3d 20 73 74 72 64 75 70  achedir = strdup
65c0: 28 61 72 67 76 5b 31 5d 29 3b 0a 0a 09 09 09 61  (argv[1]);.....a
65d0: 72 67 63 20 2d 3d 20 32 3b 0a 09 09 09 61 72 67  rgc -= 2;....arg
65e0: 76 20 2b 3d 20 32 3b 0a 09 09 7d 0a 09 7d 0a 0a  v += 2;...}..}..
65f0: 09 2f 2a 0a 09 20 2a 20 53 51 4c 69 74 65 33 20  ./*.. * SQLite3 
6600: 6d 6f 64 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e  mode, for runnin
6610: 67 20 72 61 77 20 53 51 4c 20 61 67 61 69 6e 73  g raw SQL agains
6620: 74 20 74 68 65 20 63 61 63 68 65 20 64 61 74 61  t the cache data
6630: 62 61 73 65 0a 09 20 2a 2f 0a 09 69 66 20 28 61  base.. */..if (a
6640: 72 67 63 20 3d 3d 20 32 20 26 26 20 73 74 72 63  rgc == 2 && strc
6650: 6d 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 73  mp(argv[0], "--s
6660: 71 6c 69 74 65 33 22 29 20 3d 3d 20 30 29 20 7b  qlite3") == 0) {
6670: 0a 09 09 72 65 74 75 72 6e 28 61 70 70 66 73 5f  ...return(appfs_
6680: 73 71 6c 69 74 65 33 28 61 72 67 76 5b 31 5d 29  sqlite3(argv[1])
6690: 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 54  );..}.../*.. * T
66a0: 63 6c 20 6d 6f 64 65 2c 20 66 6f 72 20 72 75 6e  cl mode, for run
66b0: 6e 69 6e 67 20 72 61 77 20 54 63 6c 20 69 6e 20  ning raw Tcl in 
66c0: 74 68 65 20 73 61 6d 65 20 65 6e 76 69 72 6f 6e  the same environ
66d0: 6d 65 6e 74 20 41 70 70 46 53 64 20 77 6f 75 6c  ment AppFSd woul
66e0: 64 0a 09 20 2a 20 72 75 6e 20 63 6f 64 65 2e 0a  d.. * run code..
66f0: 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d  . */..if (argc =
6700: 3d 20 32 20 26 26 20 73 74 72 63 6d 70 28 61 72  = 2 && strcmp(ar
6710: 67 76 5b 30 5d 2c 20 22 2d 2d 74 63 6c 22 29 20  gv[0], "--tcl") 
6720: 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e  == 0) {...return
6730: 28 61 70 70 66 73 5f 74 63 6c 28 61 72 67 76 5b  (appfs_tcl(argv[
6740: 31 5d 29 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20  1]));..}.../*.. 
6750: 2a 20 41 64 64 20 46 55 53 45 20 61 72 67 75 6d  * Add FUSE argum
6760: 65 6e 74 73 20 77 68 69 63 68 20 77 65 20 61 6c  ents which we al
6770: 77 61 79 73 20 73 75 70 70 6c 79 0a 09 20 2a 2f  ways supply.. */
6780: 0a 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65  ..fuse_opt_parse
6790: 28 26 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55  (&args, NULL, NU
67a0: 4c 4c 2c 20 61 70 70 66 73 5f 66 75 73 65 5f 6f  LL, appfs_fuse_o
67b0: 70 74 5f 63 62 29 3b 0a 09 66 75 73 65 5f 6f 70  pt_cb);..fuse_op
67c0: 74 5f 61 64 64 5f 61 72 67 28 26 61 72 67 73 2c  t_add_arg(&args,
67d0: 20 22 2d 6f 64 65 66 61 75 6c 74 5f 70 65 72 6d   "-odefault_perm
67e0: 69 73 73 69 6f 6e 73 2c 66 73 6e 61 6d 65 3d 61  issions,fsname=a
67f0: 70 70 66 73 2c 73 75 62 74 79 70 65 3d 61 70 70  ppfs,subtype=app
6800: 66 73 64 2c 75 73 65 5f 69 6e 6f 2c 6b 65 72 6e  fsd,use_ino,kern
6810: 65 6c 5f 63 61 63 68 65 2c 65 6e 74 72 79 5f 74  el_cache,entry_t
6820: 69 6d 65 6f 75 74 3d 36 30 2c 61 74 74 72 5f 74  imeout=60,attr_t
6830: 69 6d 65 6f 75 74 3d 33 36 30 30 2c 69 6e 74 72  imeout=3600,intr
6840: 2c 62 69 67 5f 77 72 69 74 65 73 22 29 3b 0a 0a  ,big_writes");..
6850: 09 69 66 20 28 67 65 74 75 69 64 28 29 20 3d 3d  .if (getuid() ==
6860: 20 30 29 20 7b 0a 09 09 66 75 73 65 5f 6f 70 74   0) {...fuse_opt
6870: 5f 70 61 72 73 65 28 26 61 72 67 73 2c 20 4e 55  _parse(&args, NU
6880: 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b  LL, NULL, NULL);
6890: 0a 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f  ...fuse_opt_add_
68a0: 61 72 67 28 26 61 72 67 73 2c 20 22 2d 6f 61 6c  arg(&args, "-oal
68b0: 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a 09 7d 0a  low_other");..}.
68c0: 0a 09 2f 2a 0a 09 20 2a 20 43 72 65 61 74 65 20  ../*.. * Create 
68d0: 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65  a Tcl interprete
68e0: 72 20 6a 75 73 74 20 74 6f 20 76 65 72 69 66 79  r just to verify
68f0: 20 74 68 61 74 20 74 68 69 6e 67 73 20 61 72 65   that things are
6900: 20 69 6e 20 77 6f 72 6b 69 6e 67 20 0a 09 20 2a   in working .. *
6910: 20 6f 72 64 65 72 20 62 65 66 6f 72 65 20 77 65   order before we
6920: 20 62 65 63 6f 6d 65 20 61 20 64 61 65 6d 6f 6e   become a daemon
6930: 2e 0a 09 20 2a 2f 0a 09 74 65 73 74 5f 69 6e 74  ... */..test_int
6940: 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61  erp = appfs_crea
6950: 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 26 74 65  te_TclInterp(&te
6960: 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 29  st_interp_error)
6970: 3b 0a 09 69 66 20 28 74 65 73 74 5f 69 6e 74 65  ;..if (test_inte
6980: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  rp == NULL) {...
6990: 69 66 20 28 74 65 73 74 5f 69 6e 74 65 72 70 5f  if (test_interp_
69a0: 65 72 72 6f 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b  error == NULL) {
69b0: 0a 09 09 09 74 65 73 74 5f 69 6e 74 65 72 70 5f  ....test_interp_
69c0: 65 72 72 6f 72 20 3d 20 22 55 6e 6b 6e 6f 77 6e  error = "Unknown
69d0: 20 65 72 72 6f 72 22 3b 0a 09 09 7d 0a 0a 09 09   error";...}....
69e0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
69f0: 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69  "Unable to initi
6a00: 61 6c 69 7a 65 20 54 63 6c 20 69 6e 74 65 72 70  alize Tcl interp
6a10: 72 65 74 65 72 20 66 6f 72 20 41 70 70 46 53 64  reter for AppFSd
6a20: 3a 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66  :\n");...fprintf
6a30: 28 73 74 64 65 72 72 2c 20 22 25 73 22 2c 20 74  (stderr, "%s", t
6a40: 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72  est_interp_error
6a50: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b  );....return(1);
6a60: 0a 09 7d 0a 09 54 63 6c 5f 44 65 6c 65 74 65 49  ..}..Tcl_DeleteI
6a70: 6e 74 65 72 70 28 74 65 73 74 5f 69 6e 74 65 72  nterp(test_inter
6a80: 70 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 45 6e 74  p);.../*.. * Ent
6a90: 65 72 20 74 68 65 20 46 55 53 45 20 6d 61 69 6e  er the FUSE main
6aa0: 20 6c 6f 6f 70 20 2d 2d 20 74 68 69 73 20 77 69   loop -- this wi
6ab0: 6c 6c 20 70 72 6f 63 65 73 73 20 61 6e 79 20 61  ll process any a
6ac0: 72 67 75 6d 65 6e 74 73 0a 09 20 2a 20 61 6e 64  rguments.. * and
6ad0: 20 73 74 61 72 74 20 73 65 72 76 69 63 69 6e 67   start servicing
6ae0: 20 72 65 71 75 65 73 74 73 2e 0a 09 20 2a 2f 0a   requests... */.
6af0: 09 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61 72  .appfs_fuse_star
6b00: 74 65 64 20 3d 20 31 3b 0a 09 72 65 74 75 72 6e  ted = 1;..return
6b10: 28 66 75 73 65 5f 6d 61 69 6e 28 61 72 67 73 2e  (fuse_main(args.
6b20: 61 72 67 63 2c 20 61 72 67 73 2e 61 72 67 76 2c  argc, args.argv,
6b30: 20 26 61 70 70 66 73 5f 6f 70 65 72 61 74 69 6f   &appfs_operatio
6b40: 6e 73 2c 20 4e 55 4c 4c 29 29 3b 0a 7d 0a 20 0a  ns, NULL));.}. .