Hex Artifact Content

Artifact 16b07e2510c9ccce0a9282b5d6bde07256aff0ad:


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 0a 2f 2a 0a  s_boottime;../*.
03c0: 20 2a 20 41 70 70 46 53 20 50 61 74 68 20 54 79   * AppFS Path Ty
03d0: 70 65 3a 20 20 44 65 73 63 72 69 62 65 73 20 74  pe:  Describes t
03e0: 68 65 20 74 79 70 65 20 6f 66 20 70 61 74 68 20  he type of path 
03f0: 61 20 67 69 76 65 6e 20 66 69 6c 65 20 69 73 0a  a given file is.
0400: 20 2a 2f 0a 74 79 70 65 64 65 66 20 65 6e 75 6d   */.typedef enum
0410: 20 7b 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59   {..APPFS_PATHTY
0420: 50 45 5f 49 4e 56 41 4c 49 44 2c 0a 09 41 50 50  PE_INVALID,..APP
0430: 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49 4c 45  FS_PATHTYPE_FILE
0440: 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50  ,..APPFS_PATHTYP
0450: 45 5f 44 49 52 45 43 54 4f 52 59 2c 0a 09 41 50  E_DIRECTORY,..AP
0460: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59 4d  PFS_PATHTYPE_SYM
0470: 4c 49 4e 4b 0a 7d 20 61 70 70 66 73 5f 70 61 74  LINK.} appfs_pat
0480: 68 74 79 70 65 5f 74 3b 0a 0a 2f 2a 0a 20 2a 20  htype_t;../*. * 
0490: 41 70 70 46 53 20 43 68 69 6c 64 72 65 6e 20 46  AppFS Children F
04a0: 69 6c 65 73 20 6c 69 6e 6b 65 64 2d 6c 69 73 74  iles linked-list
04b0: 0a 20 2a 2f 0a 73 74 72 75 63 74 20 61 70 70 66  . */.struct appf
04c0: 73 5f 63 68 69 6c 64 72 65 6e 20 7b 0a 09 73 74  s_children {..st
04d0: 72 75 63 74 20 61 70 70 66 73 5f 63 68 69 6c 64  ruct appfs_child
04e0: 72 65 6e 20 2a 5f 6e 65 78 74 3b 0a 09 63 68 61  ren *_next;..cha
04f0: 72 20 6e 61 6d 65 5b 32 35 36 5d 3b 0a 7d 3b 0a  r name[256];.};.
0500: 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 20 50 61 74  ./*. * AppFS Pat
0510: 68 20 49 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 20  h Information:. 
0520: 2a 20 20 20 20 20 20 20 20 20 43 6f 6d 70 6c 65  *         Comple
0530: 74 65 6c 79 20 64 65 73 63 72 69 62 65 73 20 61  tely describes a
0540: 20 73 70 65 63 69 66 69 63 20 70 61 74 68 2c 20   specific path, 
0550: 68 6f 77 20 69 74 20 73 68 6f 75 6c 64 20 62 65  how it should be
0560: 20 72 65 74 75 72 6e 65 64 20 74 6f 0a 20 2a 20   returned to. * 
0570: 20 20 20 20 20 20 20 20 74 6f 20 74 68 65 20 6b          to the k
0580: 65 72 6e 65 6c 0a 20 2a 2f 0a 73 74 72 75 63 74  ernel. */.struct
0590: 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20   appfs_pathinfo 
05a0: 7b 0a 09 61 70 70 66 73 5f 70 61 74 68 74 79 70  {..appfs_pathtyp
05b0: 65 5f 74 20 74 79 70 65 3b 0a 09 74 69 6d 65 5f  e_t type;..time_
05c0: 74 20 74 69 6d 65 3b 0a 09 63 68 61 72 20 68 6f  t time;..char ho
05d0: 73 74 6e 61 6d 65 5b 32 35 36 5d 3b 0a 09 69 6e  stname[256];..in
05e0: 74 20 70 61 63 6b 61 67 65 64 3b 0a 09 75 6e 73  t packaged;..uns
05f0: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 20  igned long long 
0600: 69 6e 6f 64 65 3b 0a 09 75 6e 69 6f 6e 20 7b 0a  inode;..union {.
0610: 09 09 73 74 72 75 63 74 20 7b 0a 09 09 09 69 6e  ..struct {....in
0620: 74 20 63 68 69 6c 64 63 6f 75 6e 74 3b 0a 09 09  t childcount;...
0630: 7d 20 64 69 72 3b 0a 09 09 73 74 72 75 63 74 20  } dir;...struct 
0640: 7b 0a 09 09 09 69 6e 74 20 65 78 65 63 75 74 61  {....int executa
0650: 62 6c 65 3b 0a 09 09 09 6f 66 66 5f 74 20 73 69  ble;....off_t si
0660: 7a 65 3b 0a 09 09 7d 20 66 69 6c 65 3b 0a 09 09  ze;...} file;...
0670: 73 74 72 75 63 74 20 7b 0a 09 09 09 6f 66 66 5f  struct {....off_
0680: 74 20 73 69 7a 65 3b 0a 09 09 09 63 68 61 72 20  t size;....char 
0690: 73 6f 75 72 63 65 5b 32 35 36 5d 3b 0a 09 09 7d  source[256];...}
06a0: 20 73 79 6d 6c 69 6e 6b 3b 0a 09 7d 20 74 79 70   symlink;..} typ
06b0: 65 69 6e 66 6f 3b 0a 7d 3b 0a 0a 2f 2a 0a 20 2a  einfo;.};../*. *
06c0: 20 43 72 65 61 74 65 20 61 20 6e 65 77 20 54 63   Create a new Tc
06d0: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 20 61 6e  l interpreter an
06e0: 64 20 63 6f 6d 70 6c 65 74 65 6c 79 20 69 6e 69  d completely ini
06f0: 74 69 61 6c 69 7a 65 20 69 74 0a 20 2a 2f 0a 73  tialize it. */.s
0700: 74 61 74 69 63 20 54 63 6c 5f 49 6e 74 65 72 70  tatic Tcl_Interp
0710: 20 2a 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54   *appfs_create_T
0720: 63 6c 49 6e 74 65 72 70 28 76 6f 69 64 29 20 7b  clInterp(void) {
0730: 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e  ..Tcl_Interp *in
0740: 74 65 72 70 3b 0a 09 69 6e 74 20 74 63 6c 5f 72  terp;..int tcl_r
0750: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55  et;...APPFS_DEBU
0760: 47 28 22 43 72 65 61 74 69 6e 67 20 6e 65 77 20  G("Creating new 
0770: 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 20  Tcl interpreter 
0780: 66 6f 72 20 54 49 44 20 3d 20 30 78 25 6c 6c 78  for TID = 0x%llx
0790: 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e  ", (unsigned lon
07a0: 67 20 6c 6f 6e 67 29 20 70 74 68 72 65 61 64 5f  g long) pthread_
07b0: 73 65 6c 66 28 29 29 3b 0a 0a 09 69 6e 74 65 72  self());...inter
07c0: 70 20 3d 20 54 63 6c 5f 43 72 65 61 74 65 49 6e  p = Tcl_CreateIn
07d0: 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74  terp();..if (int
07e0: 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  erp == NULL) {..
07f0: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
0800: 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61   "Unable to crea
0810: 74 65 20 54 63 6c 20 49 6e 74 65 72 70 72 65 74  te Tcl Interpret
0820: 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e  er.  Aborting.\n
0830: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  ");....return(NU
0840: 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65  LL);..}...tcl_re
0850: 74 20 3d 20 54 63 6c 5f 49 6e 69 74 28 69 6e 74  t = Tcl_Init(int
0860: 65 72 70 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72  erp);..if (tcl_r
0870: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a  et != TCL_OK) {.
0880: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
0890: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69  , "Unable to ini
08a0: 74 69 61 6c 69 7a 65 20 54 63 6c 2e 20 20 41 62  tialize Tcl.  Ab
08b0: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66  orting.\n");...f
08c0: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
08d0: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
08e0: 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69  \n", Tcl_GetStri
08f0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29  ngResult(interp)
0900: 29 3b 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65  );....Tcl_Delete
0910: 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a  Interp(interp);.
0920: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
0930: 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20  ..}...tcl_ret = 
0940: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c  Tcl_Eval(interp,
0950: 20 22 70 61 63 6b 61 67 65 20 69 66 6e 65 65 64   "package ifneed
0960: 65 64 20 73 68 61 31 20 31 2e 30 20 5b 6c 69 73  ed sha1 1.0 [lis
0970: 74 20 6c 6f 61 64 20 7b 7d 20 73 68 61 31 5d 22  t load {} sha1]"
0980: 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  );..if (tcl_ret 
0990: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66  != TCL_OK) {...f
09a0: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22  printf(stderr, "
09b0: 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61  Unable to initia
09c0: 6c 69 7a 65 20 54 63 6c 20 53 48 41 31 2e 20 20  lize Tcl SHA1.  
09d0: 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09  Aborting.\n");..
09e0: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
09f0: 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20   "Tcl Error is: 
0a00: 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74  %s\n", Tcl_GetSt
0a10: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72  ringResult(inter
0a20: 70 29 29 3b 0a 0a 09 09 54 63 6c 5f 44 65 6c 65  p));....Tcl_Dele
0a30: 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29  teInterp(interp)
0a40: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c  ;....return(NULL
0a50: 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20  );..}...tcl_ret 
0a60: 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  = Tcl_Eval(inter
0a70: 70 2c 20 22 70 61 63 6b 61 67 65 20 69 66 6e 65  p, "package ifne
0a80: 65 64 65 64 20 61 70 70 66 73 64 20 31 2e 30 20  eded appfsd 1.0 
0a90: 5b 6c 69 73 74 20 6c 6f 61 64 20 7b 7d 20 61 70  [list load {} ap
0aa0: 70 66 73 64 5d 22 29 3b 0a 09 69 66 20 28 74 63  pfsd]");..if (tc
0ab0: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29  l_ret != TCL_OK)
0ac0: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64   {...fprintf(std
0ad0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20  err, "Unable to 
0ae0: 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 41  initialize Tcl A
0af0: 70 70 46 53 20 50 61 63 6b 61 67 65 2e 20 20 41  ppFS Package.  A
0b00: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09  borting.\n");...
0b10: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20  fprintf(stderr, 
0b20: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25  "Tcl Error is: %
0b30: 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72  s\n", Tcl_GetStr
0b40: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ingResult(interp
0b50: 29 29 3b 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74  ));....Tcl_Delet
0b60: 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b  eInterp(interp);
0b70: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
0b80: 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4c 6f  ;..}.../*.. * Lo
0b90: 61 64 20 74 68 65 20 22 61 70 70 66 73 64 2e 74  ad the "appfsd.t
0ba0: 63 6c 22 20 73 63 72 69 70 74 2c 20 77 68 69 63  cl" script, whic
0bb0: 68 20 69 73 20 22 63 6f 6d 70 69 6c 65 64 22 20  h is "compiled" 
0bc0: 69 6e 74 6f 20 61 20 43 20 68 65 61 64 65 72 0a  into a C header.
0bd0: 09 20 2a 20 73 6f 20 74 68 61 74 20 69 74 20 64  . * so that it d
0be0: 6f 65 73 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20  oes not need to 
0bf0: 65 78 69 73 74 20 6f 6e 20 74 68 65 20 66 69 6c  exist on the fil
0c00: 65 73 79 73 74 65 6d 20 61 6e 64 20 63 61 6e 20  esystem and can 
0c10: 62 65 0a 09 20 2a 20 64 69 72 65 63 74 6c 79 20  be.. * directly 
0c20: 65 76 61 6c 75 61 74 65 64 2e 0a 09 20 2a 2f 0a  evaluated... */.
0c30: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45  .tcl_ret = Tcl_E
0c40: 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 22 0a 23  val(interp, "".#
0c50: 69 6e 63 6c 75 64 65 20 22 61 70 70 66 73 64 2e  include "appfsd.
0c60: 74 63 6c 2e 68 22 0a 09 22 22 29 3b 0a 09 69 66  tcl.h".."");..if
0c70: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c   (tcl_ret != TCL
0c80: 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66  _OK) {...fprintf
0c90: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65  (stderr, "Unable
0ca0: 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54   to initialize T
0cb0: 63 6c 20 41 70 70 46 53 20 73 63 72 69 70 74 2e  cl AppFS script.
0cc0: 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b    Aborting.\n");
0cd0: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72  ...fprintf(stder
0ce0: 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73  r, "Tcl Error is
0cf0: 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74  : %s\n", Tcl_Get
0d00: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74  StringResult(int
0d10: 65 72 70 29 29 3b 0a 0a 09 09 54 63 6c 5f 44 65  erp));....Tcl_De
0d20: 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72  leteInterp(inter
0d30: 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  p);....return(NU
0d40: 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a  LL);..}.../*.. *
0d50: 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69   Set global vari
0d60: 61 62 6c 65 73 20 66 72 6f 6d 20 43 20 74 6f 20  ables from C to 
0d70: 54 63 6c 0a 09 20 2a 2f 0a 09 69 66 20 28 54 63  Tcl.. */..if (Tc
0d80: 6c 5f 53 65 74 56 61 72 28 69 6e 74 65 72 70 2c  l_SetVar(interp,
0d90: 20 22 3a 3a 61 70 70 66 73 3a 3a 63 61 63 68 65   "::appfs::cache
0da0: 64 69 72 22 2c 20 61 70 70 66 73 5f 63 61 63 68  dir", appfs_cach
0db0: 65 64 69 72 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c  edir, TCL_GLOBAL
0dc0: 5f 4f 4e 4c 59 29 20 3d 3d 20 4e 55 4c 4c 29 20  _ONLY) == NULL) 
0dd0: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65  {...fprintf(stde
0de0: 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 73  rr, "Unable to s
0df0: 65 74 20 63 61 63 68 65 20 64 69 72 65 63 74 6f  et cache directo
0e00: 72 79 2e 20 20 54 68 69 73 20 73 68 6f 75 6c 64  ry.  This should
0e10: 20 6e 65 76 65 72 20 66 61 69 6c 2e 5c 6e 22 29   never fail.\n")
0e20: 3b 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49  ;....Tcl_DeleteI
0e30: 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a  nterp(interp);..
0e40: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
0e50: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 49 6e 69 74  .}.../*.. * Init
0e60: 69 61 6c 69 7a 65 20 74 68 65 20 22 61 70 70 66  ialize the "appf
0e70: 73 64 2e 74 63 6c 22 20 65 6e 76 69 72 6f 6e 6d  sd.tcl" environm
0e80: 65 6e 74 2c 20 77 68 69 63 68 20 6d 75 73 74 20  ent, which must 
0e90: 62 65 20 64 6f 6e 65 20 61 66 74 65 72 0a 09 20  be done after.. 
0ea0: 2a 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c  * global variabl
0eb0: 65 73 20 61 72 65 20 73 65 74 2e 0a 09 20 2a 2f  es are set... */
0ec0: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
0ed0: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 3a 3a  Eval(interp, "::
0ee0: 61 70 70 66 73 3a 3a 69 6e 69 74 22 29 3b 0a 09  appfs::init");..
0ef0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
0f00: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e  CL_OK) {...fprin
0f10: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62  tf(stderr, "Unab
0f20: 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65  le to initialize
0f30: 20 54 63 6c 20 41 70 70 46 53 20 73 63 72 69 70   Tcl AppFS scrip
0f40: 74 20 28 3a 3a 61 70 70 66 73 3a 3a 69 6e 69 74  t (::appfs::init
0f50: 29 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22  ).  Aborting.\n"
0f60: 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64  );...fprintf(std
0f70: 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20  err, "Tcl Error 
0f80: 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47  is: %s\n", Tcl_G
0f90: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69  etStringResult(i
0fa0: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 54 63 6c 5f  nterp));....Tcl_
0fb0: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74  DeleteInterp(int
0fc0: 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  erp);....return(
0fd0: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09  NULL);..}.../*..
0fe0: 20 2a 20 48 69 64 65 20 73 6f 6d 65 20 54 63 6c   * Hide some Tcl
0ff0: 20 63 6f 6d 6d 61 6e 64 73 20 74 68 61 74 20 77   commands that w
1000: 65 20 64 6f 20 6e 6f 74 20 63 61 72 65 20 74 6f  e do not care to
1010: 20 75 73 65 20 61 6e 64 20 77 68 69 63 68 20 6d   use and which m
1020: 61 79 0a 09 20 2a 20 73 6c 6f 77 20 64 6f 77 6e  ay.. * slow down
1030: 20 72 75 6e 2d 74 69 6d 65 20 6f 70 65 72 61 74   run-time operat
1040: 69 6f 6e 73 2e 0a 09 20 2a 2f 0a 09 54 63 6c 5f  ions... */..Tcl_
1050: 48 69 64 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  HideCommand(inte
1060: 72 70 2c 20 22 61 75 74 6f 5f 6c 6f 61 64 5f 69  rp, "auto_load_i
1070: 6e 64 65 78 22 2c 20 22 61 75 74 6f 5f 6c 6f 61  ndex", "auto_loa
1080: 64 5f 69 6e 64 65 78 22 29 3b 0a 09 54 63 6c 5f  d_index");..Tcl_
1090: 48 69 64 65 43 6f 6d 6d 61 6e 64 28 69 6e 74 65  HideCommand(inte
10a0: 72 70 2c 20 22 75 6e 6b 6e 6f 77 6e 22 2c 20 22  rp, "unknown", "
10b0: 75 6e 6b 6e 6f 77 6e 22 29 3b 0a 0a 09 2f 2a 0a  unknown");.../*.
10c0: 09 20 2a 20 52 65 74 75 72 6e 20 74 68 65 20 63  . * Return the c
10d0: 6f 6d 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61  ompletely initia
10e0: 6c 69 7a 65 64 20 69 6e 74 65 72 70 72 65 74 65  lized interprete
10f0: 72 0a 09 20 2a 2f 0a 09 72 65 74 75 72 6e 28 69  r.. */..return(i
1100: 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a  nterp);.}../*. *
1110: 20 52 65 74 75 72 6e 20 74 68 65 20 74 68 72 65   Return the thre
1120: 61 64 2d 73 70 65 63 69 66 69 63 20 54 63 6c 20  ad-specific Tcl 
1130: 69 6e 74 65 72 70 72 65 74 65 72 2c 20 63 72 65  interpreter, cre
1140: 61 74 69 6e 67 20 69 74 20 69 66 20 6e 65 65 64  ating it if need
1150: 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 54 63  ed. */.static Tc
1160: 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70 66 73 5f  l_Interp *appfs_
1170: 54 63 6c 49 6e 74 65 72 70 28 76 6f 69 64 29 20  TclInterp(void) 
1180: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  {..Tcl_Interp *i
1190: 6e 74 65 72 70 3b 0a 09 69 6e 74 20 70 74 68 72  nterp;..int pthr
11a0: 65 61 64 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72  ead_ret;...inter
11b0: 70 20 3d 20 70 74 68 72 65 61 64 5f 67 65 74 73  p = pthread_gets
11c0: 70 65 63 69 66 69 63 28 69 6e 74 65 72 70 4b 65  pecific(interpKe
11d0: 79 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  y);..if (interp 
11e0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 6e 74  == NULL) {...int
11f0: 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61  erp = appfs_crea
1200: 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a  te_TclInterp();.
1210: 0a 09 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d  ...if (interp ==
1220: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74 75   NULL) {....retu
1230: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a 0a 09  rn(NULL);...}...
1240: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70  .pthread_ret = p
1250: 74 68 72 65 61 64 5f 73 65 74 73 70 65 63 69 66  thread_setspecif
1260: 69 63 28 69 6e 74 65 72 70 4b 65 79 2c 20 69 6e  ic(interpKey, in
1270: 74 65 72 70 29 3b 0a 09 09 69 66 20 28 70 74 68  terp);...if (pth
1280: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  read_ret != 0) {
1290: 0a 09 09 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e  ....Tcl_DeleteIn
12a0: 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09  terp(interp);...
12b0: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
12c0: 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  ..}..}...return(
12d0: 69 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20  interp);.}../*. 
12e0: 2a 20 45 76 61 6c 75 61 74 65 20 61 20 54 63 6c  * Evaluate a Tcl
12f0: 20 73 63 72 69 70 74 20 63 6f 6e 73 74 72 75 63   script construc
1300: 74 65 64 20 62 79 20 63 6f 6e 63 61 74 65 6e 61  ted by concatena
1310: 74 69 6e 67 20 61 20 62 75 6e 63 68 20 6f 66 20  ting a bunch of 
1320: 43 20 73 74 72 69 6e 67 73 0a 20 2a 20 74 6f 67  C strings. * tog
1330: 65 74 68 65 72 2e 0a 20 2a 2f 0a 73 74 61 74 69  ether.. */.stati
1340: 63 20 69 6e 74 20 61 70 70 66 73 5f 54 63 6c 5f  c int appfs_Tcl_
1350: 45 76 61 6c 28 54 63 6c 5f 49 6e 74 65 72 70 20  Eval(Tcl_Interp 
1360: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a  *interp, int obj
1370: 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63  c, const char *c
1380: 6d 64 2c 20 2e 2e 2e 29 20 7b 0a 09 54 63 6c 5f  md, ...) {..Tcl_
1390: 4f 62 6a 20 2a 2a 6f 62 6a 76 3b 0a 09 63 6f 6e  Obj **objv;..con
13a0: 73 74 20 63 68 61 72 20 2a 61 72 67 3b 0a 09 76  st char *arg;..v
13b0: 61 5f 6c 69 73 74 20 61 72 67 70 3b 0a 09 69 6e  a_list argp;..in
13c0: 74 20 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20 69  t retval;..int i
13d0: 3b 0a 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d  ;...if (interp =
13e0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
13f0: 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09  rn(TCL_ERROR);..
1400: 7d 0a 0a 09 6f 62 6a 76 20 3d 20 28 76 6f 69 64  }...objv = (void
1410: 20 2a 29 20 63 6b 61 6c 6c 6f 63 28 73 69 7a 65   *) ckalloc(size
1420: 6f 66 28 2a 6f 62 6a 76 29 20 2a 20 6f 62 6a 63  of(*objv) * objc
1430: 29 3b 0a 09 6f 62 6a 76 5b 30 5d 20 3d 20 54 63  );..objv[0] = Tc
1440: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 63  l_NewStringObj(c
1450: 6d 64 2c 20 2d 31 29 3b 0a 09 54 63 6c 5f 49 6e  md, -1);..Tcl_In
1460: 63 72 52 65 66 43 6f 75 6e 74 28 6f 62 6a 76 5b  crRefCount(objv[
1470: 30 5d 29 3b 0a 0a 09 76 61 5f 73 74 61 72 74 28  0]);...va_start(
1480: 61 72 67 70 2c 20 63 6d 64 29 3b 0a 09 66 6f 72  argp, cmd);..for
1490: 20 28 69 20 3d 20 31 3b 20 69 20 3c 20 6f 62 6a   (i = 1; i < obj
14a0: 63 3b 20 69 2b 2b 29 20 7b 0a 09 09 61 72 67 20  c; i++) {...arg 
14b0: 3d 20 76 61 5f 61 72 67 28 61 72 67 70 2c 20 63  = va_arg(argp, c
14c0: 6f 6e 73 74 20 63 68 61 72 20 2a 29 3b 0a 09 09  onst char *);...
14d0: 6f 62 6a 76 5b 69 5d 20 3d 20 54 63 6c 5f 4e 65  objv[i] = Tcl_Ne
14e0: 77 53 74 72 69 6e 67 4f 62 6a 28 61 72 67 2c 20  wStringObj(arg, 
14f0: 2d 31 29 3b 0a 09 09 54 63 6c 5f 49 6e 63 72 52  -1);...Tcl_IncrR
1500: 65 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29  efCount(objv[i])
1510: 3b 0a 09 7d 0a 09 76 61 5f 65 6e 64 28 61 72 67  ;..}..va_end(arg
1520: 70 29 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 54  p);...retval = T
1530: 63 6c 5f 45 76 61 6c 4f 62 6a 76 28 69 6e 74 65  cl_EvalObjv(inte
1540: 72 70 2c 20 6f 62 6a 63 2c 20 6f 62 6a 76 2c 20  rp, objc, objv, 
1550: 30 29 3b 0a 0a 09 66 6f 72 20 28 69 20 3d 20 30  0);...for (i = 0
1560: 3b 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29  ; i < objc; i++)
1570: 20 7b 0a 09 09 54 63 6c 5f 44 65 63 72 52 65 66   {...Tcl_DecrRef
1580: 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a  Count(objv[i]);.
1590: 09 7d 0a 0a 09 63 6b 66 72 65 65 28 28 76 6f 69  .}...ckfree((voi
15a0: 64 20 2a 29 20 6f 62 6a 76 29 3b 0a 0a 09 69 66  d *) objv);...if
15b0: 20 28 72 65 74 76 61 6c 20 21 3d 20 54 43 4c 5f   (retval != TCL_
15c0: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45  OK) {...APPFS_DE
15d0: 42 55 47 28 22 54 63 6c 20 63 6f 6d 6d 61 6e 64  BUG("Tcl command
15e0: 20 66 61 69 6c 65 64 2c 20 3a 3a 65 72 72 6f 72   failed, ::error
15f0: 49 6e 66 6f 20 63 6f 6e 74 61 69 6e 73 3a 20 25  Info contains: %
1600: 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 56 61 72  s\n", Tcl_GetVar
1610: 28 69 6e 74 65 72 70 2c 20 22 3a 3a 65 72 72 6f  (interp, "::erro
1620: 72 49 6e 66 6f 22 2c 20 30 29 29 3b 0a 09 7d 0a  rInfo", 0));..}.
1630: 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29  ..return(retval)
1640: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 44 65 74 65 72  ;.}../*. * Deter
1650: 6d 69 6e 65 20 74 68 65 20 55 49 44 20 66 6f 72  mine the UID for
1660: 20 74 68 65 20 75 73 65 72 20 6d 61 6b 69 6e 67   the user making
1670: 20 74 68 65 20 63 75 72 72 65 6e 74 20 46 55 53   the current FUS
1680: 45 20 66 69 6c 65 73 79 73 74 65 6d 20 72 65 71  E filesystem req
1690: 75 65 73 74 2e 0a 20 2a 20 54 68 69 73 20 77 69  uest.. * This wi
16a0: 6c 6c 20 62 65 20 75 73 65 64 20 74 6f 20 6c 6f  ll be used to lo
16b0: 6f 6b 75 70 20 74 68 65 20 75 73 65 72 27 73 20  okup the user's 
16c0: 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20 73  home directory s
16d0: 6f 20 77 65 20 63 61 6e 20 73 65 61 72 63 68 20  o we can search 
16e0: 66 6f 72 0a 20 2a 20 6c 6f 63 61 6c 6c 79 20 6d  for. * locally m
16f0: 6f 64 69 66 69 65 64 20 66 69 6c 65 73 2e 0a 20  odified files.. 
1700: 2a 2f 0a 73 74 61 74 69 63 20 75 69 64 5f 74 20  */.static uid_t 
1710: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28  appfs_get_fsuid(
1720: 76 6f 69 64 29 20 7b 0a 09 73 74 72 75 63 74 20  void) {..struct 
1730: 66 75 73 65 5f 63 6f 6e 74 65 78 74 20 2a 63 74  fuse_context *ct
1740: 78 3b 0a 0a 09 63 74 78 20 3d 20 66 75 73 65 5f  x;...ctx = fuse_
1750: 67 65 74 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09  get_context();..
1760: 69 66 20 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29  if (ctx == NULL)
1770: 20 7b 0a 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74   {.../* Unable t
1780: 6f 20 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f  o lookup user fo
1790: 72 20 73 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f  r some reason */
17a0: 0a 09 09 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20  .../* Return an 
17b0: 75 6e 70 72 69 76 69 6c 65 67 65 64 20 75 73 65  unprivileged use
17c0: 72 20 49 44 20 2a 2f 0a 09 09 72 65 74 75 72 6e  r ID */...return
17d0: 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e  (1);..}...return
17e0: 28 63 74 78 2d 3e 75 69 64 29 3b 0a 7d 0a 0a 2f  (ctx->uid);.}../
17f0: 2a 0a 20 2a 20 4c 6f 6f 6b 20 75 70 20 74 68 65  *. * Look up the
1800: 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20   home directory 
1810: 66 6f 72 20 61 20 67 69 76 65 6e 20 55 49 44 0a  for a given UID.
1820: 20 2a 20 20 20 20 20 20 20 20 52 65 74 75 72 6e   *        Return
1830: 73 20 61 20 43 20 73 74 72 69 6e 67 20 63 6f 6e  s a C string con
1840: 74 61 69 6e 69 6e 67 20 74 68 65 20 75 73 65 72  taining the user
1850: 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72  's home director
1860: 79 20 6f 72 20 4e 55 4c 4c 20 69 66 0a 20 2a 20  y or NULL if. * 
1870: 20 20 20 20 20 20 20 74 68 65 20 75 73 65 72 27         the user'
1880: 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79  s home directory
1890: 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20   does not exist 
18a0: 6f 72 20 69 73 20 6e 6f 74 20 63 6f 72 72 65 63  or is not correc
18b0: 74 6c 79 0a 20 2a 20 20 20 20 20 20 20 20 63 6f  tly. *        co
18c0: 6e 66 69 67 75 72 65 64 0a 20 2a 2f 0a 73 74 61  nfigured. */.sta
18d0: 74 69 63 20 63 68 61 72 20 2a 61 70 70 66 73 5f  tic char *appfs_
18e0: 67 65 74 5f 68 6f 6d 65 64 69 72 28 75 69 64 5f  get_homedir(uid_
18f0: 74 20 66 73 75 69 64 29 20 7b 0a 09 73 74 72 75  t fsuid) {..stru
1900: 63 74 20 70 61 73 73 77 64 20 65 6e 74 72 79 2c  ct passwd entry,
1910: 20 2a 72 65 73 75 6c 74 3b 0a 09 73 74 72 75 63   *result;..struc
1920: 74 20 73 74 61 74 20 73 74 62 75 66 3b 0a 09 63  t stat stbuf;..c
1930: 68 61 72 20 62 75 66 5b 31 30 32 34 5d 2c 20 2a  har buf[1024], *
1940: 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20 67 70 75  retval;..int gpu
1950: 5f 72 65 74 2c 20 73 74 61 74 5f 72 65 74 3b 0a  _ret, stat_ret;.
1960: 0a 09 67 70 75 5f 72 65 74 20 3d 20 67 65 74 70  ..gpu_ret = getp
1970: 77 75 69 64 5f 72 28 66 73 75 69 64 2c 20 26 65  wuid_r(fsuid, &e
1980: 6e 74 72 79 2c 20 62 75 66 2c 20 73 69 7a 65 6f  ntry, buf, sizeo
1990: 66 28 62 75 66 29 2c 20 26 72 65 73 75 6c 74 29  f(buf), &result)
19a0: 3b 0a 09 69 66 20 28 67 70 75 5f 72 65 74 20 21  ;..if (gpu_ret !
19b0: 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44  = 0) {...APPFS_D
19c0: 45 42 55 47 28 22 67 65 74 70 77 75 69 64 5f 72  EBUG("getpwuid_r
19d0: 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 74 75  (%llu, ...) retu
19e0: 72 6e 65 64 20 69 6e 20 66 61 69 6c 75 72 65 22  rned in failure"
19f0: 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67  , (unsigned long
1a00: 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b 0a 0a   long) fsuid);..
1a10: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
1a20: 09 7d 0a 0a 09 69 66 20 28 72 65 73 75 6c 74 20  .}...if (result 
1a30: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50  == NULL) {...APP
1a40: 46 53 5f 44 45 42 55 47 28 22 67 65 74 70 77 75  FS_DEBUG("getpwu
1a50: 69 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20  id_r(%llu, ...) 
1a60: 72 65 74 75 72 6e 65 64 20 4e 55 4c 4c 20 72 65  returned NULL re
1a70: 73 75 6c 74 22 2c 20 28 75 6e 73 69 67 6e 65 64  sult", (unsigned
1a80: 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69   long long) fsui
1a90: 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55  d);....return(NU
1aa0: 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65  LL);..}...if (re
1ab0: 73 75 6c 74 2d 3e 70 77 5f 64 69 72 20 3d 3d 20  sult->pw_dir == 
1ac0: 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f  NULL) {...APPFS_
1ad0: 44 45 42 55 47 28 22 67 65 74 70 77 75 69 64 5f  DEBUG("getpwuid_
1ae0: 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 74  r(%llu, ...) ret
1af0: 75 72 6e 65 64 20 4e 55 4c 4c 20 68 6f 6d 65 20  urned NULL home 
1b00: 64 69 72 65 63 74 6f 72 79 22 2c 20 28 75 6e 73  directory", (uns
1b10: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29  igned long long)
1b20: 20 66 73 75 69 64 29 3b 0a 0a 09 09 72 65 74 75   fsuid);....retu
1b30: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 73  rn(NULL);..}...s
1b40: 74 61 74 5f 72 65 74 20 3d 20 73 74 61 74 28 72  tat_ret = stat(r
1b50: 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 2c 20 26  esult->pw_dir, &
1b60: 73 74 62 75 66 29 3b 0a 09 69 66 20 28 73 74 61  stbuf);..if (sta
1b70: 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  t_ret != 0) {...
1b80: 41 50 50 46 53 5f 44 45 42 55 47 28 22 73 74 61  APPFS_DEBUG("sta
1b90: 74 28 25 73 29 20 72 65 74 75 72 6e 65 64 20 69  t(%s) returned i
1ba0: 6e 20 66 61 69 6c 75 72 65 22 2c 20 72 65 73 75  n failure", resu
1bb0: 6c 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09 09  lt->pw_dir);....
1bc0: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
1bd0: 0a 0a 09 69 66 20 28 73 74 62 75 66 2e 73 74 5f  ...if (stbuf.st_
1be0: 75 69 64 20 21 3d 20 66 73 75 69 64 29 20 7b 0a  uid != fsuid) {.
1bf0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55  ..APPFS_DEBUG("U
1c00: 49 44 20 6d 69 73 2d 6d 61 74 63 68 20 6f 6e 20  ID mis-match on 
1c10: 75 73 65 72 20 25 6c 6c 75 27 73 20 68 6f 6d 65  user %llu's home
1c20: 20 64 69 72 65 63 74 6f 72 79 20 28 25 73 29 2e   directory (%s).
1c30: 20 20 49 74 27 73 20 6f 77 6e 65 64 20 62 79 20    It's owned by 
1c40: 25 6c 6c 75 2e 22 2c 0a 09 09 20 20 20 20 28 75  %llu.",...    (u
1c50: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e  nsigned long lon
1c60: 67 29 20 66 73 75 69 64 2c 0a 09 09 20 20 20 20  g) fsuid,...    
1c70: 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 2c 0a  result->pw_dir,.
1c80: 09 09 20 20 20 20 28 75 6e 73 69 67 6e 65 64 20  ..    (unsigned 
1c90: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 74 62 75 66  long long) stbuf
1ca0: 2e 73 74 5f 75 69 64 0a 09 09 29 3b 0a 0a 09 09  .st_uid...);....
1cb0: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
1cc0: 0a 0a 09 72 65 74 76 61 6c 20 3d 20 73 74 72 64  ...retval = strd
1cd0: 75 70 28 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69  up(result->pw_di
1ce0: 72 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65 74  r);...return(ret
1cf0: 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54  val);.}../*. * T
1d00: 63 6c 20 69 6e 74 65 72 66 61 63 65 20 74 6f 20  cl interface to 
1d10: 67 65 74 20 74 68 65 20 68 6f 6d 65 20 64 69 72  get the home dir
1d20: 65 63 74 6f 72 79 20 66 6f 72 20 74 68 65 20 75  ectory for the u
1d30: 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 22  ser making the "
1d40: 63 75 72 72 65 6e 74 22 0a 20 2a 20 46 55 53 45  current". * FUSE
1d50: 20 49 2f 4f 20 72 65 71 75 65 73 74 0a 20 2a 2f   I/O request. */
1d60: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c 5f  .static int tcl_
1d70: 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69  appfs_get_homedi
1d80: 72 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c  r(ClientData cd,
1d90: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
1da0: 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54  erp, int objc, T
1db0: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
1dc0: 6a 76 5b 5d 29 20 7b 0a 09 63 68 61 72 20 2a 68  jv[]) {..char *h
1dd0: 6f 6d 65 64 69 72 3b 0a 0a 20 20 20 20 20 20 20  omedir;..       
1de0: 20 69 66 20 28 6f 62 6a 63 20 21 3d 20 31 29 20   if (objc != 1) 
1df0: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  {.              
1e00: 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72    Tcl_WrongNumAr
1e10: 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62  gs(interp, 1, ob
1e20: 6a 76 2c 20 4e 55 4c 4c 29 3b 0a 20 20 20 20 20  jv, NULL);.     
1e30: 20 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72             retur
1e40: 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 20 20  n(TCL_ERROR);.  
1e50: 20 20 20 20 20 20 7d 0a 0a 09 68 6f 6d 65 64 69        }...homedi
1e60: 72 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 68 6f  r = appfs_get_ho
1e70: 6d 65 64 69 72 28 61 70 70 66 73 5f 67 65 74 5f  medir(appfs_get_
1e80: 66 73 75 69 64 28 29 29 3b 0a 0a 09 69 66 20 28  fsuid());...if (
1e90: 68 6f 6d 65 64 69 72 20 3d 3d 20 4e 55 4c 4c 29  homedir == NULL)
1ea0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 54 43 4c 5f   {...return(TCL_
1eb0: 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 20 20 20 20  ERROR);..}..    
1ec0: 20 20 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65      Tcl_SetObjRe
1ed0: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c  sult(interp, Tcl
1ee0: 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 68 6f  _NewStringObj(ho
1ef0: 6d 65 64 69 72 2c 20 2d 31 29 29 3b 0a 0a 09 66  medir, -1));...f
1f00: 72 65 65 28 68 6f 6d 65 64 69 72 29 3b 0a 0a 20  ree(homedir);.. 
1f10: 20 20 20 20 20 20 20 72 65 74 75 72 6e 28 54 43         return(TC
1f20: 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20  L_OK);.}../*. * 
1f30: 47 65 6e 65 72 61 74 65 20 61 6e 20 69 6e 6f 64  Generate an inod
1f40: 65 20 66 6f 72 20 61 20 67 69 76 65 6e 20 70 61  e for a given pa
1f50: 74 68 2e 20 20 54 68 65 20 69 6e 6f 64 65 20 73  th.  The inode s
1f60: 68 6f 75 6c 64 20 62 65 20 63 6f 6d 70 75 74 65  hould be compute
1f70: 64 20 69 6e 20 73 75 63 68 0a 20 2a 20 61 20 77  d in such. * a w
1f80: 61 79 20 74 68 61 74 20 69 74 20 69 73 20 75 6e  ay that it is un
1f90: 6c 69 6b 65 6c 79 20 74 6f 20 62 65 20 64 75 70  likely to be dup
1fa0: 6c 69 63 61 74 65 64 20 61 6e 64 20 72 65 6d 61  licated and rema
1fb0: 69 6e 73 20 74 68 65 20 73 61 6d 65 20 66 6f 72  ins the same for
1fc0: 20 61 20 67 69 76 65 6e 0a 20 2a 20 66 69 6c 65   a given. * file
1fd0: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 6c 6f 6e 67  . */.static long
1fe0: 20 6c 6f 6e 67 20 61 70 70 66 73 5f 67 65 74 5f   long appfs_get_
1ff0: 70 61 74 68 5f 69 6e 6f 64 65 28 63 6f 6e 73 74  path_inode(const
2000: 20 63 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09   char *path) {..
2010: 6c 6f 6e 67 20 6c 6f 6e 67 20 72 65 74 76 61 6c  long long retval
2020: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 70  ;..const char *p
2030: 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 31 30 3b  ;...retval = 10;
2040: 0a 0a 09 66 6f 72 20 28 70 20 3d 20 70 61 74 68  ...for (p = path
2050: 3b 20 2a 70 3b 20 70 2b 2b 29 20 7b 0a 09 09 72  ; *p; p++) {...r
2060: 65 74 76 61 6c 20 25 3d 20 34 32 39 30 39 36 30  etval %= 4290960
2070: 32 39 30 55 4c 4c 3b 0a 09 09 72 65 74 76 61 6c  290ULL;...retval
2080: 20 2b 3d 20 2a 70 3b 0a 09 09 72 65 74 76 61 6c   += *p;...retval
2090: 20 3c 3c 3d 20 37 3b 0a 09 7d 0a 0a 09 72 65 74   <<= 7;..}...ret
20a0: 76 61 6c 20 2b 3d 20 31 30 3b 0a 09 72 65 74 76  val += 10;..retv
20b0: 61 6c 20 25 3d 20 34 32 39 34 39 36 37 32 39 36  al %= 4294967296
20c0: 55 4c 4c 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65  ULL;...return(re
20d0: 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 20 47 65 74  tval);.}../* Get
20e0: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f   information abo
20f0: 75 74 20 61 20 70 61 74 68 2c 20 61 6e 64 20 6f  ut a path, and o
2100: 70 74 69 6f 6e 61 6c 6c 79 20 6c 69 73 74 20 63  ptionally list c
2110: 68 69 6c 64 72 65 6e 20 2a 2f 0a 73 74 61 74 69  hildren */.stati
2120: 63 20 69 6e 74 20 61 70 70 66 73 5f 67 65 74 5f  c int appfs_get_
2130: 70 61 74 68 5f 69 6e 66 6f 28 63 6f 6e 73 74 20  path_info(const 
2140: 63 68 61 72 20 2a 5f 70 61 74 68 2c 20 73 74 72  char *_path, str
2150: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e  uct appfs_pathin
2160: 66 6f 20 2a 70 61 74 68 69 6e 66 6f 2c 20 73 74  fo *pathinfo, st
2170: 72 75 63 74 20 61 70 70 66 73 5f 63 68 69 6c 64  ruct appfs_child
2180: 72 65 6e 20 2a 2a 63 68 69 6c 64 72 65 6e 29 20  ren **children) 
2190: 7b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20  {.}..static int 
21a0: 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 6c  appfs_fuse_readl
21b0: 69 6e 6b 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ink(const char *
21c0: 70 61 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c  path, char *buf,
21d0: 20 73 69 7a 65 5f 74 20 73 69 7a 65 29 20 7b 0a   size_t size) {.
21e0: 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61  .struct appfs_pa
21f0: 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b  thinfo pathinfo;
2200: 0a 09 69 6e 74 20 72 65 73 20 3d 20 30 3b 0a 0a  ..int res = 0;..
2210: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e  .APPFS_DEBUG("En
2220: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20  ter (path = %s, 
2230: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09  ...)", path);...
2240: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20  pathinfo.type = 
2250: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49  APPFS_PATHTYPE_I
2260: 4e 56 41 4c 49 44 3b 0a 0a 09 72 65 73 20 3d 20  NVALID;...res = 
2270: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69  appfs_get_path_i
2280: 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69  nfo(path, &pathi
2290: 6e 66 6f 2c 20 4e 55 4c 4c 29 3b 0a 09 69 66 20  nfo, NULL);..if 
22a0: 28 72 65 73 20 21 3d 20 30 29 20 7b 0a 09 09 72  (res != 0) {...r
22b0: 65 74 75 72 6e 28 72 65 73 29 3b 0a 09 7d 0a 0a  eturn(res);..}..
22c0: 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e 74 79  .if (pathinfo.ty
22d0: 70 65 20 21 3d 20 41 50 50 46 53 5f 50 41 54 48  pe != APPFS_PATH
22e0: 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 29 20 7b 0a  TYPE_SYMLINK) {.
22f0: 09 09 72 65 74 75 72 6e 28 2d 45 49 4e 56 41 4c  ..return(-EINVAL
2300: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 73 74 72  );..}...if ((str
2310: 6c 65 6e 28 70 61 74 68 69 6e 66 6f 2e 74 79 70  len(pathinfo.typ
2320: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f  einfo.symlink.so
2330: 75 72 63 65 29 20 2b 20 31 29 20 3e 20 73 69 7a  urce) + 1) > siz
2340: 65 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45  e) {...return(-E
2350: 4e 41 4d 45 54 4f 4f 4c 4f 4e 47 29 3b 0a 09 7d  NAMETOOLONG);..}
2360: 0a 0a 09 6d 65 6d 63 70 79 28 62 75 66 2c 20 70  ...memcpy(buf, p
2370: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f  athinfo.typeinfo
2380: 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 2c  .symlink.source,
2390: 20 73 74 72 6c 65 6e 28 70 61 74 68 69 6e 66 6f   strlen(pathinfo
23a0: 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e  .typeinfo.symlin
23b0: 6b 2e 73 6f 75 72 63 65 29 20 2b 20 31 29 3b 0a  k.source) + 1);.
23c0: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
23d0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
23e0: 5f 66 75 73 65 5f 67 65 74 61 74 74 72 28 63 6f  _fuse_getattr(co
23f0: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20  nst char *path, 
2400: 73 74 72 75 63 74 20 73 74 61 74 20 2a 73 74 62  struct stat *stb
2410: 75 66 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70  uf) {..struct ap
2420: 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74  pfs_pathinfo pat
2430: 68 69 6e 66 6f 3b 0a 09 69 6e 74 20 72 65 73 20  hinfo;..int res 
2440: 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42  = 0;...APPFS_DEB
2450: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20  UG("Enter (path 
2460: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74  = %s, ...)", pat
2470: 68 29 3b 0a 0a 09 70 61 74 68 69 6e 66 6f 2e 74  h);...pathinfo.t
2480: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48  ype = APPFS_PATH
2490: 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3b 0a  TYPE_DIRECTORY;.
24a0: 09 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e  .pathinfo.typein
24b0: 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e  fo.dir.childcoun
24c0: 74 20 3d 20 30 3b 0a 0a 09 6d 65 6d 73 65 74 28  t = 0;...memset(
24d0: 73 74 62 75 66 2c 20 30 2c 20 73 69 7a 65 6f 66  stbuf, 0, sizeof
24e0: 28 73 74 72 75 63 74 20 73 74 61 74 29 29 3b 0a  (struct stat));.
24f0: 0a 09 73 74 62 75 66 2d 3e 73 74 5f 6d 74 69 6d  ..stbuf->st_mtim
2500: 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 69 6d  e = pathinfo.tim
2510: 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 63 74  e;..stbuf->st_ct
2520: 69 6d 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74  ime = pathinfo.t
2530: 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f  ime;..stbuf->st_
2540: 61 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66 6f  atime = pathinfo
2550: 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e 73  .time;..stbuf->s
2560: 74 5f 69 6e 6f 20 20 20 3d 20 70 61 74 68 69 6e  t_ino   = pathin
2570: 66 6f 2e 69 6e 6f 64 65 3b 0a 09 73 74 62 75 66  fo.inode;..stbuf
2580: 2d 3e 73 74 5f 6d 6f 64 65 20 20 3d 20 30 3b 0a  ->st_mode  = 0;.
2590: 0a 09 73 77 69 74 63 68 20 28 70 61 74 68 69 6e  ..switch (pathin
25a0: 66 6f 2e 74 79 70 65 29 20 7b 0a 09 09 63 61 73  fo.type) {...cas
25b0: 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45  e APPFS_PATHTYPE
25c0: 5f 44 49 52 45 43 54 4f 52 59 3a 0a 09 09 09 73  _DIRECTORY:....s
25d0: 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20  tbuf->st_mode = 
25e0: 53 5f 49 46 44 49 52 20 7c 20 30 35 35 35 3b 0a  S_IFDIR | 0555;.
25f0: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69  ...stbuf->st_nli
2600: 6e 6b 20 3d 20 32 20 2b 20 70 61 74 68 69 6e 66  nk = 2 + pathinf
2610: 6f 2e 74 79 70 65 69 6e 66 6f 2e 64 69 72 2e 63  o.typeinfo.dir.c
2620: 68 69 6c 64 63 6f 75 6e 74 3b 0a 09 09 09 62 72  hildcount;....br
2630: 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46  eak;...case APPF
2640: 53 5f 50 41 54 48 54 59 50 45 5f 46 49 4c 45 3a  S_PATHTYPE_FILE:
2650: 0a 09 09 09 69 66 20 28 70 61 74 68 69 6e 66 6f  ....if (pathinfo
2660: 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 65  .typeinfo.file.e
2670: 78 65 63 75 74 61 62 6c 65 29 20 7b 0a 09 09 09  xecutable) {....
2680: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20  .stbuf->st_mode 
2690: 3d 20 53 5f 49 46 52 45 47 20 7c 20 30 35 35 35  = S_IFREG | 0555
26a0: 3b 0a 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09  ;....} else {...
26b0: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65  ..stbuf->st_mode
26c0: 20 3d 20 53 5f 49 46 52 45 47 20 7c 20 30 34 34   = S_IFREG | 044
26d0: 34 3b 0a 09 09 09 7d 0a 0a 09 09 09 73 74 62 75  4;....}.....stbu
26e0: 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b  f->st_nlink = 1;
26f0: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69  ....stbuf->st_si
2700: 7a 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 79  ze = pathinfo.ty
2710: 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65  peinfo.file.size
2720: 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61  ;....break;...ca
2730: 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 50  se APPFS_PATHTYP
2740: 45 5f 53 59 4d 4c 49 4e 4b 3a 0a 09 09 09 73 74  E_SYMLINK:....st
2750: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53  buf->st_mode = S
2760: 5f 49 46 4c 4e 4b 20 7c 20 30 35 35 35 3b 0a 09  _IFLNK | 0555;..
2770: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e  ..stbuf->st_nlin
2780: 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 2d  k = 1;....stbuf-
2790: 3e 73 74 5f 73 69 7a 65 20 3d 20 70 61 74 68 69  >st_size = pathi
27a0: 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d  nfo.typeinfo.sym
27b0: 6c 69 6e 6b 2e 73 69 7a 65 3b 0a 09 09 09 62 72  link.size;....br
27c0: 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46  eak;...case APPF
27d0: 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c  S_PATHTYPE_INVAL
27e0: 49 44 3a 0a 09 09 09 72 65 73 20 3d 20 2d 45 49  ID:....res = -EI
27f0: 4f 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a 09 7d  O;.....break;..}
2800: 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f 2e  ...if (pathinfo.
2810: 70 61 63 6b 61 67 65 64 29 20 7b 0a 09 09 69 66  packaged) {...if
2820: 20 28 30 29 20 7b 0a 09 09 09 73 74 62 75 66 2d   (0) {....stbuf-
2830: 3e 73 74 5f 6d 6f 64 65 20 7c 3d 20 30 32 32 32  >st_mode |= 0222
2840: 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72  ;...}..}...retur
2850: 6e 20 72 65 73 3b 0a 7d 0a 0a 73 74 61 74 69 63  n res;.}..static
2860: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f   int appfs_fuse_
2870: 72 65 61 64 64 69 72 28 63 6f 6e 73 74 20 63 68  readdir(const ch
2880: 61 72 20 2a 70 61 74 68 2c 20 76 6f 69 64 20 2a  ar *path, void *
2890: 62 75 66 2c 20 66 75 73 65 5f 66 69 6c 6c 5f 64  buf, fuse_fill_d
28a0: 69 72 5f 74 20 66 69 6c 6c 65 72 2c 20 6f 66 66  ir_t filler, off
28b0: 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63  _t offset, struc
28c0: 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f  t fuse_file_info
28d0: 20 2a 66 69 29 20 7b 0a 09 54 63 6c 5f 49 6e 74   *fi) {..Tcl_Int
28e0: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63  erp *interp;..Tc
28f0: 6c 5f 4f 62 6a 20 2a 2a 63 68 69 6c 64 72 65 6e  l_Obj **children
2900: 3b 0a 09 69 6e 74 20 63 68 69 6c 64 72 65 6e 5f  ;..int children_
2910: 63 6f 75 6e 74 2c 20 69 64 78 3b 0a 09 69 6e 74  count, idx;..int
2920: 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 72   tcl_ret;..int r
2930: 65 74 76 61 6c 3b 0a 0a 09 41 50 50 46 53 5f 44  etval;...APPFS_D
2940: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
2950: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
2960: 61 74 68 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d  ath);...interp =
2970: 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70   appfs_TclInterp
2980: 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20  ();..if (interp 
2990: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
29a0: 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 66 69 6c  urn(0);..}...fil
29b0: 6c 65 72 28 62 75 66 2c 20 22 2e 22 2c 20 4e 55  ler(buf, ".", NU
29c0: 4c 4c 2c 20 30 29 3b 0a 09 66 69 6c 6c 65 72 28  LL, 0);..filler(
29d0: 62 75 66 2c 20 22 2e 2e 22 2c 20 4e 55 4c 4c 2c  buf, "..", NULL,
29e0: 20 30 29 3b 0a 0a 0a 09 74 63 6c 5f 72 65 74 20   0);....tcl_ret 
29f0: 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c  = appfs_Tcl_Eval
2a00: 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61  (interp, 2, "::a
2a10: 70 70 66 73 3a 3a 67 65 74 63 68 69 6c 64 72 65  ppfs::getchildre
2a20: 6e 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 28  n", path);..if (
2a30: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f  tcl_ret != TCL_O
2a40: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42  K) {...APPFS_DEB
2a50: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74  UG("::appfs::get
2a60: 63 68 69 6c 64 72 65 6e 28 25 73 29 20 66 61 69  children(%s) fai
2a70: 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09  led.", path);...
2a80: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c  APPFS_DEBUG("Tcl
2a90: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20   Error is: %s", 
2aa0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73  Tcl_GetStringRes
2ab0: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09  ult(interp));...
2ac0: 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d  ...return(0);..}
2ad0: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c  ...tcl_ret = Tcl
2ae0: 5f 4c 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d 65  _ListObjGetEleme
2af0: 6e 74 73 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  nts(interp, Tcl_
2b00: 47 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  GetObjResult(int
2b10: 65 72 70 29 2c 20 26 63 68 69 6c 64 72 65 6e 5f  erp), &children_
2b20: 63 6f 75 6e 74 2c 20 26 63 68 69 6c 64 72 65 6e  count, &children
2b30: 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20  );..if (tcl_ret 
2b40: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41  != TCL_OK) {...A
2b50: 50 50 46 53 5f 44 45 42 55 47 28 22 50 61 72 73  PPFS_DEBUG("Pars
2b60: 69 6e 67 20 6c 69 73 74 20 6f 66 20 63 68 69 6c  ing list of chil
2b70: 64 72 65 6e 20 6f 6e 20 70 61 74 68 20 25 73 20  dren on path %s 
2b80: 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 29 3b  failed.", path);
2b90: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22  ...APPFS_DEBUG("
2ba0: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73  Tcl Error is: %s
2bb0: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  ", Tcl_GetString
2bc0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b  Result(interp));
2bd0: 0a 09 09 0a 09 09 72 65 74 75 72 6e 28 30 29 3b  ......return(0);
2be0: 0a 09 7d 0a 0a 09 66 6f 72 20 28 69 64 78 20 3d  ..}...for (idx =
2bf0: 20 30 3b 20 69 64 78 20 3c 20 63 68 69 6c 64 72   0; idx < childr
2c00: 65 6e 5f 63 6f 75 6e 74 3b 20 69 64 78 2b 2b 29  en_count; idx++)
2c10: 20 7b 0a 09 09 66 69 6c 6c 65 72 28 62 75 66 2c   {...filler(buf,
2c20: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 63   Tcl_GetString(c
2c30: 68 69 6c 64 72 65 6e 5b 69 64 78 5d 29 2c 20 4e  hildren[idx]), N
2c40: 55 4c 4c 2c 20 30 29 3b 0a 09 7d 0a 0a 09 72 65  ULL, 0);..}...re
2c50: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
2c60: 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73  ic int appfs_fus
2c70: 65 5f 6f 70 65 6e 28 63 6f 6e 73 74 20 63 68 61  e_open(const cha
2c80: 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20  r *path, struct 
2c90: 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a  fuse_file_info *
2ca0: 66 69 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70  fi) {..struct ap
2cb0: 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74  pfs_pathinfo pat
2cc0: 68 69 6e 66 6f 3b 0a 09 63 6f 6e 73 74 20 63 68  hinfo;..const ch
2cd0: 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09  ar *real_path;..
2ce0: 69 6e 74 20 66 68 3b 0a 09 69 6e 74 20 67 70 69  int fh;..int gpi
2cf0: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45  _ret;...APPFS_DE
2d00: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68  BUG("Enter (path
2d10: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61   = %s, ...)", pa
2d20: 74 68 29 3b 0a 0a 23 69 66 20 30 0a 0a 09 69 66  th);..#if 0...if
2d30: 20 28 28 66 69 2d 3e 66 6c 61 67 73 20 26 20 33   ((fi->flags & 3
2d40: 29 20 21 3d 20 4f 5f 52 44 4f 4e 4c 59 29 20 7b  ) != O_RDONLY) {
2d50: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
2d60: 20 72 65 74 75 72 6e 28 2d 45 41 43 43 45 53 29   return(-EACCES)
2d70: 3b 0a 09 7d 0a 0a 09 67 70 69 5f 72 65 74 20 3d  ;..}...gpi_ret =
2d80: 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f   appfs_get_path_
2d90: 69 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68  info(path, &path
2da0: 69 6e 66 6f 2c 20 4e 55 4c 4c 29 3b 0a 09 69 66  info, NULL);..if
2db0: 20 28 67 70 69 5f 72 65 74 20 21 3d 20 30 29 20   (gpi_ret != 0) 
2dc0: 7b 0a 09 09 72 65 74 75 72 6e 28 67 70 69 5f 72  {...return(gpi_r
2dd0: 65 74 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 70 61  et);..}...if (pa
2de0: 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 3d 20 41  thinfo.type == A
2df0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49  PPFS_PATHTYPE_DI
2e00: 52 45 43 54 4f 52 59 29 20 7b 0a 09 09 72 65 74  RECTORY) {...ret
2e10: 75 72 6e 28 2d 45 49 53 44 49 52 29 3b 0a 09 7d  urn(-EISDIR);..}
2e20: 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61  ...real_path = a
2e30: 70 70 66 73 5f 67 65 74 66 69 6c 65 28 70 61 74  ppfs_getfile(pat
2e40: 68 69 6e 66 6f 2e 68 6f 73 74 6e 61 6d 65 2c 20  hinfo.hostname, 
2e50: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66  pathinfo.typeinf
2e60: 6f 2e 66 69 6c 65 2e 73 68 61 31 29 3b 0a 09 69  o.file.sha1);..i
2e70: 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20  f (real_path == 
2e80: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
2e90: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 66 68 20  (-EIO);..}...fh 
2ea0: 3d 20 6f 70 65 6e 28 72 65 61 6c 5f 70 61 74 68  = open(real_path
2eb0: 2c 20 4f 5f 52 44 4f 4e 4c 59 29 3b 0a 09 66 72  , O_RDONLY);..fr
2ec0: 65 65 28 28 76 6f 69 64 20 2a 29 20 72 65 61 6c  ee((void *) real
2ed0: 5f 70 61 74 68 29 3b 0a 09 69 66 20 28 66 68 20  _path);..if (fh 
2ee0: 3c 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  < 0) {...return(
2ef0: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 66 69 2d 3e  -EIO);..}...fi->
2f00: 66 68 20 3d 20 66 68 3b 0a 23 65 6e 64 69 66 0a  fh = fh;.#endif.
2f10: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
2f20: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73  static int appfs
2f30: 5f 66 75 73 65 5f 63 6c 6f 73 65 28 63 6f 6e 73  _fuse_close(cons
2f40: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74  t char *path, st
2f50: 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69  ruct fuse_file_i
2f60: 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 69 6e 74 20  nfo *fi) {..int 
2f70: 63 6c 6f 73 65 5f 72 65 74 3b 0a 0a 09 63 6c 6f  close_ret;...clo
2f80: 73 65 5f 72 65 74 20 3d 20 63 6c 6f 73 65 28 66  se_ret = close(f
2f90: 69 2d 3e 66 68 29 3b 0a 09 69 66 20 28 63 6c 6f  i->fh);..if (clo
2fa0: 73 65 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  se_ret != 0) {..
2fb0: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09  .return(-EIO);..
2fc0: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  }...return(0);.}
2fd0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70  ..static int app
2fe0: 66 73 5f 66 75 73 65 5f 72 65 61 64 28 63 6f 6e  fs_fuse_read(con
2ff0: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 63  st char *path, c
3000: 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74  har *buf, size_t
3010: 20 73 69 7a 65 2c 20 6f 66 66 5f 74 20 6f 66 66   size, off_t off
3020: 73 65 74 2c 20 73 74 72 75 63 74 20 66 75 73 65  set, struct fuse
3030: 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20  _file_info *fi) 
3040: 7b 0a 09 6f 66 66 5f 74 20 6c 73 65 65 6b 5f 72  {..off_t lseek_r
3050: 65 74 3b 0a 09 73 73 69 7a 65 5f 74 20 72 65 61  et;..ssize_t rea
3060: 64 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44  d_ret;...APPFS_D
3070: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74  EBUG("Enter (pat
3080: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70  h = %s, ...)", p
3090: 61 74 68 29 3b 0a 0a 09 6c 73 65 65 6b 5f 72 65  ath);...lseek_re
30a0: 74 20 3d 20 6c 73 65 65 6b 28 66 69 2d 3e 66 68  t = lseek(fi->fh
30b0: 2c 20 6f 66 66 73 65 74 2c 20 53 45 45 4b 5f 53  , offset, SEEK_S
30c0: 45 54 29 3b 0a 09 69 66 20 28 6c 73 65 65 6b 5f  ET);..if (lseek_
30d0: 72 65 74 20 21 3d 20 6f 66 66 73 65 74 29 20 7b  ret != offset) {
30e0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b  ...return(-EIO);
30f0: 0a 09 7d 0a 0a 09 72 65 61 64 5f 72 65 74 20 3d  ..}...read_ret =
3100: 20 72 65 61 64 28 66 69 2d 3e 66 68 2c 20 62 75   read(fi->fh, bu
3110: 66 2c 20 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75  f, size);...retu
3120: 72 6e 28 72 65 61 64 5f 72 65 74 29 3b 0a 7d 0a  rn(read_ret);.}.
3130: 0a 2f 2a 0a 20 2a 20 53 51 4c 69 74 65 33 20 6d  ./*. * SQLite3 m
3140: 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72 61 77  ode: Execute raw
3150: 20 53 51 4c 20 61 6e 64 20 72 65 74 75 72 6e 20   SQL and return 
3160: 73 75 63 63 65 73 73 20 6f 72 20 66 61 69 6c 75  success or failu
3170: 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  re. */.static in
3180: 74 20 61 70 70 66 73 5f 73 71 6c 69 74 65 33 28  t appfs_sqlite3(
3190: 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 29  const char *sql)
31a0: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a   {..Tcl_Interp *
31b0: 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63  interp;..const c
31c0: 68 61 72 20 2a 73 71 6c 5f 72 65 74 3b 0a 09 69  har *sql_ret;..i
31d0: 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e  nt tcl_ret;...in
31e0: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65  terp = appfs_cre
31f0: 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  ate_TclInterp();
3200: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
3210: 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74  NULL) {...fprint
3220: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
3230: 65 20 74 6f 20 63 72 65 61 74 65 20 61 20 54 63  e to create a Tc
3240: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20  l interpreter.  
3250: 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a  Aborting.\n");..
3260: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
3270: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66  ..tcl_ret = appf
3280: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72  s_Tcl_Eval(inter
3290: 70 2c 20 35 2c 20 22 3a 3a 61 70 70 66 73 3a 3a  p, 5, "::appfs::
32a0: 64 62 22 2c 20 22 65 76 61 6c 22 2c 20 73 71 6c  db", "eval", sql
32b0: 2c 20 22 72 6f 77 22 2c 20 22 75 6e 73 65 74 20  , "row", "unset 
32c0: 2d 6e 6f 63 6f 6d 70 6c 61 69 6e 20 72 6f 77 28  -nocomplain row(
32d0: 2a 29 3b 20 70 61 72 72 61 79 20 72 6f 77 3b 20  *); parray row; 
32e0: 70 75 74 73 20 5c 22 2d 2d 2d 2d 5c 22 22 29 3b  puts \"----\"");
32f0: 0a 09 73 71 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..sql_ret = Tcl_
3300: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28  GetStringResult(
3310: 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 74  interp);...if (t
3320: 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b  cl_ret != TCL_OK
3330: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74  ) {...fprintf(st
3340: 64 65 72 72 2c 20 22 5b 65 72 72 6f 72 5d 20 25  derr, "[error] %
3350: 73 5c 6e 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a  s\n", sql_ret);.
3360: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
3370: 0a 0a 09 69 66 20 28 73 71 6c 5f 72 65 74 20 26  ...if (sql_ret &
3380: 26 20 73 71 6c 5f 72 65 74 5b 30 5d 20 21 3d 20  & sql_ret[0] != 
3390: 27 5c 30 27 29 20 7b 0a 09 09 70 72 69 6e 74 66  '\0') {...printf
33a0: 28 22 25 73 5c 6e 22 2c 20 73 71 6c 5f 72 65 74  ("%s\n", sql_ret
33b0: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30  );..}...return(0
33c0: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 54 63 6c 20  );.}../*. * Tcl 
33d0: 6d 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72 61  mode: Execute ra
33e0: 77 20 54 63 6c 20 61 6e 64 20 72 65 74 75 72 6e  w Tcl and return
33f0: 20 73 75 63 63 65 73 73 20 6f 72 20 66 61 69 6c   success or fail
3400: 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69  ure. */.static i
3410: 6e 74 20 61 70 70 66 73 5f 74 63 6c 28 63 6f 6e  nt appfs_tcl(con
3420: 73 74 20 63 68 61 72 20 2a 74 63 6c 29 20 7b 0a  st char *tcl) {.
3430: 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74  .Tcl_Interp *int
3440: 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72  erp;..const char
3450: 20 2a 74 63 6c 5f 72 65 73 75 6c 74 3b 0a 09 69   *tcl_result;..i
3460: 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 6e  nt tcl_ret;...in
3470: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65  terp = appfs_cre
3480: 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b  ate_TclInterp();
3490: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20  ..if (interp == 
34a0: 4e 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74  NULL) {...fprint
34b0: 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c  f(stderr, "Unabl
34c0: 65 20 74 6f 20 63 72 65 61 74 65 20 61 20 54 63  e to create a Tc
34d0: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20  l interpreter.  
34e0: 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a  Aborting.\n");..
34f0: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
3500: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f  ..tcl_ret = Tcl_
3510: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 74 63 6c  Eval(interp, tcl
3520: 29 3b 0a 09 74 63 6c 5f 72 65 73 75 6c 74 20 3d  );..tcl_result =
3530: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65   Tcl_GetStringRe
3540: 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09  sult(interp);...
3550: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54  if (tcl_ret != T
3560: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e  CL_OK) {...fprin
3570: 74 66 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72  tf(stderr, "[err
3580: 6f 72 5d 20 25 73 5c 6e 22 2c 20 74 63 6c 5f 72  or] %s\n", tcl_r
3590: 65 73 75 6c 74 29 3b 0a 0a 09 09 72 65 74 75 72  esult);....retur
35a0: 6e 28 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 74  n(1);..}...if (t
35b0: 63 6c 5f 72 65 73 75 6c 74 20 26 26 20 74 63 6c  cl_result && tcl
35c0: 5f 72 65 73 75 6c 74 5b 30 5d 20 21 3d 20 27 5c  _result[0] != '\
35d0: 30 27 29 20 7b 0a 09 09 70 72 69 6e 74 66 28 22  0') {...printf("
35e0: 25 73 5c 6e 22 2c 20 74 63 6c 5f 72 65 73 75 6c  %s\n", tcl_resul
35f0: 74 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  t);..}...return(
3600: 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 41 70 70  0);.}../*. * App
3610: 46 53 64 20 50 61 63 6b 61 67 65 20 66 6f 72 20  FSd Package for 
3620: 54 63 6c 3a 0a 20 2a 20 20 20 20 20 20 20 20 20  Tcl:. *         
3630: 42 72 69 64 67 65 20 66 6f 72 20 49 2f 4f 20 6f  Bridge for I/O o
3640: 70 65 72 61 74 69 6f 6e 73 20 74 6f 20 72 65 71  perations to req
3650: 75 65 73 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e  uest information
3660: 20 61 62 6f 75 74 20 74 68 65 20 63 75 72 72 65   about the curre
3670: 6e 74 0a 20 2a 20 20 20 20 20 20 20 20 20 74 72  nt. *         tr
3680: 61 6e 73 61 63 74 69 6f 6e 0a 20 2a 2f 0a 73 74  ansaction. */.st
3690: 61 74 69 63 20 69 6e 74 20 41 70 70 66 73 64 5f  atic int Appfsd_
36a0: 49 6e 69 74 28 54 63 6c 5f 49 6e 74 65 72 70 20  Init(Tcl_Interp 
36b0: 2a 69 6e 74 65 72 70 29 20 7b 0a 23 69 66 64 65  *interp) {.#ifde
36c0: 66 20 55 53 45 5f 54 43 4c 5f 53 54 55 42 53 0a  f USE_TCL_STUBS.
36d0: 09 69 66 20 28 54 63 6c 5f 49 6e 69 74 53 74 75  .if (Tcl_InitStu
36e0: 62 73 28 69 6e 74 65 72 70 2c 20 54 43 4c 5f 56  bs(interp, TCL_V
36f0: 45 52 53 49 4f 4e 2c 20 30 29 20 3d 3d 20 30 4c  ERSION, 0) == 0L
3700: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 54 43 4c  ) {...return(TCL
3710: 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 23 65 6e 64  _ERROR);..}.#end
3720: 69 66 0a 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f  if...Tcl_CreateO
3730: 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70  bjCommand(interp
3740: 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 68  , "appfsd::get_h
3750: 6f 6d 65 64 69 72 22 2c 20 74 63 6c 5f 61 70 70  omedir", tcl_app
3760: 66 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 2c 20  fs_get_homedir, 
3770: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 54  NULL, NULL);...T
3780: 63 6c 5f 50 6b 67 50 72 6f 76 69 64 65 28 69 6e  cl_PkgProvide(in
3790: 74 65 72 70 2c 20 22 61 70 70 66 73 64 22 2c 20  terp, "appfsd", 
37a0: 22 31 2e 30 22 29 3b 0a 0a 09 72 65 74 75 72 6e  "1.0");...return
37b0: 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 2f 2a 0a  (TCL_OK);.}../*.
37c0: 20 2a 20 46 55 53 45 20 6f 70 65 72 61 74 69 6f   * FUSE operatio
37d0: 6e 73 20 73 74 72 75 63 74 75 72 65 0a 20 2a 2f  ns structure. */
37e0: 0a 73 74 61 74 69 63 20 73 74 72 75 63 74 20 66  .static struct f
37f0: 75 73 65 5f 6f 70 65 72 61 74 69 6f 6e 73 20 61  use_operations a
3800: 70 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 20  ppfs_operations 
3810: 3d 20 7b 0a 09 2e 67 65 74 61 74 74 72 20 20 20  = {...getattr   
3820: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 67 65 74  = appfs_fuse_get
3830: 61 74 74 72 2c 0a 09 2e 72 65 61 64 64 69 72 20  attr,...readdir 
3840: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72    = appfs_fuse_r
3850: 65 61 64 64 69 72 2c 0a 09 2e 72 65 61 64 6c 69  eaddir,...readli
3860: 6e 6b 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65  nk  = appfs_fuse
3870: 5f 72 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f 70 65  _readlink,...ope
3880: 6e 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66  n      = appfs_f
3890: 75 73 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65 6c 65  use_open,...rele
38a0: 61 73 65 20 20 20 3d 20 61 70 70 66 73 5f 66 75  ase   = appfs_fu
38b0: 73 65 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65 61 64  se_close,...read
38c0: 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75        = appfs_fu
38d0: 73 65 5f 72 65 61 64 0a 7d 3b 0a 0a 2f 2a 0a 20  se_read.};../*. 
38e0: 2a 20 46 55 53 45 20 6f 70 74 69 6f 6e 20 70 61  * FUSE option pa
38f0: 72 73 69 6e 67 20 63 61 6c 6c 62 61 63 6b 0a 20  rsing callback. 
3900: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  */.static int ap
3910: 70 66 73 5f 66 75 73 65 5f 6f 70 74 5f 63 62 28  pfs_fuse_opt_cb(
3920: 76 6f 69 64 20 2a 64 61 74 61 2c 20 63 6f 6e 73  void *data, cons
3930: 74 20 63 68 61 72 20 2a 61 72 67 2c 20 69 6e 74  t char *arg, int
3940: 20 6b 65 79 2c 20 73 74 72 75 63 74 20 66 75 73   key, struct fus
3950: 65 5f 61 72 67 73 20 2a 6f 75 74 61 72 67 73 29  e_args *outargs)
3960: 20 7b 0a 09 73 74 61 74 69 63 20 73 65 65 6e 5f   {..static seen_
3970: 63 61 63 68 65 64 69 72 20 3d 20 30 3b 0a 0a 09  cachedir = 0;...
3980: 69 66 20 28 6b 65 79 20 3d 3d 20 46 55 53 45 5f  if (key == FUSE_
3990: 4f 50 54 5f 4b 45 59 5f 4e 4f 4e 4f 50 54 20 26  OPT_KEY_NONOPT &
39a0: 26 20 73 65 65 6e 5f 63 61 63 68 65 64 69 72 20  & seen_cachedir 
39b0: 3d 3d 20 30 29 20 7b 0a 09 09 73 65 65 6e 5f 63  == 0) {...seen_c
39c0: 61 63 68 65 64 69 72 20 3d 20 31 3b 0a 0a 09 09  achedir = 1;....
39d0: 61 70 70 66 73 5f 63 61 63 68 65 64 69 72 20 3d  appfs_cachedir =
39e0: 20 73 74 72 64 75 70 28 61 72 67 29 3b 0a 0a 09   strdup(arg);...
39f0: 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a  .return(0);..}..
3a00: 09 72 65 74 75 72 6e 28 31 29 3b 0a 7d 0a 0a 2f  .return(1);.}../
3a10: 2a 0a 20 2a 20 45 6e 74 72 79 20 70 6f 69 6e 74  *. * Entry point
3a20: 20 69 6e 74 6f 20 74 68 69 73 20 70 72 6f 67 72   into this progr
3a30: 61 6d 2e 0a 20 2a 2f 0a 69 6e 74 20 6d 61 69 6e  am.. */.int main
3a40: 28 69 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20  (int argc, char 
3a50: 2a 2a 61 72 67 76 29 20 7b 0a 09 73 74 72 75 63  **argv) {..struc
3a60: 74 20 66 75 73 65 5f 61 72 67 73 20 61 72 67 73  t fuse_args args
3a70: 20 3d 20 46 55 53 45 5f 41 52 47 53 5f 49 4e 49   = FUSE_ARGS_INI
3a80: 54 28 61 72 67 63 2c 20 61 72 67 76 29 3b 0a 09  T(argc, argv);..
3a90: 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b  int pthread_ret;
3aa0: 0a 0a 09 2f 2a 0a 09 20 2a 20 53 6b 69 70 20 70  .../*.. * Skip p
3ab0: 61 73 73 65 64 20 70 72 6f 67 72 61 6d 20 6e 61  assed program na
3ac0: 6d 65 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72 67  me.. */..if (arg
3ad0: 63 20 3d 3d 20 30 20 7c 7c 20 61 72 67 76 20 3d  c == 0 || argv =
3ae0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
3af0: 72 6e 28 31 29 3b 0a 09 7d 0a 09 61 72 67 63 2d  rn(1);..}..argc-
3b00: 2d 3b 0a 09 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a  -;..argv++;.../*
3b10: 0a 09 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20  .. * Set global 
3b20: 76 61 72 69 61 62 6c 65 73 2c 20 74 68 65 73 65  variables, these
3b30: 20 73 68 6f 75 6c 64 20 62 65 20 63 6f 6e 66 69   should be confi
3b40: 67 75 72 61 74 69 6f 6e 20 6f 70 74 69 6f 6e 73  guration options
3b50: 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61  ... */..appfs_ca
3b60: 63 68 65 64 69 72 20 3d 20 41 50 50 46 53 5f 43  chedir = APPFS_C
3b70: 41 43 48 45 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20  ACHEDIR;.../*.. 
3b80: 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72  * Set global var
3b90: 69 61 62 6c 65 20 66 6f 72 20 22 62 6f 6f 74 20  iable for "boot 
3ba0: 74 69 6d 65 22 20 74 6f 20 73 65 74 20 61 20 74  time" to set a t
3bb0: 69 6d 65 20 6f 6e 20 64 69 72 65 63 74 6f 72 69  ime on directori
3bc0: 65 73 0a 09 20 2a 20 74 68 61 74 20 77 65 20 66  es.. * that we f
3bd0: 61 6b 65 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73  ake... */..appfs
3be0: 5f 62 6f 6f 74 74 69 6d 65 20 3d 20 74 69 6d 65  _boottime = time
3bf0: 28 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a  (NULL);.../*.. *
3c00: 20 52 65 67 69 73 74 65 72 20 22 73 68 61 31 22   Register "sha1"
3c10: 20 61 6e 64 20 22 61 70 70 66 73 64 22 20 70 61   and "appfsd" pa
3c20: 63 6b 61 67 65 20 77 69 74 68 20 6c 69 62 74 63  ckage with libtc
3c30: 6c 20 73 6f 20 74 68 61 74 20 61 6e 79 20 6e 65  l so that any ne
3c40: 77 0a 09 20 2a 20 69 6e 74 65 72 70 72 65 74 65  w.. * interprete
3c50: 72 73 20 63 72 65 61 74 65 64 20 28 77 68 69 63  rs created (whic
3c60: 68 20 61 72 65 20 64 6f 6e 65 20 64 79 6e 61 6d  h are done dynam
3c70: 69 63 61 6c 6c 79 20 62 79 20 46 55 53 45 29 20  ically by FUSE) 
3c80: 63 61 6e 20 68 61 76 65 0a 09 20 2a 20 74 68 65  can have.. * the
3c90: 20 61 70 70 72 6f 70 72 69 61 74 65 20 63 6f 6e   appropriate con
3ca0: 66 69 67 75 72 61 74 69 6f 6e 20 64 6f 6e 65 20  figuration done 
3cb0: 61 75 74 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 09  automatically...
3cc0: 20 2a 2f 0a 09 54 63 6c 5f 53 74 61 74 69 63 50   */..Tcl_StaticP
3cd0: 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 73 68  ackage(NULL, "sh
3ce0: 61 31 22 2c 20 53 68 61 31 5f 49 6e 69 74 2c 20  a1", Sha1_Init, 
3cf0: 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 53 74 61 74  NULL);..Tcl_Stat
3d00: 69 63 50 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20  icPackage(NULL, 
3d10: 22 61 70 70 66 73 64 22 2c 20 41 70 70 66 73 64  "appfsd", Appfsd
3d20: 5f 49 6e 69 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09  _Init, NULL);...
3d30: 2f 2a 0a 09 20 2a 20 43 72 65 61 74 65 20 61 20  /*.. * Create a 
3d40: 74 68 72 65 61 64 2d 73 70 65 63 69 66 69 63 2d  thread-specific-
3d50: 64 61 74 61 20 28 54 53 44 29 20 6b 65 79 20 66  data (TSD) key f
3d60: 6f 72 20 65 61 63 68 20 74 68 72 65 61 64 20 74  or each thread t
3d70: 6f 20 72 65 66 65 72 0a 09 20 2a 20 74 6f 20 69  o refer.. * to i
3d80: 74 73 20 6f 77 6e 20 54 63 6c 20 69 6e 74 65 72  ts own Tcl inter
3d90: 70 72 65 74 65 72 2e 20 20 54 63 6c 20 69 6e 74  preter.  Tcl int
3da0: 65 72 70 72 65 74 65 72 73 20 6d 75 73 74 20 62  erpreters must b
3db0: 65 20 75 6e 69 71 75 65 20 70 65 72 0a 09 20 2a  e unique per.. *
3dc0: 20 74 68 72 65 61 64 20 61 6e 64 20 6e 65 77 20   thread and new 
3dd0: 74 68 72 65 61 64 73 20 61 72 65 20 64 79 6e 61  threads are dyna
3de0: 6d 69 63 61 6c 6c 79 20 63 72 65 61 74 65 64 20  mically created 
3df0: 62 79 20 46 55 53 45 2e 0a 09 20 2a 2f 0a 09 70  by FUSE... */..p
3e00: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68  thread_ret = pth
3e10: 72 65 61 64 5f 6b 65 79 5f 63 72 65 61 74 65 28  read_key_create(
3e20: 26 69 6e 74 65 72 70 4b 65 79 2c 20 4e 55 4c 4c  &interpKey, NULL
3e30: 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f  );..if (pthread_
3e40: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 66 70  ret != 0) {...fp
3e50: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55  rintf(stderr, "U
3e60: 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20  nable to create 
3e70: 54 53 44 20 6b 65 79 20 66 6f 72 20 54 63 6c 2e  TSD key for Tcl.
3e80: 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b    Aborting.\n");
3e90: 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  ....return(1);..
3ea0: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61  }.../*.. * Manua
3eb0: 6c 6c 79 20 73 70 65 63 69 66 79 20 63 61 63 68  lly specify cach
3ec0: 65 20 64 69 72 65 63 74 6f 72 79 2c 20 77 69 74  e directory, wit
3ed0: 68 6f 75 74 20 46 55 53 45 20 63 61 6c 6c 62 61  hout FUSE callba
3ee0: 63 6b 0a 09 20 2a 20 54 68 69 73 20 6f 70 74 69  ck.. * This opti
3ef0: 6f 6e 20 6f 6e 6c 79 20 77 6f 72 6b 73 20 77 68  on only works wh
3f00: 65 6e 20 6e 6f 74 20 75 73 69 6e 67 20 46 55 53  en not using FUS
3f10: 45 2c 20 73 69 6e 63 65 20 77 65 0a 09 20 2a 20  E, since we.. * 
3f20: 64 6f 20 6e 6f 74 20 70 72 6f 63 65 73 73 20 69  do not process i
3f30: 74 20 77 69 74 68 20 46 55 53 45 73 20 6f 70 74  t with FUSEs opt
3f40: 69 6f 6e 20 70 72 6f 63 65 73 73 69 6e 67 2e 0a  ion processing..
3f50: 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3e  . */..if (argc >
3f60: 3d 20 32 29 20 7b 0a 09 09 69 66 20 28 73 74 72  = 2) {...if (str
3f70: 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d  cmp(argv[0], "--
3f80: 63 61 63 68 65 64 69 72 22 29 20 3d 3d 20 30 29  cachedir") == 0)
3f90: 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 63 68   {....appfs_cach
3fa0: 65 64 69 72 20 3d 20 73 74 72 64 75 70 28 61 72  edir = strdup(ar
3fb0: 67 76 5b 31 5d 29 3b 0a 0a 09 09 09 61 72 67 63  gv[1]);.....argc
3fc0: 20 2d 3d 20 32 3b 0a 09 09 09 61 72 67 76 20 2b   -= 2;....argv +
3fd0: 3d 20 32 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a  = 2;...}..}.../*
3fe0: 0a 09 20 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64  .. * SQLite3 mod
3ff0: 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72  e, for running r
4000: 61 77 20 53 51 4c 20 61 67 61 69 6e 73 74 20 74  aw SQL against t
4010: 68 65 20 63 61 63 68 65 20 64 61 74 61 62 61 73  he cache databas
4020: 65 0a 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63  e.. */..if (argc
4030: 20 3d 3d 20 32 20 26 26 20 73 74 72 63 6d 70 28   == 2 && strcmp(
4040: 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69  argv[0], "--sqli
4050: 74 65 33 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09  te3") == 0) {...
4060: 72 65 74 75 72 6e 28 61 70 70 66 73 5f 73 71 6c  return(appfs_sql
4070: 69 74 65 33 28 61 72 67 76 5b 31 5d 29 29 3b 0a  ite3(argv[1]));.
4080: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 54 63 6c 20  .}.../*.. * Tcl 
4090: 6d 6f 64 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e  mode, for runnin
40a0: 67 20 72 61 77 20 54 63 6c 20 69 6e 20 74 68 65  g raw Tcl in the
40b0: 20 73 61 6d 65 20 65 6e 76 69 72 6f 6e 6d 65 6e   same environmen
40c0: 74 20 41 70 70 46 53 64 20 77 6f 75 6c 64 0a 09  t AppFSd would..
40d0: 20 2a 20 72 75 6e 20 63 6f 64 65 2e 0a 09 20 2a   * run code... *
40e0: 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20 32  /..if (argc == 2
40f0: 20 26 26 20 73 74 72 63 6d 70 28 61 72 67 76 5b   && strcmp(argv[
4100: 30 5d 2c 20 22 2d 2d 74 63 6c 22 29 20 3d 3d 20  0], "--tcl") == 
4110: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 61 70  0) {...return(ap
4120: 70 66 73 5f 74 63 6c 28 61 72 67 76 5b 31 5d 29  pfs_tcl(argv[1])
4130: 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 41  );..}.../*.. * A
4140: 64 64 20 46 55 53 45 20 61 72 67 75 6d 65 6e 74  dd FUSE argument
4150: 73 20 77 68 69 63 68 20 77 65 20 61 6c 77 61 79  s which we alway
4160: 73 20 73 75 70 70 6c 79 0a 09 20 2a 2f 0a 09 66  s supply.. */..f
4170: 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 26 61  use_opt_parse(&a
4180: 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c  rgs, NULL, NULL,
4190: 20 61 70 70 66 73 5f 66 75 73 65 5f 6f 70 74 5f   appfs_fuse_opt_
41a0: 63 62 29 3b 0a 09 66 75 73 65 5f 6f 70 74 5f 61  cb);..fuse_opt_a
41b0: 64 64 5f 61 72 67 28 26 61 72 67 73 2c 20 22 2d  dd_arg(&args, "-
41c0: 6f 64 65 66 61 75 6c 74 5f 70 65 72 6d 69 73 73  odefault_permiss
41d0: 69 6f 6e 73 2c 66 73 6e 61 6d 65 3d 61 70 70 66  ions,fsname=appf
41e0: 73 2c 73 75 62 74 79 70 65 3d 61 70 70 66 73 64  s,subtype=appfsd
41f0: 2c 75 73 65 5f 69 6e 6f 2c 6b 65 72 6e 65 6c 5f  ,use_ino,kernel_
4200: 63 61 63 68 65 2c 65 6e 74 72 79 5f 74 69 6d 65  cache,entry_time
4210: 6f 75 74 3d 36 30 2c 61 74 74 72 5f 74 69 6d 65  out=60,attr_time
4220: 6f 75 74 3d 33 36 30 30 2c 69 6e 74 72 2c 62 69  out=3600,intr,bi
4230: 67 5f 77 72 69 74 65 73 22 29 3b 0a 0a 09 69 66  g_writes");...if
4240: 20 28 67 65 74 75 69 64 28 29 20 3d 3d 20 30 29   (getuid() == 0)
4250: 20 7b 0a 09 09 66 75 73 65 5f 6f 70 74 5f 70 61   {...fuse_opt_pa
4260: 72 73 65 28 26 61 72 67 73 2c 20 4e 55 4c 4c 2c  rse(&args, NULL,
4270: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09   NULL, NULL);...
4280: 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67  fuse_opt_add_arg
4290: 28 26 61 72 67 73 2c 20 22 2d 6f 61 6c 6c 6f 77  (&args, "-oallow
42a0: 5f 6f 74 68 65 72 22 29 3b 0a 09 7d 0a 0a 09 2f  _other");..}.../
42b0: 2a 0a 09 20 2a 20 45 6e 74 65 72 20 74 68 65 20  *.. * Enter the 
42c0: 46 55 53 45 20 6d 61 69 6e 20 6c 6f 6f 70 20 2d  FUSE main loop -
42d0: 2d 20 74 68 69 73 20 77 69 6c 6c 20 70 72 6f 63  - this will proc
42e0: 65 73 73 20 61 6e 79 20 61 72 67 75 6d 65 6e 74  ess any argument
42f0: 73 0a 09 20 2a 20 61 6e 64 20 73 74 61 72 74 20  s.. * and start 
4300: 73 65 72 76 69 63 69 6e 67 20 72 65 71 75 65 73  servicing reques
4310: 74 73 2e 0a 09 20 2a 2f 0a 09 72 65 74 75 72 6e  ts... */..return
4320: 28 66 75 73 65 5f 6d 61 69 6e 28 61 72 67 73 2e  (fuse_main(args.
4330: 61 72 67 63 2c 20 61 72 67 73 2e 61 72 67 76 2c  argc, args.argv,
4340: 20 26 61 70 70 66 73 5f 6f 70 65 72 61 74 69 6f   &appfs_operatio
4350: 6e 73 2c 20 4e 55 4c 4c 29 29 3b 0a 7d 0a 20 0a  ns, NULL));.}. .