0000: 23 64 65 66 69 6e 65 20 46 55 53 45 5f 55 53 45 #define FUSE_USE
0010: 5f 56 45 52 53 49 4f 4e 20 32 36 0a 0a 23 69 6e _VERSION 26..#in
0020: 63 6c 75 64 65 20 3c 73 79 73 2f 66 73 75 69 64 clude <sys/fsuid
0030: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79 .h>.#include <sy
0040: 73 2f 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63 6c s/types.h>.#incl
0050: 75 64 65 20 3c 70 74 68 72 65 61 64 2e 68 3e 0a ude <pthread.h>.
0060: 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67 #include <string
0070: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 .h>.#include <st
0080: 64 61 72 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 darg.h>.#include
0090: 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 69 6e 63 <stdlib.h>.#inc
00a0: 6c 75 64 65 20 3c 75 6e 69 73 74 64 2e 68 3e 0a lude <unistd.h>.
00b0: 23 69 6e 63 6c 75 64 65 20 3c 65 72 72 6e 6f 2e #include <errno.
00c0: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 66 63 6e h>.#include <fcn
00d0: 74 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c tl.h>.#include <
00e0: 73 74 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c 75 64 stdio.h>.#includ
00f0: 65 20 3c 66 75 73 65 2e 68 3e 0a 23 69 6e 63 6c e <fuse.h>.#incl
0100: 75 64 65 20 3c 70 77 64 2e 68 3e 0a 23 69 6e 63 ude <pwd.h>.#inc
0110: 6c 75 64 65 20 3c 74 63 6c 2e 68 3e 0a 0a 2f 2a lude <tcl.h>../*
0120: 0a 20 2a 20 44 65 66 61 75 6c 74 20 63 61 63 68 . * Default cach
0130: 65 20 64 69 72 65 63 74 6f 72 79 0a 20 2a 2f 0a e directory. */.
0140: 23 69 66 6e 64 65 66 20 41 50 50 46 53 5f 43 41 #ifndef APPFS_CA
0150: 43 48 45 44 49 52 0a 23 64 65 66 69 6e 65 20 41 CHEDIR.#define A
0160: 50 50 46 53 5f 43 41 43 48 45 44 49 52 20 22 2f PPFS_CACHEDIR "/
0170: 76 61 72 2f 63 61 63 68 65 2f 61 70 70 66 73 22 var/cache/appfs"
0180: 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20 44 65 62 75 .#endif../* Debu
0190: 67 67 69 6e 67 20 6d 61 63 72 6f 73 20 2a 2f 0a gging macros */.
01a0: 23 69 66 64 65 66 20 44 45 42 55 47 0a 23 64 65 #ifdef DEBUG.#de
01b0: 66 69 6e 65 20 41 50 50 46 53 5f 44 45 42 55 47 fine APPFS_DEBUG
01c0: 28 78 2e 2e 2e 29 20 7b 20 66 70 72 69 6e 74 66 (x...) { fprintf
01d0: 28 73 74 64 65 72 72 2c 20 22 5b 64 65 62 75 67 (stderr, "[debug
01e0: 5d 20 25 73 3a 25 69 3a 25 73 3a 20 22 2c 20 5f ] %s:%i:%s: ", _
01f0: 5f 46 49 4c 45 5f 5f 2c 20 5f 5f 4c 49 4e 45 5f _FILE__, __LINE_
0200: 5f 2c 20 5f 5f 66 75 6e 63 5f 5f 29 3b 20 66 70 _, __func__); fp
0210: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 78 29 rintf(stderr, x)
0220: 3b 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 ; fprintf(stderr
0230: 2c 20 22 5c 6e 22 29 3b 20 7d 0a 23 65 6c 73 65 , "\n"); }.#else
0240: 0a 23 64 65 66 69 6e 65 20 41 50 50 46 53 5f 44 .#define APPFS_D
0250: 45 42 55 47 28 78 2e 2e 2e 29 20 2f 2a 2a 2f 0a EBUG(x...) /**/.
0260: 23 65 6e 64 69 66 0a 0a 2f 2a 0a 20 2a 20 53 48 #endif../*. * SH
0270: 41 31 20 54 63 6c 20 50 61 63 6b 61 67 65 20 69 A1 Tcl Package i
0280: 6e 69 74 69 61 6c 69 7a 65 72 2c 20 66 72 6f 6d nitializer, from
0290: 20 73 68 61 31 2e 6f 0a 20 2a 2f 0a 69 6e 74 20 sha1.o. */.int
02a0: 53 68 61 31 5f 49 6e 69 74 28 54 63 6c 5f 49 6e Sha1_Init(Tcl_In
02b0: 74 65 72 70 20 2a 69 6e 74 65 72 70 29 3b 0a 0a terp *interp);..
02c0: 2f 2a 0a 20 2a 20 54 68 72 65 61 64 20 53 70 65 /*. * Thread Spe
02d0: 63 69 66 69 63 20 44 61 74 61 20 28 54 53 44 29 cific Data (TSD)
02e0: 20 66 6f 72 20 54 63 6c 20 49 6e 74 65 72 70 72 for Tcl Interpr
02f0: 65 74 65 72 20 66 6f 72 20 74 68 65 20 63 75 72 eter for the cur
0300: 72 65 6e 74 20 74 68 72 65 61 64 0a 20 2a 2f 0a rent thread. */.
0310: 73 74 61 74 69 63 20 70 74 68 72 65 61 64 5f 6b static pthread_k
0320: 65 79 5f 74 20 69 6e 74 65 72 70 4b 65 79 3b 0a ey_t interpKey;.
0330: 0a 2f 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20 76 61 ./*. * Global va
0340: 72 69 61 62 6c 65 73 2c 20 6e 65 65 64 65 64 20 riables, needed
0350: 66 6f 72 20 61 6c 6c 20 74 68 72 65 61 64 73 20 for all threads
0360: 62 75 74 20 6f 6e 6c 79 20 69 6e 69 74 69 61 6c but only initial
0370: 69 7a 65 64 20 62 65 66 6f 72 65 20 61 6e 79 0a ized before any.
0380: 20 2a 20 46 55 53 45 20 74 68 72 65 61 64 73 20 * FUSE threads
0390: 61 72 65 20 63 72 65 61 74 65 64 0a 20 2a 2f 0a are created. */.
03a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 70 70 66 const char *appf
03b0: 73 5f 63 61 63 68 65 64 69 72 3b 0a 74 69 6d 65 s_cachedir;.time
03c0: 5f 74 20 61 70 70 66 73 5f 62 6f 6f 74 74 69 6d _t appfs_boottim
03d0: 65 3b 0a 69 6e 74 20 61 70 70 66 73 5f 66 75 73 e;.int appfs_fus
03e0: 65 5f 73 74 61 72 74 65 64 20 3d 20 30 3b 0a 0a e_started = 0;..
03f0: 2f 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20 76 61 72 /*. * Global var
0400: 69 61 62 6c 65 73 20 66 6f 72 20 41 70 70 46 53 iables for AppFS
0410: 20 63 61 63 68 69 6e 67 0a 20 2a 2f 0a 70 74 68 caching. */.pth
0420: 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 61 70 70 read_mutex_t app
0430: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 fs_path_info_cac
0440: 68 65 5f 6d 75 74 65 78 20 3d 20 50 54 48 52 45 he_mutex = PTHRE
0450: 41 44 5f 4d 55 54 45 58 5f 49 4e 49 54 49 41 4c AD_MUTEX_INITIAL
0460: 49 5a 45 52 3b 0a 69 6e 74 20 61 70 70 66 73 5f IZER;.int appfs_
0470: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f path_info_cache_
0480: 73 69 7a 65 20 3d 20 38 32 30 39 3b 0a 73 74 72 size = 8209;.str
0490: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e uct appfs_pathin
04a0: 66 6f 20 2a 61 70 70 66 73 5f 70 61 74 68 5f 69 fo *appfs_path_i
04b0: 6e 66 6f 5f 63 61 63 68 65 20 3d 20 4e 55 4c 4c nfo_cache = NULL
04c0: 3b 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 20 50 ;../*. * AppFS P
04d0: 61 74 68 20 54 79 70 65 3a 20 20 44 65 73 63 72 ath Type: Descr
04e0: 69 62 65 73 20 74 68 65 20 74 79 70 65 20 6f 66 ibes the type of
04f0: 20 70 61 74 68 20 61 20 67 69 76 65 6e 20 66 69 path a given fi
0500: 6c 65 20 69 73 0a 20 2a 2f 0a 74 79 70 65 64 65 le is. */.typede
0510: 66 20 65 6e 75 6d 20 7b 0a 09 41 50 50 46 53 5f f enum {..APPFS_
0520: 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 PATHTYPE_INVALID
0530: 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 ,..APPFS_PATHTYP
0540: 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 E_DOES_NOT_EXIST
0550: 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 ,..APPFS_PATHTYP
0560: 45 5f 46 49 4c 45 2c 0a 09 41 50 50 46 53 5f 50 E_FILE,..APPFS_P
0570: 41 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f 52 ATHTYPE_DIRECTOR
0580: 59 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 Y,..APPFS_PATHTY
0590: 50 45 5f 53 59 4d 4c 49 4e 4b 2c 0a 09 41 50 50 PE_SYMLINK,..APP
05a0: 46 53 5f 50 41 54 48 54 59 50 45 5f 53 4f 43 4b FS_PATHTYPE_SOCK
05b0: 45 54 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 ET,..APPFS_PATHT
05c0: 59 50 45 5f 46 49 46 4f 2c 0a 7d 20 61 70 70 66 YPE_FIFO,.} appf
05d0: 73 5f 70 61 74 68 74 79 70 65 5f 74 3b 0a 0a 2f s_pathtype_t;../
05e0: 2a 0a 20 2a 20 41 70 70 46 53 20 50 61 74 68 20 *. * AppFS Path
05f0: 49 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 20 2a 20 Information:. *
0600: 20 20 20 20 20 20 20 20 43 6f 6d 70 6c 65 74 65 Complete
0610: 6c 79 20 64 65 73 63 72 69 62 65 73 20 61 20 73 ly describes a s
0620: 70 65 63 69 66 69 63 20 70 61 74 68 2c 20 68 6f pecific path, ho
0630: 77 20 69 74 20 73 68 6f 75 6c 64 20 62 65 20 72 w it should be r
0640: 65 74 75 72 6e 65 64 20 74 6f 0a 20 2a 20 20 20 eturned to. *
0650: 20 20 20 20 20 20 74 6f 20 74 68 65 20 6b 65 72 to the ker
0660: 6e 65 6c 0a 20 2a 2f 0a 73 74 72 75 63 74 20 61 nel. */.struct a
0670: 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 7b 0a ppfs_pathinfo {.
0680: 09 61 70 70 66 73 5f 70 61 74 68 74 79 70 65 5f .appfs_pathtype_
0690: 74 20 74 79 70 65 3b 0a 09 74 69 6d 65 5f 74 20 t type;..time_t
06a0: 74 69 6d 65 3b 0a 09 63 68 61 72 20 68 6f 73 74 time;..char host
06b0: 6e 61 6d 65 5b 32 35 36 5d 3b 0a 09 69 6e 74 20 name[256];..int
06c0: 70 61 63 6b 61 67 65 64 3b 0a 09 75 6e 73 69 67 packaged;..unsig
06d0: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 20 69 6e ned long long in
06e0: 6f 64 65 3b 0a 09 75 6e 69 6f 6e 20 7b 0a 09 09 ode;..union {...
06f0: 73 74 72 75 63 74 20 7b 0a 09 09 09 69 6e 74 20 struct {....int
0700: 63 68 69 6c 64 63 6f 75 6e 74 3b 0a 09 09 7d 20 childcount;...}
0710: 64 69 72 3b 0a 09 09 73 74 72 75 63 74 20 7b 0a dir;...struct {.
0720: 09 09 09 69 6e 74 20 65 78 65 63 75 74 61 62 6c ...int executabl
0730: 65 3b 0a 09 09 09 6f 66 66 5f 74 20 73 69 7a 65 e;....off_t size
0740: 3b 0a 09 09 7d 20 66 69 6c 65 3b 0a 09 09 73 74 ;...} file;...st
0750: 72 75 63 74 20 7b 0a 09 09 09 6f 66 66 5f 74 20 ruct {....off_t
0760: 73 69 7a 65 3b 0a 09 09 09 63 68 61 72 20 73 6f size;....char so
0770: 75 72 63 65 5b 32 35 36 5d 3b 0a 09 09 7d 20 73 urce[256];...} s
0780: 79 6d 6c 69 6e 6b 3b 0a 09 7d 20 74 79 70 65 69 ymlink;..} typei
0790: 6e 66 6f 3b 0a 0a 09 2f 2a 20 41 74 74 72 69 62 nfo;.../* Attrib
07a0: 75 74 65 73 20 75 73 65 64 20 6f 6e 6c 79 20 66 utes used only f
07b0: 6f 72 20 63 61 63 68 69 6e 67 20 65 6e 74 72 69 or caching entri
07c0: 65 73 20 2a 2f 0a 09 63 68 61 72 20 2a 5f 63 61 es */..char *_ca
07d0: 63 68 65 5f 70 61 74 68 3b 0a 09 75 69 64 5f 74 che_path;..uid_t
07e0: 20 5f 63 61 63 68 65 5f 75 69 64 3b 0a 7d 3b 0a _cache_uid;.};.
07f0: 0a 2f 2a 0a 20 2a 20 43 72 65 61 74 65 20 61 20 ./*. * Create a
0800: 6e 65 77 20 54 63 6c 20 69 6e 74 65 72 70 72 65 new Tcl interpre
0810: 74 65 72 20 61 6e 64 20 63 6f 6d 70 6c 65 74 65 ter and complete
0820: 6c 79 20 69 6e 69 74 69 61 6c 69 7a 65 20 69 74 ly initialize it
0830: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 54 63 6c 5f . */.static Tcl_
0840: 49 6e 74 65 72 70 20 2a 61 70 70 66 73 5f 63 72 Interp *appfs_cr
0850: 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 63 eate_TclInterp(c
0860: 68 61 72 20 2a 2a 65 72 72 6f 72 5f 73 74 72 69 har **error_stri
0870: 6e 67 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 ng) {..Tcl_Inter
0880: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 69 6e 74 20 p *interp;..int
0890: 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 tcl_ret;...APPFS
08a0: 5f 44 45 42 55 47 28 22 43 72 65 61 74 69 6e 67 _DEBUG("Creating
08b0: 20 6e 65 77 20 54 63 6c 20 69 6e 74 65 72 70 72 new Tcl interpr
08c0: 65 74 65 72 20 66 6f 72 20 54 49 44 20 3d 20 30 eter for TID = 0
08d0: 78 25 6c 6c 78 22 2c 20 28 75 6e 73 69 67 6e 65 x%llx", (unsigne
08e0: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 70 74 68 d long long) pth
08f0: 72 65 61 64 5f 73 65 6c 66 28 29 29 3b 0a 0a 09 read_self());...
0900: 69 6e 74 65 72 70 20 3d 20 54 63 6c 5f 43 72 65 interp = Tcl_Cre
0910: 61 74 65 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 ateInterp();..if
0920: 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c (interp == NULL
0930: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 ) {...fprintf(st
0940: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f derr, "Unable to
0950: 20 63 72 65 61 74 65 20 54 63 6c 20 49 6e 74 65 create Tcl Inte
0960: 72 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69 rpreter. Aborti
0970: 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 69 66 20 28 ng.\n");....if (
0980: 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a error_string) {.
0990: 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 ...*error_string
09a0: 20 3d 20 73 74 72 64 75 70 28 22 55 6e 61 62 6c = strdup("Unabl
09b0: 65 20 74 6f 20 63 72 65 61 74 65 20 54 63 6c 20 e to create Tcl
09c0: 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a interpreter.");.
09d0: 09 09 7d 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 ..}....return(NU
09e0: 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 LL);..}...tcl_re
09f0: 74 20 3d 20 54 63 6c 5f 49 6e 69 74 28 69 6e 74 t = Tcl_Init(int
0a00: 65 72 70 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 erp);..if (tcl_r
0a10: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a et != TCL_OK) {.
0a20: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 ..fprintf(stderr
0a30: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 , "Unable to ini
0a40: 74 69 61 6c 69 7a 65 20 54 63 6c 2e 20 20 41 62 tialize Tcl. Ab
0a50: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66 orting.\n");...f
0a60: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 printf(stderr, "
0a70: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 Tcl Error is: %s
0a80: 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 \n", Tcl_GetStri
0a90: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 ngResult(interp)
0aa0: 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 5f );....if (error_
0ab0: 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72 string) {....*er
0ac0: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 ror_string = str
0ad0: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e dup(Tcl_GetStrin
0ae0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 gResult(interp))
0af0: 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44 65 6c ;...}....Tcl_Del
0b00: 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 eteInterp(interp
0b10: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c );....return(NUL
0b20: 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 L);..}...tcl_ret
0b30: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 = Tcl_Eval(inte
0b40: 72 70 2c 20 22 70 61 63 6b 61 67 65 20 69 66 6e rp, "package ifn
0b50: 65 65 64 65 64 20 73 68 61 31 20 31 2e 30 20 5b eeded sha1 1.0 [
0b60: 6c 69 73 74 20 6c 6f 61 64 20 7b 7d 20 73 68 61 list load {} sha
0b70: 31 5d 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 1]");..if (tcl_r
0b80: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a et != TCL_OK) {.
0b90: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 ..fprintf(stderr
0ba0: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 , "Unable to ini
0bb0: 74 69 61 6c 69 7a 65 20 54 63 6c 20 53 48 41 31 tialize Tcl SHA1
0bc0: 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 . Aborting.\n")
0bd0: 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 ;...fprintf(stde
0be0: 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 rr, "Tcl Error i
0bf0: 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 s: %s\n", Tcl_Ge
0c00: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e tStringResult(in
0c10: 74 65 72 70 29 29 3b 0a 0a 09 09 69 66 20 28 65 terp));....if (e
0c20: 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 rror_string) {..
0c30: 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 ..*error_string
0c40: 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74 = strdup(Tcl_Get
0c50: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 StringResult(int
0c60: 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 erp));...}....Tc
0c70: 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 l_DeleteInterp(i
0c80: 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 nterp);....retur
0c90: 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63 n(NULL);..}...tc
0ca0: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c l_ret = Tcl_Eval
0cb0: 28 69 6e 74 65 72 70 2c 20 22 70 61 63 6b 61 67 (interp, "packag
0cc0: 65 20 69 66 6e 65 65 64 65 64 20 61 70 70 66 73 e ifneeded appfs
0cd0: 64 20 31 2e 30 20 5b 6c 69 73 74 20 6c 6f 61 64 d 1.0 [list load
0ce0: 20 7b 7d 20 61 70 70 66 73 64 5d 22 29 3b 0a 09 {} appfsd]");..
0cf0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 if (tcl_ret != T
0d00: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e CL_OK) {...fprin
0d10: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 tf(stderr, "Unab
0d20: 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 le to initialize
0d30: 20 54 63 6c 20 41 70 70 46 53 20 50 61 63 6b 61 Tcl AppFS Packa
0d40: 67 65 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e ge. Aborting.\n
0d50: 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 ");...fprintf(st
0d60: 64 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 derr, "Tcl Error
0d70: 20 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f is: %s\n", Tcl_
0d80: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 GetStringResult(
0d90: 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 69 66 20 interp));....if
0da0: 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b (error_string) {
0db0: 0a 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 69 6e ....*error_strin
0dc0: 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c 5f 47 g = strdup(Tcl_G
0dd0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 etStringResult(i
0de0: 6e 74 65 72 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 nterp));...}....
0df0: 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 Tcl_DeleteInterp
0e00: 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 72 65 74 (interp);....ret
0e10: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 urn(NULL);..}...
0e20: 2f 2a 0a 09 20 2a 20 4c 6f 61 64 20 22 70 6b 69 /*.. * Load "pki
0e30: 2e 74 63 6c 22 20 69 6e 20 74 68 65 20 73 61 6d .tcl" in the sam
0e40: 65 20 77 61 79 20 61 73 20 61 70 70 66 73 64 2e e way as appfsd.
0e50: 74 63 6c 20 28 73 65 65 20 62 65 6c 6f 77 29 0a tcl (see below).
0e60: 09 20 2a 2f 0a 09 74 63 6c 5f 72 65 74 20 3d 20 . */..tcl_ret =
0e70: 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c Tcl_Eval(interp,
0e80: 20 22 22 0a 23 69 6e 63 6c 75 64 65 20 22 70 6b "".#include "pk
0e90: 69 2e 74 63 6c 2e 68 22 0a 09 22 22 29 3b 0a 09 i.tcl.h".."");..
0ea0: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 if (tcl_ret != T
0eb0: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e CL_OK) {...fprin
0ec0: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 tf(stderr, "Unab
0ed0: 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 le to initialize
0ee0: 20 54 63 6c 20 50 4b 49 2e 20 20 41 62 6f 72 74 Tcl PKI. Abort
0ef0: 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69 ing.\n");...fpri
0f00: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c ntf(stderr, "Tcl
0f10: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 Error is: %s\n"
0f20: 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 , Tcl_GetStringR
0f30: 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a esult(interp));.
0f40: 0a 09 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 ...if (error_str
0f50: 69 6e 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 ing) {....*error
0f60: 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 _string = strdup
0f70: 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 (Tcl_GetStringRe
0f80: 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 sult(interp));..
0f90: 09 7d 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 .}....Tcl_Delete
0fa0: 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a Interp(interp);.
0fb0: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b ...return(NULL);
0fc0: 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4c 6f 61 ..}.../*.. * Loa
0fd0: 64 20 74 68 65 20 22 61 70 70 66 73 64 2e 74 63 d the "appfsd.tc
0fe0: 6c 22 20 73 63 72 69 70 74 2c 20 77 68 69 63 68 l" script, which
0ff0: 20 69 73 20 22 63 6f 6d 70 69 6c 65 64 22 20 69 is "compiled" i
1000: 6e 74 6f 20 61 20 43 20 68 65 61 64 65 72 0a 09 nto a C header..
1010: 20 2a 20 73 6f 20 74 68 61 74 20 69 74 20 64 6f * so that it do
1020: 65 73 20 6e 6f 74 20 6e 65 65 64 20 74 6f 20 65 es not need to e
1030: 78 69 73 74 20 6f 6e 20 74 68 65 20 66 69 6c 65 xist on the file
1040: 73 79 73 74 65 6d 20 61 6e 64 20 63 61 6e 20 62 system and can b
1050: 65 0a 09 20 2a 20 64 69 72 65 63 74 6c 79 20 65 e.. * directly e
1060: 76 61 6c 75 61 74 65 64 2e 0a 09 20 2a 2f 0a 09 valuated... */..
1070: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 tcl_ret = Tcl_Ev
1080: 61 6c 28 69 6e 74 65 72 70 2c 20 22 22 0a 23 69 al(interp, "".#i
1090: 6e 63 6c 75 64 65 20 22 61 70 70 66 73 64 2e 74 nclude "appfsd.t
10a0: 63 6c 2e 68 22 0a 09 22 22 29 3b 0a 09 69 66 20 cl.h".."");..if
10b0: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f (tcl_ret != TCL_
10c0: 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 OK) {...fprintf(
10d0: 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 stderr, "Unable
10e0: 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 to initialize Tc
10f0: 6c 20 41 70 70 46 53 20 73 63 72 69 70 74 2e 20 l AppFS script.
1100: 20 41 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a Aborting.\n");.
1110: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 ..fprintf(stderr
1120: 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a , "Tcl Error is:
1130: 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 %s\n", Tcl_GetS
1140: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 tringResult(inte
1150: 72 70 29 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 rp));....if (err
1160: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 or_string) {....
1170: 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 *error_string =
1180: 73 74 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 strdup(Tcl_GetSt
1190: 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 ringResult(inter
11a0: 70 29 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f p));...}....Tcl_
11b0: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 DeleteInterp(int
11c0: 65 72 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 erp);....return(
11d0: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 NULL);..}.../*..
11e0: 20 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 * Set global va
11f0: 72 69 61 62 6c 65 73 20 66 72 6f 6d 20 43 20 74 riables from C t
1200: 6f 20 54 63 6c 0a 09 20 2a 2f 0a 09 69 66 20 28 o Tcl.. */..if (
1210: 54 63 6c 5f 53 65 74 56 61 72 28 69 6e 74 65 72 Tcl_SetVar(inter
1220: 70 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 63 61 63 p, "::appfs::cac
1230: 68 65 64 69 72 22 2c 20 61 70 70 66 73 5f 63 61 hedir", appfs_ca
1240: 63 68 65 64 69 72 2c 20 54 43 4c 5f 47 4c 4f 42 chedir, TCL_GLOB
1250: 41 4c 5f 4f 4e 4c 59 29 20 3d 3d 20 4e 55 4c 4c AL_ONLY) == NULL
1260: 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 ) {...fprintf(st
1270: 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f derr, "Unable to
1280: 20 73 65 74 20 63 61 63 68 65 20 64 69 72 65 63 set cache direc
1290: 74 6f 72 79 2e 20 20 54 68 69 73 20 73 68 6f 75 tory. This shou
12a0: 6c 64 20 6e 65 76 65 72 20 66 61 69 6c 2e 5c 6e ld never fail.\n
12b0: 22 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f 72 ");....if (error
12c0: 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a 65 _string) {....*e
12d0: 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 rror_string = st
12e0: 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 rdup(Tcl_GetStri
12f0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 ngResult(interp)
1300: 29 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44 65 );...}....Tcl_De
1310: 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 leteInterp(inter
1320: 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 p);....return(NU
1330: 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a LL);..}.../*.. *
1340: 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 Initialize the
1350: 22 61 70 70 66 73 64 2e 74 63 6c 22 20 65 6e 76 "appfsd.tcl" env
1360: 69 72 6f 6e 6d 65 6e 74 2c 20 77 68 69 63 68 20 ironment, which
1370: 6d 75 73 74 20 62 65 20 64 6f 6e 65 20 61 66 74 must be done aft
1380: 65 72 0a 09 20 2a 20 67 6c 6f 62 61 6c 20 76 61 er.. * global va
1390: 72 69 61 62 6c 65 73 20 61 72 65 20 73 65 74 2e riables are set.
13a0: 0a 09 20 2a 2f 0a 09 74 63 6c 5f 72 65 74 20 3d .. */..tcl_ret =
13b0: 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 Tcl_Eval(interp
13c0: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 69 6e 69 74 , "::appfs::init
13d0: 22 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 ");..if (tcl_ret
13e0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 != TCL_OK) {...
13f0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 fprintf(stderr,
1400: 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 "Unable to initi
1410: 61 6c 69 7a 65 20 54 63 6c 20 41 70 70 46 53 20 alize Tcl AppFS
1420: 73 63 72 69 70 74 20 28 3a 3a 61 70 70 66 73 3a script (::appfs:
1430: 3a 69 6e 69 74 29 2e 20 20 41 62 6f 72 74 69 6e :init). Abortin
1440: 67 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 g.\n");...fprint
1450: 66 28 73 74 64 65 72 72 2c 20 22 54 63 6c 20 45 f(stderr, "Tcl E
1460: 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e 22 2c 20 rror is: %s\n",
1470: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 Tcl_GetStringRes
1480: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 ult(interp));...
1490: 09 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e .if (error_strin
14a0: 67 29 20 7b 0a 09 09 09 2a 65 72 72 6f 72 5f 73 g) {....*error_s
14b0: 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 tring = strdup(T
14c0: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 cl_GetStringResu
14d0: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 7d lt(interp));...}
14e0: 0a 0a 09 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e ....Tcl_DeleteIn
14f0: 74 65 72 70 28 69 6e 74 65 72 70 29 3b 0a 0a 09 terp(interp);...
1500: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 .return(NULL);..
1510: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 48 69 64 65 20 }.../*.. * Hide
1520: 73 6f 6d 65 20 54 63 6c 20 63 6f 6d 6d 61 6e 64 some Tcl command
1530: 73 20 74 68 61 74 20 77 65 20 64 6f 20 6e 6f 74 s that we do not
1540: 20 63 61 72 65 20 74 6f 20 75 73 65 20 61 6e 64 care to use and
1550: 20 77 68 69 63 68 20 6d 61 79 0a 09 20 2a 20 73 which may.. * s
1560: 6c 6f 77 20 64 6f 77 6e 20 72 75 6e 2d 74 69 6d low down run-tim
1570: 65 20 6f 70 65 72 61 74 69 6f 6e 73 2e 0a 09 20 e operations...
1580: 2a 2f 0a 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d */..Tcl_HideComm
1590: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 75 74 and(interp, "aut
15a0: 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22 2c 20 22 o_load_index", "
15b0: 61 75 74 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22 auto_load_index"
15c0: 29 3b 0a 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d );..Tcl_HideComm
15d0: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 75 6e 6b and(interp, "unk
15e0: 6e 6f 77 6e 22 2c 20 22 75 6e 6b 6e 6f 77 6e 22 nown", "unknown"
15f0: 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 74 75 );.../*.. * Retu
1600: 72 6e 20 74 68 65 20 63 6f 6d 70 6c 65 74 65 6c rn the completel
1610: 79 20 69 6e 69 74 69 61 6c 69 7a 65 64 20 69 6e y initialized in
1620: 74 65 72 70 72 65 74 65 72 0a 09 20 2a 2f 0a 09 terpreter.. */..
1630: 72 65 74 75 72 6e 28 69 6e 74 65 72 70 29 3b 0a return(interp);.
1640: 7d 0a 0a 2f 2a 0a 20 2a 20 52 65 74 75 72 6e 20 }../*. * Return
1650: 74 68 65 20 74 68 72 65 61 64 2d 73 70 65 63 69 the thread-speci
1660: 66 69 63 20 54 63 6c 20 69 6e 74 65 72 70 72 65 fic Tcl interpre
1670: 74 65 72 2c 20 63 72 65 61 74 69 6e 67 20 69 74 ter, creating it
1680: 20 69 66 20 6e 65 65 64 65 64 0a 20 2a 2f 0a 73 if needed. */.s
1690: 74 61 74 69 63 20 54 63 6c 5f 49 6e 74 65 72 70 tatic Tcl_Interp
16a0: 20 2a 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 *appfs_TclInter
16b0: 70 28 76 6f 69 64 29 20 7b 0a 09 54 63 6c 5f 49 p(void) {..Tcl_I
16c0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 nterp *interp;..
16d0: 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b int pthread_ret;
16e0: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 70 74 68 72 ...interp = pthr
16f0: 65 61 64 5f 67 65 74 73 70 65 63 69 66 69 63 28 ead_getspecific(
1700: 69 6e 74 65 72 70 4b 65 79 29 3b 0a 09 69 66 20 interpKey);..if
1710: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 (interp == NULL)
1720: 20 7b 0a 09 09 69 6e 74 65 72 70 20 3d 20 61 70 {...interp = ap
1730: 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e pfs_create_TclIn
1740: 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 0a 09 09 69 terp(NULL);....i
1750: 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c f (interp == NUL
1760: 4c 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 4e L) {....return(N
1770: 55 4c 4c 29 3b 0a 09 09 7d 0a 0a 09 09 70 74 68 ULL);...}....pth
1780: 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 read_ret = pthre
1790: 61 64 5f 73 65 74 73 70 65 63 69 66 69 63 28 69 ad_setspecific(i
17a0: 6e 74 65 72 70 4b 65 79 2c 20 69 6e 74 65 72 70 nterpKey, interp
17b0: 29 3b 0a 09 09 69 66 20 28 70 74 68 72 65 61 64 );...if (pthread
17c0: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 _ret != 0) {....
17d0: 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 Tcl_DeleteInterp
17e0: 28 69 6e 74 65 72 70 29 3b 0a 0a 09 09 09 72 65 (interp);.....re
17f0: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a turn(NULL);...}.
1800: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 69 6e 74 65 .}...return(inte
1810: 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 76 rp);.}../*. * Ev
1820: 61 6c 75 61 74 65 20 61 20 54 63 6c 20 73 63 72 aluate a Tcl scr
1830: 69 70 74 20 63 6f 6e 73 74 72 75 63 74 65 64 20 ipt constructed
1840: 62 79 20 63 6f 6e 63 61 74 65 6e 61 74 69 6e 67 by concatenating
1850: 20 61 20 62 75 6e 63 68 20 6f 66 20 43 20 73 74 a bunch of C st
1860: 72 69 6e 67 73 0a 20 2a 20 74 6f 67 65 74 68 65 rings. * togethe
1870: 72 2e 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e r.. */.static in
1880: 74 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c t appfs_Tcl_Eval
1890: 28 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 (Tcl_Interp *int
18a0: 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 63 erp, int objc, c
18b0: 6f 6e 73 74 20 63 68 61 72 20 2a 63 6d 64 2c 20 onst char *cmd,
18c0: 2e 2e 2e 29 20 7b 0a 09 54 63 6c 5f 4f 62 6a 20 ...) {..Tcl_Obj
18d0: 2a 2a 6f 62 6a 76 3b 0a 09 63 6f 6e 73 74 20 63 **objv;..const c
18e0: 68 61 72 20 2a 61 72 67 3b 0a 09 76 61 5f 6c 69 har *arg;..va_li
18f0: 73 74 20 61 72 67 70 3b 0a 09 69 6e 74 20 72 65 st argp;..int re
1900: 74 76 61 6c 3b 0a 09 69 6e 74 20 69 3b 0a 0a 09 tval;..int i;...
1910: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 if (interp == NU
1920: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 54 LL) {...return(T
1930: 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09 CL_ERROR);..}...
1940: 6f 62 6a 76 20 3d 20 28 76 6f 69 64 20 2a 29 20 objv = (void *)
1950: 63 6b 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 2a ckalloc(sizeof(*
1960: 6f 62 6a 76 29 20 2a 20 6f 62 6a 63 29 3b 0a 09 objv) * objc);..
1970: 6f 62 6a 76 5b 30 5d 20 3d 20 54 63 6c 5f 4e 65 objv[0] = Tcl_Ne
1980: 77 53 74 72 69 6e 67 4f 62 6a 28 63 6d 64 2c 20 wStringObj(cmd,
1990: 2d 31 29 3b 0a 09 54 63 6c 5f 49 6e 63 72 52 65 -1);..Tcl_IncrRe
19a0: 66 43 6f 75 6e 74 28 6f 62 6a 76 5b 30 5d 29 3b fCount(objv[0]);
19b0: 0a 0a 09 76 61 5f 73 74 61 72 74 28 61 72 67 70 ...va_start(argp
19c0: 2c 20 63 6d 64 29 3b 0a 09 66 6f 72 20 28 69 20 , cmd);..for (i
19d0: 3d 20 31 3b 20 69 20 3c 20 6f 62 6a 63 3b 20 69 = 1; i < objc; i
19e0: 2b 2b 29 20 7b 0a 09 09 61 72 67 20 3d 20 76 61 ++) {...arg = va
19f0: 5f 61 72 67 28 61 72 67 70 2c 20 63 6f 6e 73 74 _arg(argp, const
1a00: 20 63 68 61 72 20 2a 29 3b 0a 09 09 6f 62 6a 76 char *);...objv
1a10: 5b 69 5d 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 [i] = Tcl_NewStr
1a20: 69 6e 67 4f 62 6a 28 61 72 67 2c 20 2d 31 29 3b ingObj(arg, -1);
1a30: 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f ...Tcl_IncrRefCo
1a40: 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09 7d unt(objv[i]);..}
1a50: 0a 09 76 61 5f 65 6e 64 28 61 72 67 70 29 3b 0a ..va_end(argp);.
1a60: 0a 09 72 65 74 76 61 6c 20 3d 20 54 63 6c 5f 45 ..retval = Tcl_E
1a70: 76 61 6c 4f 62 6a 76 28 69 6e 74 65 72 70 2c 20 valObjv(interp,
1a80: 6f 62 6a 63 2c 20 6f 62 6a 76 2c 20 30 29 3b 0a objc, objv, 0);.
1a90: 0a 09 66 6f 72 20 28 69 20 3d 20 30 3b 20 69 20 ..for (i = 0; i
1aa0: 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29 20 7b 0a 09 < objc; i++) {..
1ab0: 09 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e .Tcl_DecrRefCoun
1ac0: 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09 7d 0a 0a t(objv[i]);..}..
1ad0: 09 63 6b 66 72 65 65 28 28 76 6f 69 64 20 2a 29 .ckfree((void *)
1ae0: 20 6f 62 6a 76 29 3b 0a 0a 09 69 66 20 28 72 65 objv);...if (re
1af0: 74 76 61 6c 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 tval != TCL_OK)
1b00: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 {...APPFS_DEBUG(
1b10: 22 54 63 6c 20 63 6f 6d 6d 61 6e 64 20 66 61 69 "Tcl command fai
1b20: 6c 65 64 2c 20 3a 3a 65 72 72 6f 72 49 6e 66 6f led, ::errorInfo
1b30: 20 63 6f 6e 74 61 69 6e 73 3a 20 25 73 5c 6e 22 contains: %s\n"
1b40: 2c 20 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 , Tcl_GetVar(int
1b50: 65 72 70 2c 20 22 3a 3a 65 72 72 6f 72 49 6e 66 erp, "::errorInf
1b60: 6f 22 2c 20 30 29 29 3b 0a 09 7d 0a 0a 09 72 65 o", 0));..}...re
1b70: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a turn(retval);.}.
1b80: 0a 2f 2a 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65 ./*. * Determine
1b90: 20 74 68 65 20 55 49 44 20 66 6f 72 20 74 68 65 the UID for the
1ba0: 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 user making the
1bb0: 20 63 75 72 72 65 6e 74 20 46 55 53 45 20 66 69 current FUSE fi
1bc0: 6c 65 73 79 73 74 65 6d 20 72 65 71 75 65 73 74 lesystem request
1bd0: 2e 0a 20 2a 20 54 68 69 73 20 77 69 6c 6c 20 62 .. * This will b
1be0: 65 20 75 73 65 64 20 74 6f 20 6c 6f 6f 6b 75 70 e used to lookup
1bf0: 20 74 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 the user's home
1c00: 20 64 69 72 65 63 74 6f 72 79 20 73 6f 20 77 65 directory so we
1c10: 20 63 61 6e 20 73 65 61 72 63 68 20 66 6f 72 0a can search for.
1c20: 20 2a 20 6c 6f 63 61 6c 6c 79 20 6d 6f 64 69 66 * locally modif
1c30: 69 65 64 20 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73 ied files.. */.s
1c40: 74 61 74 69 63 20 75 69 64 5f 74 20 61 70 70 66 tatic uid_t appf
1c50: 73 5f 67 65 74 5f 66 73 75 69 64 28 76 6f 69 64 s_get_fsuid(void
1c60: 29 20 7b 0a 09 73 74 72 75 63 74 20 66 75 73 65 ) {..struct fuse
1c70: 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78 3b 0a 0a _context *ctx;..
1c80: 09 69 66 20 28 21 61 70 70 66 73 5f 66 75 73 65 .if (!appfs_fuse
1c90: 5f 73 74 61 72 74 65 64 29 20 7b 0a 09 09 72 65 _started) {...re
1ca0: 74 75 72 6e 28 67 65 74 75 69 64 28 29 29 3b 0a turn(getuid());.
1cb0: 09 7d 0a 0a 09 63 74 78 20 3d 20 66 75 73 65 5f .}...ctx = fuse_
1cc0: 67 65 74 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09 get_context();..
1cd0: 69 66 20 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 if (ctx == NULL)
1ce0: 20 7b 0a 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74 {.../* Unable t
1cf0: 6f 20 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f o lookup user fo
1d00: 72 20 73 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f r some reason */
1d10: 0a 09 09 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20 .../* Return an
1d20: 75 6e 70 72 69 76 69 6c 65 67 65 64 20 75 73 65 unprivileged use
1d30: 72 20 49 44 20 2a 2f 0a 09 09 72 65 74 75 72 6e r ID */...return
1d40: 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e (1);..}...return
1d50: 28 63 74 78 2d 3e 75 69 64 29 3b 0a 7d 0a 0a 2f (ctx->uid);.}../
1d60: 2a 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65 20 74 *. * Determine t
1d70: 68 65 20 47 49 44 20 66 6f 72 20 74 68 65 20 75 he GID for the u
1d80: 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 63 ser making the c
1d90: 75 72 72 65 6e 74 20 46 55 53 45 20 66 69 6c 65 urrent FUSE file
1da0: 73 79 73 74 65 6d 20 72 65 71 75 65 73 74 2e 0a system request..
1db0: 20 2a 20 54 68 69 73 20 77 69 6c 6c 20 62 65 20 * This will be
1dc0: 75 73 65 64 20 74 6f 20 6c 6f 6f 6b 75 70 20 74 used to lookup t
1dd0: 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64 he user's home d
1de0: 69 72 65 63 74 6f 72 79 20 73 6f 20 77 65 20 63 irectory so we c
1df0: 61 6e 20 73 65 61 72 63 68 20 66 6f 72 0a 20 2a an search for. *
1e00: 20 6c 6f 63 61 6c 6c 79 20 6d 6f 64 69 66 69 65 locally modifie
1e10: 64 20 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73 74 61 d files.. */.sta
1e20: 74 69 63 20 67 69 64 5f 74 20 61 70 70 66 73 5f tic gid_t appfs_
1e30: 67 65 74 5f 66 73 67 69 64 28 76 6f 69 64 29 20 get_fsgid(void)
1e40: 7b 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f 63 {..struct fuse_c
1e50: 6f 6e 74 65 78 74 20 2a 63 74 78 3b 0a 0a 09 69 ontext *ctx;...i
1e60: 66 20 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73 f (!appfs_fuse_s
1e70: 74 61 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75 tarted) {...retu
1e80: 72 6e 28 67 65 74 67 69 64 28 29 29 3b 0a 09 7d rn(getgid());..}
1e90: 0a 0a 09 63 74 78 20 3d 20 66 75 73 65 5f 67 65 ...ctx = fuse_ge
1ea0: 74 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09 69 66 t_context();..if
1eb0: 20 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 20 7b (ctx == NULL) {
1ec0: 0a 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74 6f 20 .../* Unable to
1ed0: 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20 lookup user for
1ee0: 73 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f 0a 09 some reason */..
1ef0: 09 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20 75 6e ./* Return an un
1f00: 70 72 69 76 69 6c 65 67 65 64 20 75 73 65 72 20 privileged user
1f10: 49 44 20 2a 2f 0a 09 09 72 65 74 75 72 6e 28 31 ID */...return(1
1f20: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 63 );..}...return(c
1f30: 74 78 2d 3e 67 69 64 29 3b 0a 7d 0a 0a 73 74 61 tx->gid);.}..sta
1f40: 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 73 tic void appfs_s
1f50: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f imulate_user_fs_
1f60: 65 6e 74 65 72 28 76 6f 69 64 29 20 7b 0a 09 73 enter(void) {..s
1f70: 65 74 66 73 75 69 64 28 61 70 70 66 73 5f 67 65 etfsuid(appfs_ge
1f80: 74 5f 66 73 75 69 64 28 29 29 3b 0a 09 73 65 74 t_fsuid());..set
1f90: 66 73 67 69 64 28 61 70 70 66 73 5f 67 65 74 5f fsgid(appfs_get_
1fa0: 66 73 67 69 64 28 29 29 3b 0a 7d 0a 0a 73 74 61 fsgid());.}..sta
1fb0: 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 73 tic void appfs_s
1fc0: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f imulate_user_fs_
1fd0: 6c 65 61 76 65 28 76 6f 69 64 29 20 7b 0a 09 73 leave(void) {..s
1fe0: 65 74 66 73 75 69 64 28 30 29 3b 0a 09 73 65 74 etfsuid(0);..set
1ff0: 66 73 67 69 64 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a fsgid(0);.}../*.
2000: 20 2a 20 4c 6f 6f 6b 20 75 70 20 74 68 65 20 68 * Look up the h
2010: 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20 66 6f ome directory fo
2020: 72 20 61 20 67 69 76 65 6e 20 55 49 44 0a 20 2a r a given UID. *
2030: 20 20 20 20 20 20 20 20 52 65 74 75 72 6e 73 20 Returns
2040: 61 20 43 20 73 74 72 69 6e 67 20 63 6f 6e 74 61 a C string conta
2050: 69 6e 69 6e 67 20 74 68 65 20 75 73 65 72 27 73 ining the user's
2060: 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20 home directory
2070: 6f 72 20 4e 55 4c 4c 20 69 66 0a 20 2a 20 20 20 or NULL if. *
2080: 20 20 20 20 20 74 68 65 20 75 73 65 72 27 73 20 the user's
2090: 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 79 20 64 home directory d
20a0: 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20 6f 72 oes not exist or
20b0: 20 69 73 20 6e 6f 74 20 63 6f 72 72 65 63 74 6c is not correctl
20c0: 79 0a 20 2a 20 20 20 20 20 20 20 20 63 6f 6e 66 y. * conf
20d0: 69 67 75 72 65 64 0a 20 2a 2f 0a 73 74 61 74 69 igured. */.stati
20e0: 63 20 63 68 61 72 20 2a 61 70 70 66 73 5f 67 65 c char *appfs_ge
20f0: 74 5f 68 6f 6d 65 64 69 72 28 75 69 64 5f 74 20 t_homedir(uid_t
2100: 66 73 75 69 64 29 20 7b 0a 09 73 74 72 75 63 74 fsuid) {..struct
2110: 20 70 61 73 73 77 64 20 65 6e 74 72 79 2c 20 2a passwd entry, *
2120: 72 65 73 75 6c 74 3b 0a 09 73 74 72 75 63 74 20 result;..struct
2130: 73 74 61 74 20 73 74 62 75 66 3b 0a 09 63 68 61 stat stbuf;..cha
2140: 72 20 62 75 66 5b 31 30 32 34 5d 2c 20 2a 72 65 r buf[1024], *re
2150: 74 76 61 6c 3b 0a 09 69 6e 74 20 67 70 75 5f 72 tval;..int gpu_r
2160: 65 74 2c 20 73 74 61 74 5f 72 65 74 3b 0a 0a 09 et, stat_ret;...
2170: 67 70 75 5f 72 65 74 20 3d 20 67 65 74 70 77 75 gpu_ret = getpwu
2180: 69 64 5f 72 28 66 73 75 69 64 2c 20 26 65 6e 74 id_r(fsuid, &ent
2190: 72 79 2c 20 62 75 66 2c 20 73 69 7a 65 6f 66 28 ry, buf, sizeof(
21a0: 62 75 66 29 2c 20 26 72 65 73 75 6c 74 29 3b 0a buf), &result);.
21b0: 09 69 66 20 28 67 70 75 5f 72 65 74 20 21 3d 20 .if (gpu_ret !=
21c0: 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 0) {...APPFS_DEB
21d0: 55 47 28 22 67 65 74 70 77 75 69 64 5f 72 28 25 UG("getpwuid_r(%
21e0: 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 74 75 72 6e llu, ...) return
21f0: 65 64 20 69 6e 20 66 61 69 6c 75 72 65 22 2c 20 ed in failure",
2200: 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c (unsigned long l
2210: 6f 6e 67 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 ong) fsuid);....
2220: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d return(NULL);..}
2230: 0a 0a 09 69 66 20 28 72 65 73 75 6c 74 20 3d 3d ...if (result ==
2240: 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 NULL) {...APPFS
2250: 5f 44 45 42 55 47 28 22 67 65 74 70 77 75 69 64 _DEBUG("getpwuid
2260: 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 _r(%llu, ...) re
2270: 74 75 72 6e 65 64 20 4e 55 4c 4c 20 72 65 73 75 turned NULL resu
2280: 6c 74 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c lt", (unsigned l
2290: 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 ong long) fsuid)
22a0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c ;....return(NULL
22b0: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65 73 75 );..}...if (resu
22c0: 6c 74 2d 3e 70 77 5f 64 69 72 20 3d 3d 20 4e 55 lt->pw_dir == NU
22d0: 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 LL) {...APPFS_DE
22e0: 42 55 47 28 22 67 65 74 70 77 75 69 64 5f 72 28 BUG("getpwuid_r(
22f0: 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 74 75 72 %llu, ...) retur
2300: 6e 65 64 20 4e 55 4c 4c 20 68 6f 6d 65 20 64 69 ned NULL home di
2310: 72 65 63 74 6f 72 79 22 2c 20 28 75 6e 73 69 67 rectory", (unsig
2320: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 ned long long) f
2330: 73 75 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e suid);....return
2340: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 73 74 61 (NULL);..}...sta
2350: 74 5f 72 65 74 20 3d 20 73 74 61 74 28 72 65 73 t_ret = stat(res
2360: 75 6c 74 2d 3e 70 77 5f 64 69 72 2c 20 26 73 74 ult->pw_dir, &st
2370: 62 75 66 29 3b 0a 09 69 66 20 28 73 74 61 74 5f buf);..if (stat_
2380: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 ret != 0) {...AP
2390: 50 46 53 5f 44 45 42 55 47 28 22 73 74 61 74 28 PFS_DEBUG("stat(
23a0: 25 73 29 20 72 65 74 75 72 6e 65 64 20 69 6e 20 %s) returned in
23b0: 66 61 69 6c 75 72 65 22 2c 20 72 65 73 75 6c 74 failure", result
23c0: 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a 09 09 72 65 ->pw_dir);....re
23d0: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a turn(NULL);..}..
23e0: 09 69 66 20 28 73 74 62 75 66 2e 73 74 5f 75 69 .if (stbuf.st_ui
23f0: 64 20 21 3d 20 66 73 75 69 64 29 20 7b 0a 09 09 d != fsuid) {...
2400: 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 49 44 APPFS_DEBUG("UID
2410: 20 6d 69 73 2d 6d 61 74 63 68 20 6f 6e 20 75 73 mis-match on us
2420: 65 72 20 25 6c 6c 75 27 73 20 68 6f 6d 65 20 64 er %llu's home d
2430: 69 72 65 63 74 6f 72 79 20 28 25 73 29 2e 20 20 irectory (%s).
2440: 49 74 27 73 20 6f 77 6e 65 64 20 62 79 20 25 6c It's owned by %l
2450: 6c 75 2e 22 2c 0a 09 09 20 20 20 20 28 75 6e 73 lu.",... (uns
2460: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 igned long long)
2470: 20 66 73 75 69 64 2c 0a 09 09 20 20 20 20 72 65 fsuid,... re
2480: 73 75 6c 74 2d 3e 70 77 5f 64 69 72 2c 0a 09 09 sult->pw_dir,...
2490: 20 20 20 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f (unsigned lo
24a0: 6e 67 20 6c 6f 6e 67 29 20 73 74 62 75 66 2e 73 ng long) stbuf.s
24b0: 74 5f 75 69 64 0a 09 09 29 3b 0a 0a 09 09 72 65 t_uid...);....re
24c0: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a turn(NULL);..}..
24d0: 09 72 65 74 76 61 6c 20 3d 20 73 74 72 64 75 70 .retval = strdup
24e0: 28 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 29 (result->pw_dir)
24f0: 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 ;...return(retva
2500: 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 47 65 6e l);.}../*. * Gen
2510: 65 72 61 74 65 20 61 6e 20 69 6e 6f 64 65 20 66 erate an inode f
2520: 6f 72 20 61 20 67 69 76 65 6e 20 70 61 74 68 2e or a given path.
2530: 20 20 54 68 65 20 69 6e 6f 64 65 20 73 68 6f 75 The inode shou
2540: 6c 64 20 62 65 20 63 6f 6d 70 75 74 65 64 20 69 ld be computed i
2550: 6e 20 73 75 63 68 0a 20 2a 20 61 20 77 61 79 20 n such. * a way
2560: 74 68 61 74 20 69 74 20 69 73 20 75 6e 6c 69 6b that it is unlik
2570: 65 6c 79 20 74 6f 20 62 65 20 64 75 70 6c 69 63 ely to be duplic
2580: 61 74 65 64 20 61 6e 64 20 72 65 6d 61 69 6e 73 ated and remains
2590: 20 74 68 65 20 73 61 6d 65 20 66 6f 72 20 61 20 the same for a
25a0: 67 69 76 65 6e 0a 20 2a 20 66 69 6c 65 0a 20 2a given. * file. *
25b0: 2f 0a 73 74 61 74 69 63 20 6c 6f 6e 67 20 6c 6f /.static long lo
25c0: 6e 67 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 ng appfs_get_pat
25d0: 68 5f 69 6e 6f 64 65 28 63 6f 6e 73 74 20 63 68 h_inode(const ch
25e0: 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 6c 6f 6e ar *path) {..lon
25f0: 67 20 6c 6f 6e 67 20 72 65 74 76 61 6c 3b 0a 09 g long retval;..
2600: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 3b 0a 0a const char *p;..
2610: 09 72 65 74 76 61 6c 20 3d 20 31 30 3b 0a 0a 09 .retval = 10;...
2620: 66 6f 72 20 28 70 20 3d 20 70 61 74 68 3b 20 2a for (p = path; *
2630: 70 3b 20 70 2b 2b 29 20 7b 0a 09 09 72 65 74 76 p; p++) {...retv
2640: 61 6c 20 25 3d 20 34 32 39 30 39 36 30 32 39 30 al %= 4290960290
2650: 55 4c 4c 3b 0a 09 09 72 65 74 76 61 6c 20 2b 3d ULL;...retval +=
2660: 20 2a 70 3b 0a 09 09 72 65 74 76 61 6c 20 3c 3c *p;...retval <<
2670: 3d 20 37 3b 0a 09 7d 0a 0a 09 72 65 74 76 61 6c = 7;..}...retval
2680: 20 2b 3d 20 31 30 3b 0a 09 72 65 74 76 61 6c 20 += 10;..retval
2690: 25 3d 20 34 32 39 34 39 36 37 32 39 36 55 4c 4c %= 4294967296ULL
26a0: 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 ;...return(retva
26b0: 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 61 63 l);.}../*. * Cac
26c0: 68 65 20 47 65 74 20 50 61 74 68 20 49 6e 66 6f he Get Path Info
26d0: 20 6c 6f 6f 6b 75 70 73 20 66 6f 72 20 73 70 65 lookups for spe
26e0: 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e ed. */.static in
26f0: 74 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 t appfs_get_path
2700: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28 _info_cache_get(
2710: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 const char *path
2720: 2c 20 75 69 64 5f 74 20 75 69 64 2c 20 73 74 72 , uid_t uid, str
2730: 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e uct appfs_pathin
2740: 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a fo *pathinfo) {.
2750: 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61 .unsigned int ha
2760: 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 sh_idx;..int pth
2770: 72 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20 72 read_ret;..int r
2780: 65 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 etval;...retval
2790: 3d 20 31 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 = 1;...pthread_r
27a0: 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 et = pthread_mut
27b0: 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 ex_lock(&appfs_p
27c0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d ath_info_cache_m
27d0: 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 utex);..if (pthr
27e0: 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a ead_ret != 0) {.
27f0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 ..APPFS_DEBUG("U
2800: 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 nable to lock pa
2810: 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 th_info cache mu
2820: 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 tex !");....retu
2830: 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 rn(-1);..}...if
2840: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f (appfs_path_info
2850: 5f 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 _cache != NULL)
2860: 7b 0a 09 09 68 61 73 68 5f 69 64 78 20 3d 20 28 {...hash_idx = (
2870: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 appfs_get_path_i
2880: 6e 6f 64 65 28 70 61 74 68 29 20 2b 20 75 69 64 node(path) + uid
2890: 29 20 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69 ) % appfs_path_i
28a0: 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a nfo_cache_size;.
28b0: 0a 09 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 ...if (appfs_pat
28c0: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 h_info_cache[has
28d0: 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 h_idx]._cache_pa
28e0: 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 th != NULL) {...
28f0: 09 69 66 20 28 73 74 72 63 6d 70 28 61 70 70 66 .if (strcmp(appf
2900: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 s_path_info_cach
2910: 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 e[hash_idx]._cac
2920: 68 65 5f 70 61 74 68 2c 20 70 61 74 68 29 20 3d he_path, path) =
2930: 3d 20 30 20 26 26 20 61 70 70 66 73 5f 70 61 74 = 0 && appfs_pat
2940: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 h_info_cache[has
2950: 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 75 69 h_idx]._cache_ui
2960: 64 20 3d 3d 20 75 69 64 29 20 7b 0a 09 09 09 09 d == uid) {.....
2970: 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 09 09 retval = 0;.....
2980: 09 6d 65 6d 63 70 79 28 70 61 74 68 69 6e 66 6f .memcpy(pathinfo
2990: 2c 20 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e , &appfs_path_in
29a0: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 fo_cache[hash_id
29b0: 78 5d 2c 20 73 69 7a 65 6f 66 28 2a 70 61 74 68 x], sizeof(*path
29c0: 69 6e 66 6f 29 29 3b 0a 09 09 09 09 70 61 74 68 info));.....path
29d0: 69 6e 66 6f 2d 3e 5f 63 61 63 68 65 5f 70 61 74 info->_cache_pat
29e0: 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09 h = NULL;....}..
29f0: 09 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f .}..}...pthread_
2a00: 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 ret = pthread_mu
2a10: 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 tex_unlock(&appf
2a20: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 s_path_info_cach
2a30: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 e_mutex);..if (p
2a40: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 thread_ret != 0)
2a50: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 {...APPFS_DEBUG
2a60: 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f ("Unable to unlo
2a70: 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 ck path_info cac
2a80: 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 he mutex !");...
2a90: 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a .return(-1);..}.
2aa0: 0a 09 69 66 20 28 72 65 74 76 61 6c 20 3d 3d 20 ..if (retval ==
2ab0: 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 0) {...APPFS_DEB
2ac0: 55 47 28 22 43 61 63 68 65 20 68 69 74 20 6f 6e UG("Cache hit on
2ad0: 20 25 73 22 2c 20 70 61 74 68 29 3b 0a 09 7d 20 %s", path);..}
2ae0: 65 6c 73 65 20 7b 0a 09 09 41 50 50 46 53 5f 44 else {...APPFS_D
2af0: 45 42 55 47 28 22 43 61 63 68 65 20 6d 69 73 73 EBUG("Cache miss
2b00: 20 6f 6e 20 25 73 22 2c 20 70 61 74 68 29 3b 0a on %s", path);.
2b10: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 76 .}...return(retv
2b20: 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 al);.}..static v
2b30: 6f 69 64 20 61 70 70 66 73 5f 67 65 74 5f 70 61 oid appfs_get_pa
2b40: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64 th_info_cache_ad
2b50: 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 d(const char *pa
2b60: 74 68 2c 20 75 69 64 5f 74 20 75 69 64 2c 20 73 th, uid_t uid, s
2b70: 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 truct appfs_path
2b80: 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66 6f 29 20 info *pathinfo)
2b90: 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 {..unsigned int
2ba0: 68 61 73 68 5f 69 64 78 3b 0a 09 69 6e 74 20 70 hash_idx;..int p
2bb0: 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 70 74 thread_ret;...pt
2bc0: 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 hread_ret = pthr
2bd0: 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 ead_mutex_lock(&
2be0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f appfs_path_info_
2bf0: 63 61 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 cache_mutex);..i
2c00: 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 f (pthread_ret !
2c10: 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 = 0) {...APPFS_D
2c20: 45 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 EBUG("Unable to
2c30: 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 lock path_info c
2c40: 61 63 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a ache mutex !");.
2c50: 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 ...return;..}...
2c60: 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 if (appfs_path_i
2c70: 6e 66 6f 5f 63 61 63 68 65 20 3d 3d 20 4e 55 4c nfo_cache == NUL
2c80: 4c 29 20 7b 0a 09 09 61 70 70 66 73 5f 70 61 74 L) {...appfs_pat
2c90: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20 63 h_info_cache = c
2ca0: 61 6c 6c 6f 63 28 61 70 70 66 73 5f 70 61 74 68 alloc(appfs_path
2cb0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 _info_cache_size
2cc0: 2c 20 73 69 7a 65 6f 66 28 2a 61 70 70 66 73 5f , sizeof(*appfs_
2cd0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 29 path_info_cache)
2ce0: 29 3b 0a 09 7d 0a 0a 09 68 61 73 68 5f 69 64 78 );..}...hash_idx
2cf0: 20 3d 20 28 61 70 70 66 73 5f 67 65 74 5f 70 61 = (appfs_get_pa
2d00: 74 68 5f 69 6e 6f 64 65 28 70 61 74 68 29 20 2b th_inode(path) +
2d10: 20 75 69 64 29 20 25 20 61 70 70 66 73 5f 70 61 uid) % appfs_pa
2d20: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 th_info_cache_si
2d30: 7a 65 3b 0a 0a 09 69 66 20 28 61 70 70 66 73 5f ze;...if (appfs_
2d40: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b path_info_cache[
2d50: 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 hash_idx]._cache
2d60: 5f 70 61 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b _path != NULL) {
2d70: 0a 09 09 66 72 65 65 28 61 70 70 66 73 5f 70 61 ...free(appfs_pa
2d80: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 th_info_cache[ha
2d90: 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 sh_idx]._cache_p
2da0: 61 74 68 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 63 70 ath);..}...memcp
2db0: 79 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e y(&appfs_path_in
2dc0: 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 fo_cache[hash_id
2dd0: 78 5d 2c 20 70 61 74 68 69 6e 66 6f 2c 20 73 69 x], pathinfo, si
2de0: 7a 65 6f 66 28 2a 70 61 74 68 69 6e 66 6f 29 29 zeof(*pathinfo))
2df0: 3b 0a 0a 09 61 70 70 66 73 5f 70 61 74 68 5f 69 ;...appfs_path_i
2e00: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 nfo_cache[hash_i
2e10: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 dx]._cache_path
2e20: 3d 20 73 74 72 64 75 70 28 70 61 74 68 29 3b 0a = strdup(path);.
2e30: 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f .appfs_path_info
2e40: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d _cache[hash_idx]
2e50: 2e 5f 63 61 63 68 65 5f 75 69 64 20 20 3d 20 75 ._cache_uid = u
2e60: 69 64 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 id;...pthread_re
2e70: 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 t = pthread_mute
2e80: 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f x_unlock(&appfs_
2e90: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f path_info_cache_
2ea0: 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 mutex);..if (pth
2eb0: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b read_ret != 0) {
2ec0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 ...APPFS_DEBUG("
2ed0: 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b Unable to unlock
2ee0: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 path_info cache
2ef0: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 mutex !");....r
2f00: 65 74 75 72 6e 3b 0a 09 7d 0a 09 72 65 74 75 72 eturn;..}..retur
2f10: 6e 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 n;.}..static voi
2f20: 64 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 d appfs_get_path
2f30: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 63 _info_cache_rm(c
2f40: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c onst char *path,
2f50: 20 75 69 64 5f 74 20 75 69 64 29 20 7b 0a 09 75 uid_t uid) {..u
2f60: 6e 73 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68 nsigned int hash
2f70: 5f 69 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 _idx;..int pthre
2f80: 61 64 5f 72 65 74 3b 0a 0a 09 70 74 68 72 65 61 ad_ret;...pthrea
2f90: 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f d_ret = pthread_
2fa0: 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 mutex_lock(&appf
2fb0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 s_path_info_cach
2fc0: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 e_mutex);..if (p
2fd0: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 thread_ret != 0)
2fe0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 {...APPFS_DEBUG
2ff0: 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b ("Unable to lock
3000: 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 path_info cache
3010: 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 mutex !");....r
3020: 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28 eturn;..}...if (
3030: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f appfs_path_info_
3040: 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 20 7b cache != NULL) {
3050: 0a 09 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61 ...hash_idx = (a
3060: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e ppfs_get_path_in
3070: 6f 64 65 28 70 61 74 68 29 20 2b 20 75 69 64 29 ode(path) + uid)
3080: 20 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e % appfs_path_in
3090: 66 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a fo_cache_size;..
30a0: 09 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 ..if (appfs_path
30b0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 _info_cache[hash
30c0: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 _idx]._cache_pat
30d0: 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 h != NULL) {....
30e0: 66 72 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f free(appfs_path_
30f0: 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f info_cache[hash_
3100: 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 idx]._cache_path
3110: 29 3b 0a 0a 09 09 09 61 70 70 66 73 5f 70 61 74 );.....appfs_pat
3120: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 h_info_cache[has
3130: 68 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 h_idx]._cache_pa
3140: 74 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 7d 0a 09 th = NULL;...}..
3150: 7d 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 }...pthread_ret
3160: 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f = pthread_mutex_
3170: 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 unlock(&appfs_pa
3180: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 th_info_cache_mu
3190: 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 tex);..if (pthre
31a0: 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 ad_ret != 0) {..
31b0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e .APPFS_DEBUG("Un
31c0: 61 62 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 able to unlock p
31d0: 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d ath_info cache m
31e0: 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 utex !");....ret
31f0: 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e urn;..}...return
3200: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 ;.}..static void
3210: 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f appfs_get_path_
3220: 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 info_cache_flush
3230: 28 75 69 64 5f 74 20 75 69 64 2c 20 69 6e 74 20 (uid_t uid, int
3240: 6e 65 77 5f 73 69 7a 65 29 20 7b 0a 09 75 6e 73 new_size) {..uns
3250: 69 67 6e 65 64 20 69 6e 74 20 69 64 78 3b 0a 09 igned int idx;..
3260: 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b int pthread_ret;
3270: 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d ...pthread_ret =
3280: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c pthread_mutex_l
3290: 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f ock(&appfs_path_
32a0: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 info_cache_mutex
32b0: 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f );..if (pthread_
32c0: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 ret != 0) {...AP
32d0: 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c PFS_DEBUG("Unabl
32e0: 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69 e to lock path_i
32f0: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 nfo cache mutex
3300: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a !");....return;.
3310: 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 70 .}...if (appfs_p
3320: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 20 21 ath_info_cache !
3330: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 6f 72 20 = NULL) {...for
3340: 28 69 64 78 20 3d 20 30 3b 20 69 64 78 20 3c 20 (idx = 0; idx <
3350: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f appfs_path_info_
3360: 63 61 63 68 65 5f 73 69 7a 65 3b 20 69 64 78 2b cache_size; idx+
3370: 2b 29 20 7b 0a 09 09 09 69 66 20 28 61 70 70 66 +) {....if (appf
3380: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 s_path_info_cach
3390: 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 e[idx]._cache_pa
33a0: 74 68 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 th != NULL) {...
33b0: 09 09 69 66 20 28 75 69 64 20 21 3d 20 28 28 75 ..if (uid != ((u
33c0: 69 64 5f 74 29 20 2d 31 29 29 20 7b 0a 09 09 09 id_t) -1)) {....
33d0: 09 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 ..if (appfs_path
33e0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d _info_cache[idx]
33f0: 2e 5f 63 61 63 68 65 5f 75 69 64 20 21 3d 20 75 ._cache_uid != u
3400: 69 64 29 20 7b 0a 09 09 09 09 09 09 63 6f 6e 74 id) {.......cont
3410: 69 6e 75 65 3b 0a 09 09 09 09 09 7d 0a 09 09 09 inue;......}....
3420: 09 7d 0a 0a 09 09 09 09 66 72 65 65 28 61 70 70 .}......free(app
3430: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 fs_path_info_cac
3440: 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 he[idx]._cache_p
3450: 61 74 68 29 3b 0a 0a 09 09 09 09 61 70 70 66 73 ath);......appfs
3460: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 _path_info_cache
3470: 5b 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 [idx]._cache_pat
3480: 68 20 3d 20 4e 55 4c 4c 3b 0a 09 09 09 7d 0a 09 h = NULL;....}..
3490: 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 75 69 64 20 .}..}...if (uid
34a0: 3d 3d 20 28 28 75 69 64 5f 74 29 20 2d 31 29 29 == ((uid_t) -1))
34b0: 20 7b 0a 09 09 66 72 65 65 28 61 70 70 66 73 5f {...free(appfs_
34c0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 29 path_info_cache)
34d0: 3b 0a 0a 09 09 61 70 70 66 73 5f 70 61 74 68 5f ;....appfs_path_
34e0: 69 6e 66 6f 5f 63 61 63 68 65 20 3d 20 4e 55 4c info_cache = NUL
34f0: 4c 3b 0a 0a 09 09 69 66 20 28 6e 65 77 5f 73 69 L;....if (new_si
3500: 7a 65 20 21 3d 20 2d 31 29 20 7b 0a 09 09 09 61 ze != -1) {....a
3510: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 ppfs_path_info_c
3520: 61 63 68 65 5f 73 69 7a 65 20 3d 20 6e 65 77 5f ache_size = new_
3530: 73 69 7a 65 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 70 size;...}..}...p
3540: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 thread_ret = pth
3550: 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 read_mutex_unloc
3560: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e k(&appfs_path_in
3570: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b fo_cache_mutex);
3580: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 ..if (pthread_re
3590: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 t != 0) {...APPF
35a0: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 S_DEBUG("Unable
35b0: 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 to unlock path_i
35c0: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 nfo cache mutex
35d0: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a !");....return;.
35e0: 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a .}...return;.}..
35f0: 2f 2a 20 47 65 74 20 69 6e 66 6f 72 6d 61 74 69 /* Get informati
3600: 6f 6e 20 61 62 6f 75 74 20 61 20 70 61 74 68 2c on about a path,
3610: 20 61 6e 64 20 6f 70 74 69 6f 6e 61 6c 6c 79 20 and optionally
3620: 6c 69 73 74 20 63 68 69 6c 64 72 65 6e 20 2a 2f list children */
3630: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 .static int appf
3640: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 s_get_path_info(
3650: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 const char *path
3660: 2c 20 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 , struct appfs_p
3670: 61 74 68 69 6e 66 6f 20 2a 70 61 74 68 69 6e 66 athinfo *pathinf
3680: 6f 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 o) {..Tcl_Interp
3690: 20 2a 69 6e 74 65 72 70 3b 0a 09 54 63 6c 5f 4f *interp;..Tcl_O
36a0: 62 6a 20 2a 61 74 74 72 73 5f 64 69 63 74 2c 20 bj *attrs_dict,
36b0: 2a 61 74 74 72 5f 76 61 6c 75 65 3b 0a 09 63 6f *attr_value;..co
36c0: 6e 73 74 20 63 68 61 72 20 2a 61 74 74 72 5f 76 nst char *attr_v
36d0: 61 6c 75 65 5f 73 74 72 3b 0a 09 54 63 6c 5f 57 alue_str;..Tcl_W
36e0: 69 64 65 49 6e 74 20 61 74 74 72 5f 76 61 6c 75 ideInt attr_valu
36f0: 65 5f 77 69 64 65 3b 0a 09 69 6e 74 20 61 74 74 e_wide;..int att
3700: 72 5f 76 61 6c 75 65 5f 69 6e 74 3b 0a 09 73 74 r_value_int;..st
3710: 61 74 69 63 20 5f 5f 74 68 72 65 61 64 20 54 63 atic __thread Tc
3720: 6c 5f 4f 62 6a 20 2a 61 74 74 72 5f 6b 65 79 5f l_Obj *attr_key_
3730: 74 79 70 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 type = NULL, *at
3740: 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20 3d 20 4e tr_key_perms = N
3750: 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 73 ULL, *attr_key_s
3760: 69 7a 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 ize = NULL, *att
3770: 72 5f 6b 65 79 5f 74 69 6d 65 20 3d 20 4e 55 4c r_key_time = NUL
3780: 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 73 6f 75 L, *attr_key_sou
3790: 72 63 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 rce = NULL, *att
37a0: 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 r_key_childcount
37b0: 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b = NULL, *attr_k
37c0: 65 79 5f 70 61 63 6b 61 67 65 64 20 3d 20 4e 55 ey_packaged = NU
37d0: 4c 4c 3b 0a 09 69 6e 74 20 63 61 63 68 65 5f 72 LL;..int cache_r
37e0: 65 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 et;..int tcl_ret
37f0: 3b 0a 0a 09 63 61 63 68 65 5f 72 65 74 20 3d 20 ;...cache_ret =
3800: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 appfs_get_path_i
3810: 6e 66 6f 5f 63 61 63 68 65 5f 67 65 74 28 70 61 nfo_cache_get(pa
3820: 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73 th, appfs_get_fs
3830: 75 69 64 28 29 2c 20 70 61 74 68 69 6e 66 6f 29 uid(), pathinfo)
3840: 3b 0a 09 69 66 20 28 63 61 63 68 65 5f 72 65 74 ;..if (cache_ret
3850: 20 3d 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 70 == 0) {...if (p
3860: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 3d athinfo->type ==
3870: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f APPFS_PATHTYPE_
3880: 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 54 29 20 DOES_NOT_EXIST)
3890: 7b 0a 09 09 09 72 65 74 75 72 6e 28 2d 45 4e 4f {....return(-ENO
38a0: 45 4e 54 29 3b 0a 09 09 7d 0a 0a 09 09 69 66 20 ENT);...}....if
38b0: 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 (pathinfo->type
38c0: 3d 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 == APPFS_PATHTYP
38d0: 45 5f 49 4e 56 41 4c 49 44 29 20 7b 0a 09 09 09 E_INVALID) {....
38e0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 09 return(-EIO);...
38f0: 7d 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a }....return(0);.
3900: 09 7d 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 .}...interp = ap
3910: 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b pfs_TclInterp();
3920: 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 ..if (interp ==
3930: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e NULL) {...return
3940: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 74 63 6c (-EIO);..}...tcl
3950: 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c _ret = appfs_Tcl
3960: 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c _Eval(interp, 2,
3970: 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61 74 "::appfs::getat
3980: 74 72 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 tr", path);..if
3990: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f (tcl_ret != TCL_
39a0: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 OK) {...APPFS_DE
39b0: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67 65 BUG("::appfs::ge
39c0: 74 61 74 74 72 28 25 73 29 20 66 61 69 6c 65 64 tattr(%s) failed
39d0: 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41 50 50 .", path);...APP
39e0: 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 FS_DEBUG("Tcl Er
39f0: 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c ror is: %s", Tcl
3a00: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 _GetStringResult
3a10: 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 70 61 (interp));....pa
3a20: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 thinfo->type = A
3a30: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 4f PPFS_PATHTYPE_DO
3a40: 45 53 5f 4e 4f 54 5f 45 58 49 53 54 3b 0a 0a 09 ES_NOT_EXIST;...
3a50: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f .appfs_get_path_
3a60: 69 6e 66 6f 5f 63 61 63 68 65 5f 61 64 64 28 70 info_cache_add(p
3a70: 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 ath, appfs_get_f
3a80: 73 75 69 64 28 29 2c 20 70 61 74 68 69 6e 66 6f suid(), pathinfo
3a90: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 4e );....return(-EN
3aa0: 4f 45 4e 54 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 OENT);..}...if (
3ab0: 61 74 74 72 5f 6b 65 79 5f 74 79 70 65 20 3d 3d attr_key_type ==
3ac0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 61 74 74 72 5f NULL) {...attr_
3ad0: 6b 65 79 5f 74 79 70 65 20 20 20 20 20 20 20 3d key_type =
3ae0: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 Tcl_NewStringOb
3af0: 6a 28 22 74 79 70 65 22 2c 20 2d 31 29 3b 0a 09 j("type", -1);..
3b00: 09 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 20 .attr_key_perms
3b10: 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 = Tcl_NewSt
3b20: 72 69 6e 67 4f 62 6a 28 22 70 65 72 6d 73 22 2c ringObj("perms",
3b30: 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79 -1);...attr_key
3b40: 5f 73 69 7a 65 20 20 20 20 20 20 20 3d 20 54 63 _size = Tc
3b50: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 l_NewStringObj("
3b60: 73 69 7a 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74 size", -1);...at
3b70: 74 72 5f 6b 65 79 5f 74 69 6d 65 20 20 20 20 20 tr_key_time
3b80: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e = Tcl_NewStrin
3b90: 67 4f 62 6a 28 22 74 69 6d 65 22 2c 20 2d 31 29 gObj("time", -1)
3ba0: 3b 0a 09 09 61 74 74 72 5f 6b 65 79 5f 73 6f 75 ;...attr_key_sou
3bb0: 72 63 65 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 rce = Tcl_Ne
3bc0: 77 53 74 72 69 6e 67 4f 62 6a 28 22 73 6f 75 72 wStringObj("sour
3bd0: 63 65 22 2c 20 2d 31 29 3b 0a 09 09 61 74 74 72 ce", -1);...attr
3be0: 5f 6b 65 79 5f 63 68 69 6c 64 63 6f 75 6e 74 20 _key_childcount
3bf0: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f = Tcl_NewStringO
3c00: 62 6a 28 22 63 68 69 6c 64 63 6f 75 6e 74 22 2c bj("childcount",
3c10: 20 2d 31 29 3b 0a 09 09 61 74 74 72 5f 6b 65 79 -1);...attr_key
3c20: 5f 70 61 63 6b 61 67 65 64 20 20 20 3d 20 54 63 _packaged = Tc
3c30: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 l_NewStringObj("
3c40: 70 61 63 6b 61 67 65 64 22 2c 20 2d 31 29 3b 0a packaged", -1);.
3c50: 09 7d 0a 0a 09 61 74 74 72 73 5f 64 69 63 74 20 .}...attrs_dict
3c60: 3d 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65 73 75 = Tcl_GetObjResu
3c70: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 74 63 6c lt(interp);..tcl
3c80: 5f 72 65 74 20 3d 20 54 63 6c 5f 44 69 63 74 4f _ret = Tcl_DictO
3c90: 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 bjGet(interp, at
3ca0: 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b trs_dict, attr_k
3cb0: 65 79 5f 74 79 70 65 2c 20 26 61 74 74 72 5f 76 ey_type, &attr_v
3cc0: 61 6c 75 65 29 3b 0a 09 69 66 20 28 74 63 6c 5f alue);..if (tcl_
3cd0: 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b ret != TCL_OK) {
3ce0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 ...APPFS_DEBUG("
3cf0: 5b 64 69 63 74 20 67 65 74 20 5c 22 74 79 70 65 [dict get \"type
3d00: 5c 22 5d 20 66 61 69 6c 65 64 22 29 3b 0a 09 09 \"] failed");...
3d10: 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c APPFS_DEBUG("Tcl
3d20: 20 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 Error is: %s",
3d30: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 Tcl_GetStringRes
3d40: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 ult(interp));...
3d50: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 .return(-EIO);..
3d60: 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 76 61 6c }...if (attr_val
3d70: 75 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 ue == NULL) {...
3d80: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d return(-EIO);..}
3d90: 0a 0a 09 70 61 74 68 69 6e 66 6f 2d 3e 70 61 63 ...pathinfo->pac
3da0: 6b 61 67 65 64 20 3d 20 30 3b 0a 09 70 61 74 68 kaged = 0;..path
3db0: 69 6e 66 6f 2d 3e 69 6e 6f 64 65 20 3d 20 61 70 info->inode = ap
3dc0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f pfs_get_path_ino
3dd0: 64 65 28 70 61 74 68 29 3b 0a 0a 09 61 74 74 72 de(path);...attr
3de0: 5f 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63 6c _value_str = Tcl
3df0: 5f 47 65 74 53 74 72 69 6e 67 28 61 74 74 72 5f _GetString(attr_
3e00: 76 61 6c 75 65 29 3b 0a 09 73 77 69 74 63 68 20 value);..switch
3e10: 28 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 72 5b (attr_value_str[
3e20: 30 5d 29 20 7b 0a 09 09 63 61 73 65 20 27 64 27 0]) {...case 'd'
3e30: 3a 20 2f 2a 20 64 69 72 65 63 74 6f 72 79 20 2a : /* directory *
3e40: 2f 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 /....pathinfo->t
3e50: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 ype = APPFS_PATH
3e60: 54 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3b 0a TYPE_DIRECTORY;.
3e70: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 ...pathinfo->typ
3e80: 65 69 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63 einfo.dir.childc
3e90: 6f 75 6e 74 20 3d 20 30 3b 0a 0a 09 09 09 54 63 ount = 0;.....Tc
3ea0: 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 l_DictObjGet(int
3eb0: 65 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c erp, attrs_dict,
3ec0: 20 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 attr_key_childc
3ed0: 6f 75 6e 74 2c 20 26 61 74 74 72 5f 76 61 6c 75 ount, &attr_valu
3ee0: 65 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72 5f e);....if (attr_
3ef0: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b value != NULL) {
3f00: 0a 09 09 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 .....tcl_ret = T
3f10: 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f cl_GetWideIntFro
3f20: 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 5f mObj(NULL, attr_
3f30: 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 6c value, &attr_val
3f40: 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 09 69 66 ue_wide);.....if
3f50: 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 4c (tcl_ret == TCL
3f60: 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 70 61 74 68 _OK) {......path
3f70: 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 64 info->typeinfo.d
3f80: 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 20 3d 20 ir.childcount =
3f90: 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b attr_value_wide;
3fa0: 0a 09 09 09 09 7d 0a 09 09 09 7d 0a 0a 09 09 09 .....}....}.....
3fb0: 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 27 66 break;...case 'f
3fc0: 27 3a 20 2f 2a 20 66 69 6c 65 20 2a 2f 0a 09 09 ': /* file */...
3fd0: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 .pathinfo->type
3fe0: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 = APPFS_PATHTYPE
3ff0: 5f 46 49 4c 45 3b 0a 09 09 09 70 61 74 68 69 6e _FILE;....pathin
4000: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c fo->typeinfo.fil
4010: 65 2e 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 70 e.size = 0;....p
4020: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 athinfo->typeinf
4030: 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74 61 62 6c o.file.executabl
4040: 65 20 3d 20 30 3b 0a 0a 09 09 09 54 63 6c 5f 44 e = 0;.....Tcl_D
4050: 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 ictObjGet(interp
4060: 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 61 74 , attrs_dict, at
4070: 74 72 5f 6b 65 79 5f 73 69 7a 65 2c 20 26 61 74 tr_key_size, &at
4080: 74 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 69 66 tr_value);....if
4090: 20 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 (attr_value !=
40a0: 4e 55 4c 4c 29 20 7b 0a 09 09 09 09 74 63 6c 5f NULL) {.....tcl_
40b0: 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 57 69 64 ret = Tcl_GetWid
40c0: 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c eIntFromObj(NULL
40d0: 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c 20 26 61 , attr_value, &a
40e0: 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 29 3b ttr_value_wide);
40f0: 0a 09 09 09 09 69 66 20 28 74 63 6c 5f 72 65 74 .....if (tcl_ret
4100: 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 == TCL_OK) {...
4110: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 ...pathinfo->typ
4120: 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 einfo.file.size
4130: 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 = attr_value_wid
4140: 65 3b 0a 09 09 09 09 7d 0a 09 09 09 7d 0a 0a 09 e;.....}....}...
4150: 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 ..Tcl_DictObjGet
4160: 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 (interp, attrs_d
4170: 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 70 65 ict, attr_key_pe
4180: 72 6d 73 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 rms, &attr_value
4190: 29 3b 0a 09 09 09 69 66 20 28 61 74 74 72 5f 76 );....if (attr_v
41a0: 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a alue != NULL) {.
41b0: 09 09 09 09 61 74 74 72 5f 76 61 6c 75 65 5f 73 ....attr_value_s
41c0: 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 tr = Tcl_GetStri
41d0: 6e 67 28 61 74 74 72 5f 76 61 6c 75 65 29 3b 0a ng(attr_value);.
41e0: 09 09 09 09 69 66 20 28 61 74 74 72 5f 76 61 6c ....if (attr_val
41f0: 75 65 5f 73 74 72 5b 30 5d 20 3d 3d 20 27 78 27 ue_str[0] == 'x'
4200: 29 20 7b 0a 09 09 09 09 09 70 61 74 68 69 6e 66 ) {......pathinf
4210: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 o->typeinfo.file
4220: 2e 65 78 65 63 75 74 61 62 6c 65 20 3d 20 31 3b .executable = 1;
4230: 0a 09 09 09 09 7d 0a 09 09 09 7d 0a 09 09 09 62 .....}....}....b
4240: 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 27 73 27 reak;...case 's'
4250: 3a 20 2f 2a 20 73 79 6d 6c 69 6e 6b 20 2a 2f 0a : /* symlink */.
4260: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 ...pathinfo->typ
4270: 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 e = APPFS_PATHTY
4280: 50 45 5f 53 59 4d 4c 49 4e 4b 3b 0a 09 09 09 70 PE_SYMLINK;....p
4290: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 athinfo->typeinf
42a0: 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d o.symlink.size =
42b0: 20 30 3b 0a 09 09 09 70 61 74 68 69 6e 66 6f 2d 0;....pathinfo-
42c0: 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e >typeinfo.symlin
42d0: 6b 2e 73 6f 75 72 63 65 5b 30 5d 20 3d 20 27 5c k.source[0] = '\
42e0: 30 27 3b 0a 0a 09 09 09 54 63 6c 5f 44 69 63 74 0';.....Tcl_Dict
42f0: 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 ObjGet(interp, a
4300: 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f ttrs_dict, attr_
4310: 6b 65 79 5f 73 6f 75 72 63 65 2c 20 26 61 74 74 key_source, &att
4320: 72 5f 76 61 6c 75 65 29 3b 0a 09 09 09 69 66 20 r_value);....if
4330: 28 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e (attr_value != N
4340: 55 4c 4c 29 20 7b 0a 09 09 09 09 61 74 74 72 5f ULL) {.....attr_
4350: 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f value_str = Tcl_
4360: 47 65 74 53 74 72 69 6e 67 46 72 6f 6d 4f 62 6a GetStringFromObj
4370: 28 61 74 74 72 5f 76 61 6c 75 65 2c 20 26 61 74 (attr_value, &at
4380: 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 20 0a tr_value_int); .
4390: 0a 09 09 09 09 69 66 20 28 28 61 74 74 72 5f 76 .....if ((attr_v
43a0: 61 6c 75 65 5f 69 6e 74 20 2b 20 31 29 20 3c 3d alue_int + 1) <=
43b0: 20 73 69 7a 65 6f 66 28 70 61 74 68 69 6e 66 6f sizeof(pathinfo
43c0: 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 ->typeinfo.symli
43d0: 6e 6b 2e 73 6f 75 72 63 65 29 29 20 7b 0a 09 09 nk.source)) {...
43e0: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 ...pathinfo->typ
43f0: 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 einfo.symlink.si
4400: 7a 65 20 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f ze = attr_value_
4410: 69 6e 74 3b 0a 09 09 09 09 09 70 61 74 68 69 6e int;......pathin
4420: 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d fo->typeinfo.sym
4430: 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b 61 74 74 72 link.source[attr
4440: 5f 76 61 6c 75 65 5f 69 6e 74 5d 20 3d 20 27 5c _value_int] = '\
4450: 30 27 3b 0a 0a 09 09 09 09 09 6d 65 6d 63 70 79 0';.......memcpy
4460: 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 (pathinfo->typei
4470: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 nfo.symlink.sour
4480: 63 65 2c 20 61 74 74 72 5f 76 61 6c 75 65 5f 73 ce, attr_value_s
4490: 74 72 2c 20 61 74 74 72 5f 76 61 6c 75 65 5f 69 tr, attr_value_i
44a0: 6e 74 29 3b 0a 09 09 09 09 7d 0a 09 09 09 7d 0a nt);.....}....}.
44b0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 ...break;...case
44c0: 20 27 46 27 3a 20 2f 2a 20 70 69 70 65 2f 66 69 'F': /* pipe/fi
44d0: 66 6f 20 2a 2f 0a 09 09 09 70 61 74 68 69 6e 66 fo */....pathinf
44e0: 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f o->type = APPFS_
44f0: 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3b 0a 09 PATHTYPE_FIFO;..
4500: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 ..break;...case
4510: 27 53 27 3a 20 2f 2a 20 55 4e 49 58 20 64 6f 6d 'S': /* UNIX dom
4520: 61 69 6e 20 73 6f 63 6b 65 74 20 2a 2f 0a 09 09 ain socket */...
4530: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 .pathinfo->type
4540: 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 = APPFS_PATHTYPE
4550: 5f 53 4f 43 4b 45 54 3b 0a 09 09 09 62 72 65 61 _SOCKET;....brea
4560: 6b 3b 0a 09 09 64 65 66 61 75 6c 74 3a 0a 09 09 k;...default:...
4570: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 .return(-EIO);..
4580: 7d 0a 0a 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 }...Tcl_DictObjG
4590: 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 et(interp, attrs
45a0: 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f _dict, attr_key_
45b0: 70 61 63 6b 61 67 65 64 2c 20 26 61 74 74 72 5f packaged, &attr_
45c0: 76 61 6c 75 65 29 3b 0a 09 69 66 20 28 61 74 74 value);..if (att
45d0: 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 r_value != NULL)
45e0: 20 7b 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e 70 {...pathinfo->p
45f0: 61 63 6b 61 67 65 64 20 3d 20 31 3b 0a 09 7d 0a ackaged = 1;..}.
4600: 0a 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 ..Tcl_DictObjGet
4610: 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 (interp, attrs_d
4620: 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74 69 ict, attr_key_ti
4630: 6d 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 me, &attr_value)
4640: 3b 0a 09 69 66 20 28 61 74 74 72 5f 76 61 6c 75 ;..if (attr_valu
4650: 65 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 74 e != NULL) {...t
4660: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 cl_ret = Tcl_Get
4670: 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 4e WideIntFromObj(N
4680: 55 4c 4c 2c 20 61 74 74 72 5f 76 61 6c 75 65 2c ULL, attr_value,
4690: 20 26 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 &attr_value_wid
46a0: 65 29 3b 0a 09 09 69 66 20 28 74 63 6c 5f 72 65 e);...if (tcl_re
46b0: 74 20 3d 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 t == TCL_OK) {..
46c0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 69 6d 65 ..pathinfo->time
46d0: 20 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 = attr_value_wi
46e0: 64 65 3b 0a 09 09 7d 0a 09 7d 20 65 6c 73 65 20 de;...}..} else
46f0: 7b 0a 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 69 {...pathinfo->ti
4700: 6d 65 20 3d 20 30 3b 0a 09 7d 0a 0a 09 61 70 70 me = 0;..}...app
4710: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f fs_get_path_info
4720: 5f 63 61 63 68 65 5f 61 64 64 28 70 61 74 68 2c _cache_add(path,
4730: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 appfs_get_fsuid
4740: 28 29 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a 0a (), pathinfo);..
4750: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 .return(0);.}..s
4760: 74 61 74 69 63 20 63 68 61 72 20 2a 61 70 70 66 tatic char *appf
4770: 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 s_prepare_to_cre
4780: 61 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a ate(const char *
4790: 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 path) {..Tcl_Int
47a0: 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f erp *interp;..co
47b0: 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 nst char *real_p
47c0: 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 ath;..int tcl_re
47d0: 74 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 t;...appfs_get_p
47e0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 ath_info_cache_f
47f0: 6c 75 73 68 28 61 70 70 66 73 5f 67 65 74 5f 66 lush(appfs_get_f
4800: 73 75 69 64 28 29 2c 20 2d 31 29 3b 0a 0a 09 69 suid(), -1);...i
4810: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 nterp = appfs_Tc
4820: 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 lInterp();..if (
4830: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 interp == NULL)
4840: 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 {...return(NULL)
4850: 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d ;..}...tcl_ret =
4860: 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 appfs_Tcl_Eval(
4870: 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 interp, 2, "::ap
4880: 70 66 73 3a 3a 70 72 65 70 61 72 65 5f 74 6f 5f pfs::prepare_to_
4890: 63 72 65 61 74 65 22 2c 20 70 61 74 68 29 3b 0a create", path);.
48a0: 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 .if (tcl_ret !=
48b0: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 TCL_OK) {...APPF
48c0: 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 S_DEBUG("::appfs
48d0: 3a 3a 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 ::prepare_to_cre
48e0: 61 74 65 28 25 73 29 20 66 61 69 6c 65 64 2e 22 ate(%s) failed."
48f0: 2c 20 70 61 74 68 29 3b 0a 09 09 41 50 50 46 53 , path);...APPFS
4900: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f _DEBUG("Tcl Erro
4910: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 r is: %s", Tcl_G
4920: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 etStringResult(i
4930: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 nterp));....retu
4940: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 rn(NULL);..}...r
4950: 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 eal_path = Tcl_G
4960: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 etStringResult(i
4970: 6e 74 65 72 70 29 3b 0a 09 69 66 20 28 72 65 61 nterp);..if (rea
4980: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 l_path == NULL)
4990: 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 {...return(NULL)
49a0: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 73 74 ;..}...return(st
49b0: 72 64 75 70 28 72 65 61 6c 5f 70 61 74 68 29 29 rdup(real_path))
49c0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 63 68 61 72 ;.}..static char
49d0: 20 2a 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61 74 *appfs_localpat
49e0: 68 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 h(const char *pa
49f0: 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 th) {..Tcl_Inter
4a00: 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 p *interp;..cons
4a10: 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 t char *real_pat
4a20: 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b h;..int tcl_ret;
4a30: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 ...interp = appf
4a40: 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 s_TclInterp();..
4a50: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 if (interp == NU
4a60: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e LL) {...return(N
4a70: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 ULL);..}...tcl_r
4a80: 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 et = appfs_Tcl_E
4a90: 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 val(interp, 2, "
4aa0: 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63 61 6c 70 61 ::appfs::localpa
4ab0: 74 68 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 20 th", path);..if
4ac0: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f (tcl_ret != TCL_
4ad0: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 OK) {...APPFS_DE
4ae0: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f BUG("::appfs::lo
4af0: 63 61 6c 70 61 74 68 28 25 73 29 20 66 61 69 6c calpath(%s) fail
4b00: 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 41 ed.", path);...A
4b10: 50 50 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 PPFS_DEBUG("Tcl
4b20: 45 72 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 Error is: %s", T
4b30: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 cl_GetStringResu
4b40: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 0a 09 09 lt(interp));....
4b50: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d return(NULL);..}
4b60: 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 ...real_path = T
4b70: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 cl_GetStringResu
4b80: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 09 69 66 20 lt(interp);..if
4b90: 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 (real_path == NU
4ba0: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e LL) {...return(N
4bb0: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 ULL);..}...retur
4bc0: 6e 28 73 74 72 64 75 70 28 72 65 61 6c 5f 70 61 n(strdup(real_pa
4bd0: 74 68 29 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 th));.}..static
4be0: 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72 int appfs_fuse_r
4bf0: 65 61 64 6c 69 6e 6b 28 63 6f 6e 73 74 20 63 68 eadlink(const ch
4c00: 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72 20 2a ar *path, char *
4c10: 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a 65 buf, size_t size
4c20: 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70 70 66 ) {..struct appf
4c30: 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74 68 69 s_pathinfo pathi
4c40: 6e 66 6f 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c nfo;..int retval
4c50: 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44 45 = 0;...APPFS_DE
4c60: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 BUG("Enter (path
4c70: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 = %s, ...)", pa
4c80: 74 68 29 3b 0a 0a 09 70 61 74 68 69 6e 66 6f 2e th);...pathinfo.
4c90: 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 type = APPFS_PAT
4ca0: 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a HTYPE_INVALID;..
4cb0: 09 72 65 74 76 61 6c 20 3d 20 61 70 70 66 73 5f .retval = appfs_
4cc0: 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61 get_path_info(pa
4cd0: 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a th, &pathinfo);.
4ce0: 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20 30 .if (retval != 0
4cf0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 72 65 74 ) {...return(ret
4d00: 76 61 6c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 70 val);..}...if (p
4d10: 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 21 3d 20 athinfo.type !=
4d20: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 APPFS_PATHTYPE_S
4d30: 59 4d 4c 49 4e 4b 29 20 7b 0a 09 09 72 65 74 75 YMLINK) {...retu
4d40: 72 6e 28 2d 45 49 4e 56 41 4c 29 3b 0a 09 7d 0a rn(-EINVAL);..}.
4d50: 0a 09 69 66 20 28 28 73 74 72 6c 65 6e 28 70 61 ..if ((strlen(pa
4d60: 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e thinfo.typeinfo.
4d70: 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 20 symlink.source)
4d80: 2b 20 31 29 20 3e 20 73 69 7a 65 29 20 7b 0a 09 + 1) > size) {..
4d90: 09 72 65 74 75 72 6e 28 2d 45 4e 41 4d 45 54 4f .return(-ENAMETO
4da0: 4f 4c 4f 4e 47 29 3b 0a 09 7d 0a 0a 09 6d 65 6d OLONG);..}...mem
4db0: 63 70 79 28 62 75 66 2c 20 70 61 74 68 69 6e 66 cpy(buf, pathinf
4dc0: 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 o.typeinfo.symli
4dd0: 6e 6b 2e 73 6f 75 72 63 65 2c 20 73 74 72 6c 65 nk.source, strle
4de0: 6e 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 n(pathinfo.typei
4df0: 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 nfo.symlink.sour
4e00: 63 65 29 20 2b 20 31 29 3b 0a 0a 09 72 65 74 75 ce) + 1);...retu
4e10: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 rn(0);.}..static
4e20: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f int appfs_fuse_
4e30: 67 65 74 61 74 74 72 28 63 6f 6e 73 74 20 63 68 getattr(const ch
4e40: 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74 ar *path, struct
4e50: 20 73 74 61 74 20 2a 73 74 62 75 66 29 20 7b 0a stat *stbuf) {.
4e60: 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 .struct appfs_pa
4e70: 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f 3b thinfo pathinfo;
4e80: 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09 ..int retval;...
4e90: 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 41 50 retval = 0;...AP
4ea0: 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 PFS_DEBUG("Enter
4eb0: 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e (path = %s, ...
4ec0: 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 70 61 74 )", path);...pat
4ed0: 68 69 6e 66 6f 2e 74 79 70 65 20 3d 20 41 50 50 hinfo.type = APP
4ee0: 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 FS_PATHTYPE_INVA
4ef0: 4c 49 44 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 LID;...retval =
4f00: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 appfs_get_path_i
4f10: 6e 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69 nfo(path, &pathi
4f20: 6e 66 6f 29 3b 0a 09 69 66 20 28 72 65 74 76 61 nfo);..if (retva
4f30: 6c 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 l != 0) {...retu
4f40: 72 6e 28 72 65 74 76 61 6c 29 3b 0a 09 7d 0a 0a rn(retval);..}..
4f50: 09 6d 65 6d 73 65 74 28 73 74 62 75 66 2c 20 30 .memset(stbuf, 0
4f60: 2c 20 73 69 7a 65 6f 66 28 73 74 72 75 63 74 20 , sizeof(struct
4f70: 73 74 61 74 29 29 3b 0a 0a 09 73 74 62 75 66 2d stat));...stbuf-
4f80: 3e 73 74 5f 6d 74 69 6d 65 20 3d 20 70 61 74 68 >st_mtime = path
4f90: 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 info.time;..stbu
4fa0: 66 2d 3e 73 74 5f 63 74 69 6d 65 20 3d 20 70 61 f->st_ctime = pa
4fb0: 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 thinfo.time;..st
4fc0: 62 75 66 2d 3e 73 74 5f 61 74 69 6d 65 20 3d 20 buf->st_atime =
4fd0: 70 61 74 68 69 6e 66 6f 2e 74 69 6d 65 3b 0a 09 pathinfo.time;..
4fe0: 73 74 62 75 66 2d 3e 73 74 5f 69 6e 6f 20 20 20 stbuf->st_ino
4ff0: 3d 20 70 61 74 68 69 6e 66 6f 2e 69 6e 6f 64 65 = pathinfo.inode
5000: 3b 0a 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 ;..stbuf->st_mod
5010: 65 20 20 3d 20 30 3b 0a 0a 09 73 77 69 74 63 68 e = 0;...switch
5020: 20 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 29 (pathinfo.type)
5030: 20 7b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f {...case APPFS_
5040: 50 41 54 48 54 59 50 45 5f 44 49 52 45 43 54 4f PATHTYPE_DIRECTO
5050: 52 59 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 RY:....stbuf->st
5060: 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 44 49 52 20 _mode = S_IFDIR
5070: 7c 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66 | 0555;....stbuf
5080: 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 32 20 2b ->st_nlink = 2 +
5090: 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e pathinfo.typein
50a0: 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e fo.dir.childcoun
50b0: 74 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 t;....break;...c
50c0: 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 ase APPFS_PATHTY
50d0: 50 45 5f 46 49 4c 45 3a 0a 09 09 09 69 66 20 28 PE_FILE:....if (
50e0: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 pathinfo.typeinf
50f0: 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74 61 62 6c o.file.executabl
5100: 65 29 20 7b 0a 09 09 09 09 73 74 62 75 66 2d 3e e) {.....stbuf->
5110: 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 52 45 st_mode = S_IFRE
5120: 47 20 7c 20 30 35 35 35 3b 0a 09 09 09 7d 20 65 G | 0555;....} e
5130: 6c 73 65 20 7b 0a 09 09 09 09 73 74 62 75 66 2d lse {.....stbuf-
5140: 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 52 >st_mode = S_IFR
5150: 45 47 20 7c 20 30 34 34 34 3b 0a 09 09 09 7d 0a EG | 0444;....}.
5160: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c ....stbuf->st_nl
5170: 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 ink = 1;....stbu
5180: 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 70 61 74 f->st_size = pat
5190: 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 hinfo.typeinfo.f
51a0: 69 6c 65 2e 73 69 7a 65 3b 0a 09 09 09 62 72 65 ile.size;....bre
51b0: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 ak;...case APPFS
51c0: 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e _PATHTYPE_SYMLIN
51d0: 4b 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f K:....stbuf->st_
51e0: 6d 6f 64 65 20 3d 20 53 5f 49 46 4c 4e 4b 20 7c mode = S_IFLNK |
51f0: 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 0555;....stbuf-
5200: 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 >st_nlink = 1;..
5210: 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 ..stbuf->st_size
5220: 20 3d 20 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 = pathinfo.type
5230: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 69 7a info.symlink.siz
5240: 65 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 e;....break;...c
5250: 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 ase APPFS_PATHTY
5260: 50 45 5f 53 4f 43 4b 45 54 3a 0a 09 09 09 73 74 PE_SOCKET:....st
5270: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 3d 20 53 buf->st_mode = S
5280: 5f 49 46 53 4f 43 4b 20 7c 20 30 35 35 35 3b 0a _IFSOCK | 0555;.
5290: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 ...stbuf->st_nli
52a0: 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 75 66 nk = 1;....stbuf
52b0: 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 30 3b 0a 09 ->st_size = 0;..
52c0: 09 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 ..break;...case
52d0: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46 APPFS_PATHTYPE_F
52e0: 49 46 4f 3a 0a 09 09 09 73 74 62 75 66 2d 3e 73 IFO:....stbuf->s
52f0: 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 49 46 4f t_mode = S_IFIFO
5300: 20 7c 20 30 35 35 35 3b 0a 09 09 09 73 74 62 75 | 0555;....stbu
5310: 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 31 3b f->st_nlink = 1;
5320: 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 73 69 ....stbuf->st_si
5330: 7a 65 20 3d 20 30 3b 0a 09 09 09 62 72 65 61 6b ze = 0;....break
5340: 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f 50 ;...case APPFS_P
5350: 41 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f 54 ATHTYPE_DOES_NOT
5360: 5f 45 58 49 53 54 3a 0a 09 09 09 72 65 74 76 61 _EXIST:....retva
5370: 6c 20 3d 20 2d 45 4e 4f 45 4e 54 3b 0a 0a 09 09 l = -ENOENT;....
5380: 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 .break;...case A
5390: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 49 4e PPFS_PATHTYPE_IN
53a0: 56 41 4c 49 44 3a 0a 09 09 09 72 65 74 76 61 6c VALID:....retval
53b0: 20 3d 20 2d 45 49 4f 3b 0a 0a 09 09 09 62 72 65 = -EIO;.....bre
53c0: 61 6b 3b 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 ak;..}...if (pat
53d0: 68 69 6e 66 6f 2e 70 61 63 6b 61 67 65 64 29 20 hinfo.packaged)
53e0: 7b 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f 75 69 {...stbuf->st_ui
53f0: 64 20 20 20 3d 20 61 70 70 66 73 5f 67 65 74 5f d = appfs_get_
5400: 66 73 75 69 64 28 29 3b 0a 09 09 73 74 62 75 66 fsuid();...stbuf
5410: 2d 3e 73 74 5f 67 69 64 20 20 20 3d 20 61 70 70 ->st_gid = app
5420: 66 73 5f 67 65 74 5f 66 73 67 69 64 28 29 3b 0a fs_get_fsgid();.
5430: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 ..stbuf->st_mode
5440: 20 7c 3d 20 30 32 30 30 3b 0a 09 7d 0a 0a 09 72 |= 0200;..}...r
5450: 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d eturn(retval);.}
5460: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 ..static int app
5470: 66 73 5f 66 75 73 65 5f 72 65 61 64 64 69 72 28 fs_fuse_readdir(
5480: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 const char *path
5490: 2c 20 76 6f 69 64 20 2a 62 75 66 2c 20 66 75 73 , void *buf, fus
54a0: 65 5f 66 69 6c 6c 5f 64 69 72 5f 74 20 66 69 6c e_fill_dir_t fil
54b0: 6c 65 72 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 ler, off_t offse
54c0: 74 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 t, struct fuse_f
54d0: 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a ile_info *fi) {.
54e0: 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 .Tcl_Interp *int
54f0: 65 72 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a erp;..Tcl_Obj **
5500: 63 68 69 6c 64 72 65 6e 3b 0a 09 69 6e 74 20 63 children;..int c
5510: 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c 20 69 hildren_count, i
5520: 64 78 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 dx;..int tcl_ret
5530: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 ;...APPFS_DEBUG(
5540: 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 "Enter (path = %
5550: 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b s, ...)", path);
5560: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 ...interp = appf
5570: 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 s_TclInterp();..
5580: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 if (interp == NU
5590: 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 30 LL) {...return(0
55a0: 29 3b 0a 09 7d 0a 0a 09 66 69 6c 6c 65 72 28 62 );..}...filler(b
55b0: 75 66 2c 20 22 2e 22 2c 20 4e 55 4c 4c 2c 20 30 uf, ".", NULL, 0
55c0: 29 3b 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 );..filler(buf,
55d0: 22 2e 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a "..", NULL, 0);.
55e0: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 ..tcl_ret = appf
55f0: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 s_Tcl_Eval(inter
5600: 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a p, 2, "::appfs::
5610: 67 65 74 63 68 69 6c 64 72 65 6e 22 2c 20 70 61 getchildren", pa
5620: 74 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 th);..if (tcl_re
5630: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 t != TCL_OK) {..
5640: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a .APPFS_DEBUG("::
5650: 61 70 70 66 73 3a 3a 67 65 74 63 68 69 6c 64 72 appfs::getchildr
5660: 65 6e 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c en(%s) failed.",
5670: 20 70 61 74 68 29 3b 0a 09 09 41 50 50 46 53 5f path);...APPFS_
5680: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 DEBUG("Tcl Error
5690: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 is: %s", Tcl_Ge
56a0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e tStringResult(in
56b0: 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 72 terp));....retur
56c0: 6e 28 30 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 n(0);..}...tcl_r
56d0: 65 74 20 3d 20 54 63 6c 5f 4c 69 73 74 4f 62 6a et = Tcl_ListObj
56e0: 47 65 74 45 6c 65 6d 65 6e 74 73 28 69 6e 74 65 GetElements(inte
56f0: 72 70 2c 20 54 63 6c 5f 47 65 74 4f 62 6a 52 65 rp, Tcl_GetObjRe
5700: 73 75 6c 74 28 69 6e 74 65 72 70 29 2c 20 26 63 sult(interp), &c
5710: 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 2c 20 26 hildren_count, &
5720: 63 68 69 6c 64 72 65 6e 29 3b 0a 09 69 66 20 28 children);..if (
5730: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f tcl_ret != TCL_O
5740: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 K) {...APPFS_DEB
5750: 55 47 28 22 50 61 72 73 69 6e 67 20 6c 69 73 74 UG("Parsing list
5760: 20 6f 66 20 63 68 69 6c 64 72 65 6e 20 6f 6e 20 of children on
5770: 70 61 74 68 20 25 73 20 66 61 69 6c 65 64 2e 22 path %s failed."
5780: 2c 20 70 61 74 68 29 3b 0a 09 09 41 50 50 46 53 , path);...APPFS
5790: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f _DEBUG("Tcl Erro
57a0: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 r is: %s", Tcl_G
57b0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 etStringResult(i
57c0: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 nterp));....retu
57d0: 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 66 6f 72 20 rn(0);..}...for
57e0: 28 69 64 78 20 3d 20 30 3b 20 69 64 78 20 3c 20 (idx = 0; idx <
57f0: 63 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 3b 20 children_count;
5800: 69 64 78 2b 2b 29 20 7b 0a 09 09 66 69 6c 6c 65 idx++) {...fille
5810: 72 28 62 75 66 2c 20 54 63 6c 5f 47 65 74 53 74 r(buf, Tcl_GetSt
5820: 72 69 6e 67 28 63 68 69 6c 64 72 65 6e 5b 69 64 ring(children[id
5830: 78 5d 29 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 09 x]), NULL, 0);..
5840: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d }...return(0);.}
5850: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 ..static int app
5860: 66 73 5f 66 75 73 65 5f 6f 70 65 6e 28 63 6f 6e fs_fuse_open(con
5870: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73 st char *path, s
5880: 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f truct fuse_file_
5890: 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c info *fi) {..Tcl
58a0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b _Interp *interp;
58b0: 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 ..struct appfs_p
58c0: 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f athinfo pathinfo
58d0: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72 ;..const char *r
58e0: 65 61 6c 5f 70 61 74 68 2c 20 2a 6d 6f 64 65 3b eal_path, *mode;
58f0: 0a 09 69 6e 74 20 67 70 69 5f 72 65 74 2c 20 74 ..int gpi_ret, t
5900: 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 66 68 3b cl_ret;..int fh;
5910: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 ...APPFS_DEBUG("
5920: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 Enter (path = %s
5930: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a , ...)", path);.
5940: 0a 09 67 70 69 5f 72 65 74 20 3d 20 61 70 70 66 ..gpi_ret = appf
5950: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 s_get_path_info(
5960: 70 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 path, &pathinfo)
5970: 3b 0a 0a 09 69 66 20 28 28 66 69 2d 3e 66 6c 61 ;...if ((fi->fla
5980: 67 73 20 26 20 28 4f 5f 57 52 4f 4e 4c 59 7c 4f gs & (O_WRONLY|O
5990: 5f 43 52 45 41 54 29 29 20 3d 3d 20 28 4f 5f 43 _CREAT)) == (O_C
59a0: 52 45 41 54 7c 4f 5f 57 52 4f 4e 4c 59 29 29 20 REAT|O_WRONLY))
59b0: 7b 0a 09 09 2f 2a 20 54 68 65 20 66 69 6c 65 20 {.../* The file
59c0: 77 69 6c 6c 20 62 65 20 63 72 65 61 74 65 64 20 will be created
59d0: 69 66 20 69 74 20 64 6f 65 73 20 6e 6f 74 20 65 if it does not e
59e0: 78 69 73 74 20 2a 2f 0a 09 09 69 66 20 28 67 70 xist */...if (gp
59f0: 69 5f 72 65 74 20 21 3d 20 30 20 26 26 20 67 70 i_ret != 0 && gp
5a00: 69 5f 72 65 74 20 21 3d 20 2d 45 4e 4f 45 4e 54 i_ret != -ENOENT
5a10: 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 67 70 ) {....return(gp
5a20: 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a 09 09 6d i_ret);...}....m
5a30: 6f 64 65 20 3d 20 22 63 72 65 61 74 65 22 3b 0a ode = "create";.
5a40: 0a 09 09 2f 2a 0a 09 09 20 2a 20 57 65 20 68 61 .../*... * We ha
5a50: 76 65 20 74 6f 20 63 6c 65 61 72 20 74 68 65 20 ve to clear the
5a60: 63 61 63 68 65 20 68 65 72 65 20 73 6f 20 74 68 cache here so th
5a70: 61 74 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 at the number of
5a80: 0a 09 09 20 2a 20 6c 69 6e 6b 73 20 67 65 74 73 ... * links gets
5a90: 20 6d 61 69 6e 74 61 69 6e 65 64 20 6f 6e 20 74 maintained on t
5aa0: 68 65 20 70 61 72 65 6e 74 20 64 69 72 65 63 74 he parent direct
5ab0: 6f 72 79 0a 09 09 20 2a 2f 0a 09 09 61 70 70 66 ory... */...appf
5ac0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f s_get_path_info_
5ad0: 63 61 63 68 65 5f 66 6c 75 73 68 28 61 70 70 66 cache_flush(appf
5ae0: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 2c 20 2d s_get_fsuid(), -
5af0: 31 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 1);..} else {...
5b00: 2f 2a 20 54 68 65 20 66 69 6c 65 20 6d 75 73 74 /* The file must
5b10: 20 61 6c 72 65 61 64 79 20 65 78 69 73 74 20 2a already exist *
5b20: 2f 0a 09 09 69 66 20 28 67 70 69 5f 72 65 74 20 /...if (gpi_ret
5b30: 21 3d 20 30 29 20 7b 0a 09 09 09 72 65 74 75 72 != 0) {....retur
5b40: 6e 28 67 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a n(gpi_ret);...}.
5b50: 0a 09 09 6d 6f 64 65 20 3d 20 22 22 3b 0a 0a 09 ...mode = "";...
5b60: 09 69 66 20 28 28 66 69 2d 3e 66 6c 61 67 73 20 .if ((fi->flags
5b70: 26 20 4f 5f 57 52 4f 4e 4c 59 29 20 3d 3d 20 4f & O_WRONLY) == O
5b80: 5f 57 52 4f 4e 4c 59 29 20 7b 0a 09 09 09 6d 6f _WRONLY) {....mo
5b90: 64 65 20 3d 20 22 77 72 69 74 65 22 3b 0a 09 09 de = "write";...
5ba0: 7d 0a 09 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 }..}...if (pathi
5bb0: 6e 66 6f 2e 74 79 70 65 20 3d 3d 20 41 50 50 46 nfo.type == APPF
5bc0: 53 5f 50 41 54 48 54 59 50 45 5f 44 49 52 45 43 S_PATHTYPE_DIREC
5bd0: 54 4f 52 59 29 20 7b 0a 09 09 72 65 74 75 72 6e TORY) {...return
5be0: 28 2d 45 49 53 44 49 52 29 3b 0a 09 7d 0a 0a 09 (-EISDIR);..}...
5bf0: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 interp = appfs_T
5c00: 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 clInterp();..if
5c10: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 (interp == NULL)
5c20: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f {...return(-EIO
5c30: 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 );..}...tcl_ret
5c40: 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c = appfs_Tcl_Eval
5c50: 28 69 6e 74 65 72 70 2c 20 33 2c 20 22 3a 3a 61 (interp, 3, "::a
5c60: 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 22 2c ppfs::openpath",
5c70: 20 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 09 69 path, mode);..i
5c80: 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 f (tcl_ret != TC
5c90: 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f L_OK) {...APPFS_
5ca0: 44 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a DEBUG("::appfs::
5cb0: 6f 70 65 6e 70 61 74 68 28 25 73 2c 20 25 73 29 openpath(%s, %s)
5cc0: 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 2c failed.", path,
5cd0: 20 6d 6f 64 65 29 3b 0a 09 09 41 50 50 46 53 5f mode);...APPFS_
5ce0: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 DEBUG("Tcl Error
5cf0: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 is: %s", Tcl_Ge
5d00: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e tStringResult(in
5d10: 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 72 terp));....retur
5d20: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65 n(-EIO);..}...re
5d30: 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 al_path = Tcl_Ge
5d40: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e tStringResult(in
5d50: 74 65 72 70 29 3b 0a 09 69 66 20 28 72 65 61 6c terp);..if (real
5d60: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b _path == NULL) {
5d70: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b ...return(-EIO);
5d80: 0a 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 ..}...APPFS_DEBU
5d90: 47 28 22 54 72 61 6e 73 6c 61 74 65 64 20 72 65 G("Translated re
5da0: 71 75 65 73 74 20 74 6f 20 6f 70 65 6e 20 25 73 quest to open %s
5db0: 20 74 6f 20 6f 70 65 6e 69 6e 67 20 25 73 20 28 to opening %s (
5dc0: 6d 6f 64 65 20 3d 20 5c 22 25 73 5c 22 29 22 2c mode = \"%s\")",
5dd0: 20 70 61 74 68 2c 20 72 65 61 6c 5f 70 61 74 68 path, real_path
5de0: 2c 20 6d 6f 64 65 29 3b 0a 0a 09 66 68 20 3d 20 , mode);...fh =
5df0: 6f 70 65 6e 28 72 65 61 6c 5f 70 61 74 68 2c 20 open(real_path,
5e00: 66 69 2d 3e 66 6c 61 67 73 2c 20 30 36 30 30 29 fi->flags, 0600)
5e10: 3b 0a 0a 09 69 66 20 28 66 68 20 3c 20 30 29 20 ;...if (fh < 0)
5e20: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 {...return(-EIO)
5e30: 3b 0a 09 7d 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 ;..}...fi->fh =
5e40: 66 68 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b fh;...return(0);
5e50: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 .}..static int a
5e60: 70 70 66 73 5f 66 75 73 65 5f 63 6c 6f 73 65 28 ppfs_fuse_close(
5e70: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 const char *path
5e80: 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 , struct fuse_fi
5e90: 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 le_info *fi) {..
5ea0: 69 6e 74 20 63 6c 6f 73 65 5f 72 65 74 3b 0a 0a int close_ret;..
5eb0: 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f .appfs_get_path_
5ec0: 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 info_cache_rm(pa
5ed0: 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 73 th, appfs_get_fs
5ee0: 75 69 64 28 29 29 3b 0a 0a 09 63 6c 6f 73 65 5f uid());...close_
5ef0: 72 65 74 20 3d 20 63 6c 6f 73 65 28 66 69 2d 3e ret = close(fi->
5f00: 66 68 29 3b 0a 09 69 66 20 28 63 6c 6f 73 65 5f fh);..if (close_
5f10: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 ret != 0) {...re
5f20: 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a turn(-EIO);..}..
5f30: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 .return(0);.}..s
5f40: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f tatic int appfs_
5f50: 66 75 73 65 5f 72 65 61 64 28 63 6f 6e 73 74 20 fuse_read(const
5f60: 63 68 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72 char *path, char
5f70: 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 *buf, size_t si
5f80: 7a 65 2c 20 6f 66 66 5f 74 20 6f 66 66 73 65 74 ze, off_t offset
5f90: 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 , struct fuse_fi
5fa0: 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 le_info *fi) {..
5fb0: 6f 66 66 5f 74 20 6c 73 65 65 6b 5f 72 65 74 3b off_t lseek_ret;
5fc0: 0a 09 73 73 69 7a 65 5f 74 20 72 65 61 64 5f 72 ..ssize_t read_r
5fd0: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 et;...APPFS_DEBU
5fe0: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d G("Enter (path =
5ff0: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 %s, ...)", path
6000: 29 3b 0a 0a 09 6c 73 65 65 6b 5f 72 65 74 20 3d );...lseek_ret =
6010: 20 6c 73 65 65 6b 28 66 69 2d 3e 66 68 2c 20 6f lseek(fi->fh, o
6020: 66 66 73 65 74 2c 20 53 45 45 4b 5f 53 45 54 29 ffset, SEEK_SET)
6030: 3b 0a 09 69 66 20 28 6c 73 65 65 6b 5f 72 65 74 ;..if (lseek_ret
6040: 20 21 3d 20 6f 66 66 73 65 74 29 20 7b 0a 09 09 != offset) {...
6050: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d return(-EIO);..}
6060: 0a 0a 09 72 65 61 64 5f 72 65 74 20 3d 20 72 65 ...read_ret = re
6070: 61 64 28 66 69 2d 3e 66 68 2c 20 62 75 66 2c 20 ad(fi->fh, buf,
6080: 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72 6e 28 size);...return(
6090: 72 65 61 64 5f 72 65 74 29 3b 0a 7d 0a 0a 73 74 read_ret);.}..st
60a0: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 atic int appfs_f
60b0: 75 73 65 5f 77 72 69 74 65 28 63 6f 6e 73 74 20 use_write(const
60c0: 63 68 61 72 20 2a 70 61 74 68 2c 20 63 6f 6e 73 char *path, cons
60d0: 74 20 63 68 61 72 20 2a 62 75 66 2c 20 73 69 7a t char *buf, siz
60e0: 65 5f 74 20 73 69 7a 65 2c 20 6f 66 66 5f 74 20 e_t size, off_t
60f0: 6f 66 66 73 65 74 2c 20 73 74 72 75 63 74 20 66 offset, struct f
6100: 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 use_file_info *f
6110: 69 29 20 7b 0a 09 6f 66 66 5f 74 20 6c 73 65 65 i) {..off_t lsee
6120: 6b 5f 72 65 74 3b 0a 09 73 73 69 7a 65 5f 74 20 k_ret;..ssize_t
6130: 77 72 69 74 65 5f 72 65 74 3b 0a 0a 09 41 50 50 write_ret;...APP
6140: 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 FS_DEBUG("Enter
6150: 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 (path = %s, ...)
6160: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 ", path);...appf
6170: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f s_get_path_info_
6180: 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 cache_rm(path, a
6190: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 ppfs_get_fsuid()
61a0: 29 3b 0a 0a 09 6c 73 65 65 6b 5f 72 65 74 20 3d );...lseek_ret =
61b0: 20 6c 73 65 65 6b 28 66 69 2d 3e 66 68 2c 20 6f lseek(fi->fh, o
61c0: 66 66 73 65 74 2c 20 53 45 45 4b 5f 53 45 54 29 ffset, SEEK_SET)
61d0: 3b 0a 09 69 66 20 28 6c 73 65 65 6b 5f 72 65 74 ;..if (lseek_ret
61e0: 20 21 3d 20 6f 66 66 73 65 74 29 20 7b 0a 09 09 != offset) {...
61f0: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d return(-EIO);..}
6200: 0a 0a 09 77 72 69 74 65 5f 72 65 74 20 3d 20 77 ...write_ret = w
6210: 72 69 74 65 28 66 69 2d 3e 66 68 2c 20 62 75 66 rite(fi->fh, buf
6220: 2c 20 73 69 7a 65 29 3b 0a 0a 09 72 65 74 75 72 , size);...retur
6230: 6e 28 77 72 69 74 65 5f 72 65 74 29 3b 0a 7d 0a n(write_ret);.}.
6240: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 .static int appf
6250: 73 5f 66 75 73 65 5f 6d 6b 6e 6f 64 28 63 6f 6e s_fuse_mknod(con
6260: 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 6d st char *path, m
6270: 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 64 65 76 5f ode_t mode, dev_
6280: 74 20 64 65 76 69 63 65 29 20 7b 0a 09 63 68 61 t device) {..cha
6290: 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 r *real_path;..i
62a0: 6e 74 20 6d 6b 6e 6f 64 5f 72 65 74 3b 0a 0a 09 nt mknod_ret;...
62b0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 APPFS_DEBUG("Ent
62c0: 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e er (path = %s, .
62d0: 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69 ..)", path);...i
62e0: 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 43 f ((mode & S_IFC
62f0: 48 52 29 20 3d 3d 20 53 5f 49 46 43 48 52 29 20 HR) == S_IFCHR)
6300: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45 52 {...return(-EPER
6310: 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 6d 6f M);..}...if ((mo
6320: 64 65 20 26 20 53 5f 49 46 42 4c 4b 29 20 3d 3d de & S_IFBLK) ==
6330: 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09 72 65 S_IFBLK) {...re
6340: 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d turn(-EPERM);..}
6350: 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 ...real_path = a
6360: 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f ppfs_prepare_to_
6370: 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a 09 69 create(path);..i
6380: 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 f (real_path ==
6390: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e NULL) {...return
63a0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 (-EIO);..}...app
63b0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 fs_simulate_user
63c0: 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 6d _fs_enter();...m
63d0: 6b 6e 6f 64 5f 72 65 74 20 3d 20 6d 6b 6e 6f 64 knod_ret = mknod
63e0: 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 (real_path, mode
63f0: 2c 20 64 65 76 69 63 65 29 3b 0a 0a 09 61 70 70 , device);...app
6400: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 fs_simulate_user
6410: 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 _fs_leave();...f
6420: 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a ree(real_path);.
6430: 0a 09 69 66 20 28 6d 6b 6e 6f 64 5f 72 65 74 20 ..if (mknod_ret
6440: 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e != 0) {...return
6450: 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d (errno * -1);..}
6460: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a ...return(0);.}.
6470: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 .static int appf
6480: 73 5f 66 75 73 65 5f 63 72 65 61 74 65 28 63 6f s_fuse_create(co
6490: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 nst char *path,
64a0: 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 73 74 72 mode_t mode, str
64b0: 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e uct fuse_file_in
64c0: 66 6f 20 2a 66 69 29 20 7b 0a 09 63 68 61 72 20 fo *fi) {..char
64d0: 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 *real_path;..int
64e0: 20 66 64 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 fd;...APPFS_DEB
64f0: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 UG("Enter (path
6500: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 = %s, ...)", pat
6510: 68 29 3b 0a 0a 09 69 66 20 28 28 6d 6f 64 65 20 h);...if ((mode
6520: 26 20 53 5f 49 46 43 48 52 29 20 3d 3d 20 53 5f & S_IFCHR) == S_
6530: 49 46 43 48 52 29 20 7b 0a 09 09 72 65 74 75 72 IFCHR) {...retur
6540: 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 n(-EPERM);..}...
6550: 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 46 if ((mode & S_IF
6560: 42 4c 4b 29 20 3d 3d 20 53 5f 49 46 42 4c 4b 29 BLK) == S_IFBLK)
6570: 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 45 {...return(-EPE
6580: 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c 5f 70 RM);..}...real_p
6590: 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70 ath = appfs_prep
65a0: 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 70 61 are_to_create(pa
65b0: 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 th);..if (real_p
65c0: 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 ath == NULL) {..
65d0: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 .return(-EIO);..
65e0: 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 }...appfs_simula
65f0: 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 te_user_fs_enter
6600: 28 29 3b 0a 0a 09 66 64 20 3d 20 63 72 65 61 74 ();...fd = creat
6610: 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f 64 65 (real_path, mode
6620: 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c );...appfs_simul
6630: 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 61 76 ate_user_fs_leav
6640: 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 61 6c e();...free(real
6650: 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 66 64 _path);...if (fd
6660: 20 3c 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e < 0) {...return
6670: 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d (errno * -1);..}
6680: 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66 64 3b 0a ...fi->fh = fd;.
6690: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a ..return(0);.}..
66a0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 static int appfs
66b0: 5f 66 75 73 65 5f 74 72 75 6e 63 61 74 65 28 63 _fuse_truncate(c
66c0: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c onst char *path,
66d0: 20 6f 66 66 5f 74 20 73 69 7a 65 29 20 7b 0a 09 off_t size) {..
66e0: 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b char *real_path;
66f0: 0a 09 69 6e 74 20 74 72 75 6e 63 61 74 65 5f 72 ..int truncate_r
6700: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 et;...APPFS_DEBU
6710: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d G("Enter (path =
6720: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 %s, ...)", path
6730: 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d );...real_path =
6740: 20 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61 74 68 appfs_localpath
6750: 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 (path);..if (rea
6760: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 l_path == NULL)
6770: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 {...return(-EIO)
6780: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67 65 74 ;..}...appfs_get
6790: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 _path_info_cache
67a0: 5f 72 6d 28 70 61 74 68 2c 20 61 70 70 66 73 5f _rm(path, appfs_
67b0: 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 get_fsuid());...
67c0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 appfs_simulate_u
67d0: 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a ser_fs_enter();.
67e0: 0a 09 74 72 75 6e 63 61 74 65 5f 72 65 74 20 3d ..truncate_ret =
67f0: 20 74 72 75 6e 63 61 74 65 28 72 65 61 6c 5f 70 truncate(real_p
6800: 61 74 68 2c 20 73 69 7a 65 29 3b 0a 0a 09 61 70 ath, size);...ap
6810: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 pfs_simulate_use
6820: 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 r_fs_leave();...
6830: 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b free(real_path);
6840: 0a 0a 09 69 66 20 28 74 72 75 6e 63 61 74 65 5f ...if (truncate_
6850: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 ret != 0) {...re
6860: 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 turn(errno * -1)
6870: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 ;..}...return(0)
6880: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 ;.}..static int
6890: 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e appfs_fuse_unlin
68a0: 6b 5f 72 6d 64 69 72 28 63 6f 6e 73 74 20 63 68 k_rmdir(const ch
68b0: 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c ar *path) {..Tcl
68c0: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b _Interp *interp;
68d0: 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a ..int tcl_ret;..
68e0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e .APPFS_DEBUG("En
68f0: 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 ter (path = %s,
6900: 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 ...)", path);...
6910: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 appfs_get_path_i
6920: 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 nfo_cache_flush(
6930: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 appfs_get_fsuid(
6940: 29 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74 65 72 70 ), -1);...interp
6950: 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 = appfs_TclInte
6960: 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 rp();..if (inter
6970: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 p == NULL) {...r
6980: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a eturn(-EIO);..}.
6990: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 ..tcl_ret = appf
69a0: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 s_Tcl_Eval(inter
69b0: 70 2c 20 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a p, 2, "::appfs::
69c0: 75 6e 6c 69 6e 6b 70 61 74 68 22 2c 20 70 61 74 unlinkpath", pat
69d0: 68 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 h);..if (tcl_ret
69e0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 != TCL_OK) {...
69f0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 APPFS_DEBUG("::a
6a00: 70 70 66 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68 ppfs::unlinkpath
6a10: 28 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 (%s) failed.", p
6a20: 61 74 68 29 3b 0a 09 09 41 50 50 46 53 5f 44 45 ath);...APPFS_DE
6a30: 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 BUG("Tcl Error i
6a40: 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 s: %s", Tcl_GetS
6a50: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 tringResult(inte
6a60: 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 rp));....return(
6a70: 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 -EIO);..}...retu
6a80: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 rn(0);.}..static
6a90: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f int appfs_fuse_
6aa0: 6d 6b 64 69 72 28 63 6f 6e 73 74 20 63 68 61 72 mkdir(const char
6ab0: 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d *path, mode_t m
6ac0: 6f 64 65 29 20 7b 0a 09 63 68 61 72 20 2a 72 65 ode) {..char *re
6ad0: 61 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 6d 6b al_path;..int mk
6ae0: 64 69 72 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 dir_ret;...APPFS
6af0: 5f 44 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 _DEBUG("Enter (p
6b00: 61 74 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c ath = %s, ...)",
6b10: 20 70 61 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 path);...real_p
6b20: 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72 65 70 ath = appfs_prep
6b30: 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 70 61 are_to_create(pa
6b40: 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c 5f 70 th);..if (real_p
6b50: 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 ath == NULL) {..
6b60: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 .return(-EIO);..
6b70: 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 }...appfs_simula
6b80: 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 te_user_fs_enter
6b90: 28 29 3b 0a 0a 09 6d 6b 64 69 72 5f 72 65 74 20 ();...mkdir_ret
6ba0: 3d 20 6d 6b 64 69 72 28 72 65 61 6c 5f 70 61 74 = mkdir(real_pat
6bb0: 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61 70 70 66 h, mode);...appf
6bc0: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f s_simulate_user_
6bd0: 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 fs_leave();...fr
6be0: 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a ee(real_path);..
6bf0: 09 69 66 20 28 6d 6b 64 69 72 5f 72 65 74 20 21 .if (mkdir_ret !
6c00: 3d 20 30 29 20 7b 0a 09 09 69 66 20 28 65 72 72 = 0) {...if (err
6c10: 6e 6f 20 21 3d 20 45 45 58 49 53 54 29 20 7b 0a no != EEXIST) {.
6c20: 09 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 ...return(errno
6c30: 2a 20 2d 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 * -1);...}..}...
6c40: 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 return(0);.}..st
6c50: 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 atic int appfs_f
6c60: 75 73 65 5f 63 68 6d 6f 64 28 63 6f 6e 73 74 20 use_chmod(const
6c70: 63 68 61 72 20 2a 70 61 74 68 2c 20 6d 6f 64 65 char *path, mode
6c80: 5f 74 20 6d 6f 64 65 29 20 7b 0a 09 54 63 6c 5f _t mode) {..Tcl_
6c90: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a Interp *interp;.
6ca0: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 .const char *rea
6cb0: 6c 5f 70 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c l_path;..int tcl
6cc0: 5f 72 65 74 2c 20 63 68 6d 6f 64 5f 72 65 74 3b _ret, chmod_ret;
6cd0: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 ...APPFS_DEBUG("
6ce0: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 Enter (path = %s
6cf0: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a , ...)", path);.
6d00: 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 ..appfs_get_path
6d10: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d 28 70 _info_cache_rm(p
6d20: 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74 5f 66 ath, appfs_get_f
6d30: 73 75 69 64 28 29 29 3b 0a 0a 09 69 6e 74 65 72 suid());...inter
6d40: 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 p = appfs_TclInt
6d50: 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 erp();..if (inte
6d60: 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 rp == NULL) {...
6d70: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d return(-EIO);..}
6d80: 0a 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 ...tcl_ret = app
6d90: 66 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 fs_Tcl_Eval(inte
6da0: 72 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a rp, 3, "::appfs:
6db0: 3a 6f 70 65 6e 70 61 74 68 22 2c 20 70 61 74 68 :openpath", path
6dc0: 2c 20 22 77 72 69 74 65 22 29 3b 0a 09 69 66 20 , "write");..if
6dd0: 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f (tcl_ret != TCL_
6de0: 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 OK) {...APPFS_DE
6df0: 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 BUG("::appfs::op
6e00: 65 6e 70 61 74 68 28 25 73 2c 20 25 73 29 20 66 enpath(%s, %s) f
6e10: 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 2c 20 22 ailed.", path, "
6e20: 77 72 69 74 65 22 29 3b 0a 09 09 41 50 50 46 53 write");...APPFS
6e30: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f _DEBUG("Tcl Erro
6e40: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 r is: %s", Tcl_G
6e50: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 etStringResult(i
6e60: 6e 74 65 72 70 29 29 3b 0a 0a 09 09 72 65 74 75 nterp));....retu
6e70: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 72 rn(-EIO);..}...r
6e80: 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 eal_path = Tcl_G
6e90: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 etStringResult(i
6ea0: 6e 74 65 72 70 29 3b 0a 09 69 66 20 28 72 65 61 nterp);..if (rea
6eb0: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 l_path == NULL)
6ec0: 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 {...return(-EIO)
6ed0: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d ;..}...appfs_sim
6ee0: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e ulate_user_fs_en
6ef0: 74 65 72 28 29 3b 0a 0a 09 63 68 6d 6f 64 5f 72 ter();...chmod_r
6f00: 65 74 20 3d 20 63 68 6d 6f 64 28 72 65 61 6c 5f et = chmod(real_
6f10: 70 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61 path, mode);...a
6f20: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 ppfs_simulate_us
6f30: 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a er_fs_leave();..
6f40: 09 72 65 74 75 72 6e 28 63 68 6d 6f 64 5f 72 65 .return(chmod_re
6f50: 74 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 53 51 4c t);.}../*. * SQL
6f60: 69 74 65 33 20 6d 6f 64 65 3a 20 45 78 65 63 75 ite3 mode: Execu
6f70: 74 65 20 72 61 77 20 53 51 4c 20 61 6e 64 20 72 te raw SQL and r
6f80: 65 74 75 72 6e 20 73 75 63 63 65 73 73 20 6f 72 eturn success or
6f90: 20 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74 61 failure. */.sta
6fa0: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 73 71 tic int appfs_sq
6fb0: 6c 69 74 65 33 28 63 6f 6e 73 74 20 63 68 61 72 lite3(const char
6fc0: 20 2a 73 71 6c 29 20 7b 0a 09 54 63 6c 5f 49 6e *sql) {..Tcl_In
6fd0: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 terp *interp;..c
6fe0: 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 5f 72 onst char *sql_r
6ff0: 65 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 et;..int tcl_ret
7000: 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 ;...interp = app
7010: 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 fs_create_TclInt
7020: 65 72 70 28 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 erp(NULL);..if (
7030: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 interp == NULL)
7040: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 {...fprintf(stde
7050: 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 rr, "Unable to c
7060: 72 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65 reate a Tcl inte
7070: 72 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69 rpreter. Aborti
7080: 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75 ng.\n");....retu
7090: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f rn(1);..}...tcl_
70a0: 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f ret = appfs_Tcl_
70b0: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 35 2c 20 Eval(interp, 5,
70c0: 22 3a 3a 61 70 70 66 73 3a 3a 64 62 22 2c 20 22 "::appfs::db", "
70d0: 65 76 61 6c 22 2c 20 73 71 6c 2c 20 22 72 6f 77 eval", sql, "row
70e0: 22 2c 20 22 75 6e 73 65 74 20 2d 6e 6f 63 6f 6d ", "unset -nocom
70f0: 70 6c 61 69 6e 20 72 6f 77 28 2a 29 3b 20 70 61 plain row(*); pa
7100: 72 72 61 79 20 72 6f 77 3b 20 70 75 74 73 20 5c rray row; puts \
7110: 22 2d 2d 2d 2d 5c 22 22 29 3b 0a 09 73 71 6c 5f "----\"");..sql_
7120: 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 ret = Tcl_GetStr
7130: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 ingResult(interp
7140: 29 3b 0a 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 );...if (tcl_ret
7150: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 != TCL_OK) {...
7160: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 fprintf(stderr,
7170: 22 5b 65 72 72 6f 72 5d 20 25 73 5c 6e 22 2c 20 "[error] %s\n",
7180: 73 71 6c 5f 72 65 74 29 3b 0a 0a 09 09 72 65 74 sql_ret);....ret
7190: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 urn(1);..}...if
71a0: 28 73 71 6c 5f 72 65 74 20 26 26 20 73 71 6c 5f (sql_ret && sql_
71b0: 72 65 74 5b 30 5d 20 21 3d 20 27 5c 30 27 29 20 ret[0] != '\0')
71c0: 7b 0a 09 09 70 72 69 6e 74 66 28 22 25 73 5c 6e {...printf("%s\n
71d0: 22 2c 20 73 71 6c 5f 72 65 74 29 3b 0a 09 7d 0a ", sql_ret);..}.
71e0: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a ..return(0);.}..
71f0: 2f 2a 0a 20 2a 20 54 63 6c 20 6d 6f 64 65 3a 20 /*. * Tcl mode:
7200: 45 78 65 63 75 74 65 20 72 61 77 20 54 63 6c 20 Execute raw Tcl
7210: 61 6e 64 20 72 65 74 75 72 6e 20 73 75 63 63 65 and return succe
7220: 73 73 20 6f 72 20 66 61 69 6c 75 72 65 0a 20 2a ss or failure. *
7230: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 /.static int app
7240: 66 73 5f 74 63 6c 28 63 6f 6e 73 74 20 63 68 61 fs_tcl(const cha
7250: 72 20 2a 74 63 6c 29 20 7b 0a 09 54 63 6c 5f 49 r *tcl) {..Tcl_I
7260: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 nterp *interp;..
7270: 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c 5f const char *tcl_
7280: 72 65 73 75 6c 74 3b 0a 09 69 6e 74 20 74 63 6c result;..int tcl
7290: 5f 72 65 74 3b 0a 0a 09 69 6e 74 65 72 70 20 3d _ret;...interp =
72a0: 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63 appfs_create_Tc
72b0: 6c 49 6e 74 65 72 70 28 4e 55 4c 4c 29 3b 0a 09 lInterp(NULL);..
72c0: 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 if (interp == NU
72d0: 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 LL) {...fprintf(
72e0: 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 stderr, "Unable
72f0: 74 6f 20 63 72 65 61 74 65 20 61 20 54 63 6c 20 to create a Tcl
7300: 69 6e 74 65 72 70 72 65 74 65 72 2e 20 20 41 62 interpreter. Ab
7310: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 orting.\n");....
7320: 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 return(1);..}...
7330: 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 76 tcl_ret = Tcl_Ev
7340: 61 6c 28 69 6e 74 65 72 70 2c 20 74 63 6c 29 3b al(interp, tcl);
7350: 0a 09 74 63 6c 5f 72 65 73 75 6c 74 20 3d 20 54 ..tcl_result = T
7360: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 cl_GetStringResu
7370: 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 69 66 lt(interp);...if
7380: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c (tcl_ret != TCL
7390: 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 _OK) {...fprintf
73a0: 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72 6f 72 (stderr, "[error
73b0: 5d 20 25 73 5c 6e 22 2c 20 74 63 6c 5f 72 65 73 ] %s\n", tcl_res
73c0: 75 6c 74 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 ult);....return(
73d0: 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 74 63 6c 1);..}...if (tcl
73e0: 5f 72 65 73 75 6c 74 20 26 26 20 74 63 6c 5f 72 _result && tcl_r
73f0: 65 73 75 6c 74 5b 30 5d 20 21 3d 20 27 5c 30 27 esult[0] != '\0'
7400: 29 20 7b 0a 09 09 70 72 69 6e 74 66 28 22 25 73 ) {...printf("%s
7410: 5c 6e 22 2c 20 74 63 6c 5f 72 65 73 75 6c 74 29 \n", tcl_result)
7420: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 ;..}...return(0)
7430: 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 53 ;.}../*. * AppFS
7440: 64 20 50 61 63 6b 61 67 65 20 66 6f 72 20 54 63 d Package for Tc
7450: 6c 3a 0a 20 2a 20 20 20 20 20 20 20 20 20 42 72 l:. * Br
7460: 69 64 67 65 20 66 6f 72 20 49 2f 4f 20 6f 70 65 idge for I/O ope
7470: 72 61 74 69 6f 6e 73 20 74 6f 20 72 65 71 75 65 rations to reque
7480: 73 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 st information a
7490: 62 6f 75 74 20 74 68 65 20 63 75 72 72 65 6e 74 bout the current
74a0: 0a 20 2a 20 20 20 20 20 20 20 20 20 74 72 61 6e . * tran
74b0: 73 61 63 74 69 6f 6e 0a 20 2a 2f 0a 2f 2a 0a 20 saction. */./*.
74c0: 2a 20 54 63 6c 20 69 6e 74 65 72 66 61 63 65 20 * Tcl interface
74d0: 74 6f 20 67 65 74 20 74 68 65 20 68 6f 6d 65 20 to get the home
74e0: 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20 74 68 directory for th
74f0: 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 e user making th
7500: 65 20 22 63 75 72 72 65 6e 74 22 0a 20 2a 20 46 e "current". * F
7510: 55 53 45 20 49 2f 4f 20 72 65 71 75 65 73 74 0a USE I/O request.
7520: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 */.static int t
7530: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d cl_appfs_get_hom
7540: 65 64 69 72 28 43 6c 69 65 6e 74 44 61 74 61 20 edir(ClientData
7550: 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a cd, Tcl_Interp *
7560: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 interp, int objc
7570: 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 , Tcl_Obj *CONST
7580: 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 63 68 61 72 objv[]) {..char
7590: 20 2a 68 6f 6d 65 64 69 72 3b 0a 09 54 63 6c 5f *homedir;..Tcl_
75a0: 4f 62 6a 20 2a 68 6f 6d 65 64 69 72 5f 6f 62 6a Obj *homedir_obj
75b0: 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b 0a ;..uid_t fsuid;.
75c0: 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61 64 .static __thread
75d0: 20 54 63 6c 5f 4f 62 6a 20 2a 6c 61 73 74 5f 68 Tcl_Obj *last_h
75e0: 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 4e 55 4c omedir_obj = NUL
75f0: 4c 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 L;..static __thr
7600: 65 61 64 20 75 69 64 5f 74 20 6c 61 73 74 5f 66 ead uid_t last_f
7610: 73 75 69 64 20 3d 20 2d 31 3b 0a 0a 20 20 20 20 suid = -1;..
7620: 20 20 20 20 69 66 20 28 6f 62 6a 63 20 21 3d 20 if (objc !=
7630: 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 20 1) {.
7640: 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 Tcl_WrongNu
7650: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c mArgs(interp, 1,
7660: 20 6f 62 6a 76 2c 20 4e 55 4c 4c 29 3b 0a 20 20 objv, NULL);.
7670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72 65 re
7680: 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b turn(TCL_ERROR);
7690: 0a 20 20 20 20 20 20 20 20 7d 0a 0a 09 66 73 75 . }...fsu
76a0: 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 id = appfs_get_f
76b0: 73 75 69 64 28 29 3b 0a 0a 09 69 66 20 28 66 73 suid();...if (fs
76c0: 75 69 64 20 3d 3d 20 6c 61 73 74 5f 66 73 75 69 uid == last_fsui
76d0: 64 20 26 26 20 6c 61 73 74 5f 68 6f 6d 65 64 69 d && last_homedi
76e0: 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b r_obj != NULL) {
76f0: 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d ...homedir_obj =
7700: 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 last_homedir_ob
7710: 6a 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 68 j;..} else {...h
7720: 6f 6d 65 64 69 72 20 3d 20 61 70 70 66 73 5f 67 omedir = appfs_g
7730: 65 74 5f 68 6f 6d 65 64 69 72 28 61 70 70 66 73 et_homedir(appfs
7740: 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a 0a _get_fsuid());..
7750: 09 09 69 66 20 28 68 6f 6d 65 64 69 72 20 3d 3d ..if (homedir ==
7760: 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72 65 74 75 NULL) {....retu
7770: 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 rn(TCL_ERROR);..
7780: 09 7d 0a 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 .}....homedir_ob
7790: 6a 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e j = Tcl_NewStrin
77a0: 67 4f 62 6a 28 68 6f 6d 65 64 69 72 2c 20 2d 31 gObj(homedir, -1
77b0: 29 3b 0a 0a 09 09 66 72 65 65 28 68 6f 6d 65 64 );....free(homed
77c0: 69 72 29 3b 0a 0a 09 09 69 66 20 28 6c 61 73 74 ir);....if (last
77d0: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 21 3d 20 _homedir_obj !=
77e0: 4e 55 4c 4c 29 20 7b 0a 09 09 09 54 63 6c 5f 44 NULL) {....Tcl_D
77f0: 65 63 72 52 65 66 43 6f 75 6e 74 28 6c 61 73 74 ecrRefCount(last
7800: 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a 29 3b 0a 09 _homedir_obj);..
7810: 09 7d 0a 0a 09 09 6c 61 73 74 5f 68 6f 6d 65 64 .}....last_homed
7820: 69 72 5f 6f 62 6a 20 3d 20 68 6f 6d 65 64 69 72 ir_obj = homedir
7830: 5f 6f 62 6a 3b 0a 09 09 6c 61 73 74 5f 66 73 75 _obj;...last_fsu
7840: 69 64 20 3d 20 66 73 75 69 64 3b 0a 0a 09 09 54 id = fsuid;....T
7850: 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 cl_IncrRefCount(
7860: 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 6a last_homedir_obj
7870: 29 3b 0a 09 7d 0a 0a 20 20 20 20 20 20 20 09 54 );..}.. .T
7880: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 cl_SetObjResult(
7890: 69 6e 74 65 72 70 2c 20 68 6f 6d 65 64 69 72 5f interp, homedir_
78a0: 6f 62 6a 29 3b 0a 0a 20 20 20 20 20 20 20 20 72 obj);.. r
78b0: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d eturn(TCL_OK);.}
78c0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c ..static int tcl
78d0: 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f _appfs_simulate_
78e0: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 43 6c user_fs_enter(Cl
78f0: 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 6c ientData cd, Tcl
7900: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c _Interp *interp,
7910: 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f 4f int objc, Tcl_O
7920: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d bj *CONST objv[]
7930: 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c ) {..appfs_simul
7940: 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 ate_user_fs_ente
7950: 72 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 r();...return(TC
7960: 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 L_OK);.}..static
7970: 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f 73 int tcl_appfs_s
7980: 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f imulate_user_fs_
7990: 6c 65 61 76 65 28 43 6c 69 65 6e 74 44 61 74 61 leave(ClientData
79a0: 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 cd, Tcl_Interp
79b0: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a *interp, int obj
79c0: 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 c, Tcl_Obj *CONS
79d0: 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70 70 T objv[]) {..app
79e0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 fs_simulate_user
79f0: 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 72 _fs_leave();...r
7a00: 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d eturn(TCL_OK);.}
7a10: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 6c ..static int tcl
7a20: 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 _appfs_get_fsuid
7a30: 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 (ClientData cd,
7a40: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 Tcl_Interp *inte
7a50: 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 rp, int objc, Tc
7a60: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a l_Obj *CONST obj
7a70: 76 5b 5d 29 20 7b 0a 09 75 69 64 5f 74 20 66 73 v[]) {..uid_t fs
7a80: 75 69 64 3b 0a 0a 09 66 73 75 69 64 20 3d 20 61 uid;...fsuid = a
7a90: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 ppfs_get_fsuid()
7aa0: 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f 53 ;.. .Tcl_S
7ab0: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 etObjResult(inte
7ac0: 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65 49 rp, Tcl_NewWideI
7ad0: 6e 74 4f 62 6a 28 66 73 75 69 64 29 29 3b 0a 0a ntObj(fsuid));..
7ae0: 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b .return(TCL_OK);
7af0: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 .}..static int t
7b00: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 67 cl_appfs_get_fsg
7b10: 69 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 id(ClientData cd
7b20: 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e , Tcl_Interp *in
7b30: 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 terp, int objc,
7b40: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f Tcl_Obj *CONST o
7b50: 62 6a 76 5b 5d 29 20 7b 0a 09 67 69 64 5f 74 20 bjv[]) {..gid_t
7b60: 66 73 67 69 64 3b 0a 0a 09 66 73 67 69 64 20 3d fsgid;...fsgid =
7b70: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 appfs_get_fsgid
7b80: 28 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c ();.. .Tcl
7b90: 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e _SetObjResult(in
7ba0: 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64 terp, Tcl_NewWid
7bb0: 65 49 6e 74 4f 62 6a 28 66 73 67 69 64 29 29 3b eIntObj(fsgid));
7bc0: 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b ...return(TCL_OK
7bd0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 );.}..static int
7be0: 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 70 tcl_appfs_get_p
7bf0: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 ath_info_cache_f
7c00: 6c 75 73 68 28 43 6c 69 65 6e 74 44 61 74 61 20 lush(ClientData
7c10: 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a cd, Tcl_Interp *
7c20: 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 interp, int objc
7c30: 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 , Tcl_Obj *CONST
7c40: 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 69 6e 74 20 objv[]) {..int
7c50: 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 6e 65 tcl_ret;..int ne
7c60: 77 5f 73 69 7a 65 3b 0a 0a 09 6e 65 77 5f 73 69 w_size;...new_si
7c70: 7a 65 20 3d 20 2d 31 3b 0a 0a 09 69 66 20 28 6f ze = -1;...if (o
7c80: 62 6a 63 20 3d 3d 20 32 29 20 7b 0a 09 09 74 63 bjc == 2) {...tc
7c90: 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 49 l_ret = Tcl_GetI
7ca0: 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 ntFromObj(interp
7cb0: 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26 6e 65 77 5f , objv[1], &new_
7cc0: 73 69 7a 65 29 3b 0a 09 09 69 66 20 28 74 63 6c size);...if (tcl
7cd0: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 _ret != TCL_OK)
7ce0: 7b 0a 09 09 09 72 65 74 75 72 6e 28 74 63 6c 5f {....return(tcl_
7cf0: 72 65 74 29 3b 0a 09 09 7d 0a 09 7d 20 65 6c 73 ret);...}..} els
7d00: 65 20 69 66 20 28 6f 62 6a 63 20 3e 20 32 20 7c e if (objc > 2 |
7d10: 7c 20 6f 62 6a 63 20 3c 20 31 29 20 7b 0a 20 20 | objc < 1) {.
7d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 63 Tc
7d30: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 l_WrongNumArgs(i
7d40: 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 nterp, 1, objv,
7d50: 22 3f 6e 65 77 5f 63 61 63 68 65 5f 73 69 7a 65 "?new_cache_size
7d60: 3f 22 29 3b 0a 09 09 72 65 74 75 72 6e 28 54 43 ?");...return(TC
7d70: 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09 61 L_ERROR);..}...a
7d80: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e ppfs_get_path_in
7d90: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d fo_cache_flush(-
7da0: 31 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a 09 1, new_size);...
7db0: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a return(TCL_OK);.
7dc0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 41 70 }..static int Ap
7dd0: 70 66 73 64 5f 49 6e 69 74 28 54 63 6c 5f 49 6e pfsd_Init(Tcl_In
7de0: 74 65 72 70 20 2a 69 6e 74 65 72 70 29 20 7b 0a terp *interp) {.
7df0: 23 69 66 64 65 66 20 55 53 45 5f 54 43 4c 5f 53 #ifdef USE_TCL_S
7e00: 54 55 42 53 0a 09 69 66 20 28 54 63 6c 5f 49 6e TUBS..if (Tcl_In
7e10: 69 74 53 74 75 62 73 28 69 6e 74 65 72 70 2c 20 itStubs(interp,
7e20: 54 43 4c 5f 56 45 52 53 49 4f 4e 2c 20 30 29 20 TCL_VERSION, 0)
7e30: 3d 3d 20 30 4c 29 20 7b 0a 09 09 72 65 74 75 72 == 0L) {...retur
7e40: 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d n(TCL_ERROR);..}
7e50: 0a 23 65 6e 64 69 66 0a 0a 09 54 63 6c 5f 43 72 .#endif...Tcl_Cr
7e60: 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 eateObjCommand(i
7e70: 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a nterp, "appfsd::
7e80: 67 65 74 5f 68 6f 6d 65 64 69 72 22 2c 20 74 63 get_homedir", tc
7e90: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d 65 l_appfs_get_home
7ea0: 64 69 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 dir, NULL, NULL)
7eb0: 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a ;..Tcl_CreateObj
7ec0: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 Command(interp,
7ed0: 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 66 73 75 "appfsd::get_fsu
7ee0: 69 64 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f 67 id", tcl_appfs_g
7ef0: 65 74 5f 66 73 75 69 64 2c 20 4e 55 4c 4c 2c 20 et_fsuid, NULL,
7f00: 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 61 NULL);..Tcl_Crea
7f10: 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 teObjCommand(int
7f20: 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 65 erp, "appfsd::ge
7f30: 74 5f 66 73 67 69 64 22 2c 20 74 63 6c 5f 61 70 t_fsgid", tcl_ap
7f40: 70 66 73 5f 67 65 74 5f 66 73 67 69 64 2c 20 4e pfs_get_fsgid, N
7f50: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c ULL, NULL);..Tcl
7f60: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e _CreateObjComman
7f70: 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 d(interp, "appfs
7f80: 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 d::simulate_user
7f90: 5f 66 73 5f 65 6e 74 65 72 22 2c 20 74 63 6c 5f _fs_enter", tcl_
7fa0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 appfs_simulate_u
7fb0: 73 65 72 5f 66 73 5f 65 6e 74 65 72 2c 20 4e 55 ser_fs_enter, NU
7fc0: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f LL, NULL);..Tcl_
7fd0: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 CreateObjCommand
7fe0: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 (interp, "appfsd
7ff0: 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f ::simulate_user_
8000: 66 73 5f 6c 65 61 76 65 22 2c 20 74 63 6c 5f 61 fs_leave", tcl_a
8010: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 ppfs_simulate_us
8020: 65 72 5f 66 73 5f 6c 65 61 76 65 2c 20 4e 55 4c er_fs_leave, NUL
8030: 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 L, NULL);..Tcl_C
8040: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 reateObjCommand(
8050: 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a interp, "appfsd:
8060: 3a 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 :get_path_info_c
8070: 61 63 68 65 5f 66 6c 75 73 68 22 2c 20 74 63 6c ache_flush", tcl
8080: 5f 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f _appfs_get_path_
8090: 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 info_cache_flush
80a0: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 0a , NULL, NULL);..
80b0: 09 54 63 6c 5f 50 6b 67 50 72 6f 76 69 64 65 28 .Tcl_PkgProvide(
80c0: 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 22 interp, "appfsd"
80d0: 2c 20 22 31 2e 30 22 29 3b 0a 0a 09 72 65 74 75 , "1.0");...retu
80e0: 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 2f rn(TCL_OK);.}../
80f0: 2a 0a 20 2a 20 46 55 53 45 20 6f 70 65 72 61 74 *. * FUSE operat
8100: 69 6f 6e 73 20 73 74 72 75 63 74 75 72 65 0a 20 ions structure.
8110: 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 75 63 74 */.static struct
8120: 20 66 75 73 65 5f 6f 70 65 72 61 74 69 6f 6e 73 fuse_operations
8130: 20 61 70 70 66 73 5f 6f 70 65 72 61 74 69 6f 6e appfs_operation
8140: 73 20 3d 20 7b 0a 09 2e 67 65 74 61 74 74 72 20 s = {...getattr
8150: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 67 = appfs_fuse_g
8160: 65 74 61 74 74 72 2c 0a 09 2e 72 65 61 64 64 69 etattr,...readdi
8170: 72 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 r = appfs_fuse
8180: 5f 72 65 61 64 64 69 72 2c 0a 09 2e 72 65 61 64 _readdir,...read
8190: 6c 69 6e 6b 20 20 3d 20 61 70 70 66 73 5f 66 75 link = appfs_fu
81a0: 73 65 5f 72 65 61 64 6c 69 6e 6b 2c 0a 09 2e 6f se_readlink,...o
81b0: 70 65 6e 20 20 20 20 20 20 3d 20 61 70 70 66 73 pen = appfs
81c0: 5f 66 75 73 65 5f 6f 70 65 6e 2c 0a 09 2e 72 65 _fuse_open,...re
81d0: 6c 65 61 73 65 20 20 20 3d 20 61 70 70 66 73 5f lease = appfs_
81e0: 66 75 73 65 5f 63 6c 6f 73 65 2c 0a 09 2e 72 65 fuse_close,...re
81f0: 61 64 20 20 20 20 20 20 3d 20 61 70 70 66 73 5f ad = appfs_
8200: 66 75 73 65 5f 72 65 61 64 2c 0a 09 2e 77 72 69 fuse_read,...wri
8210: 74 65 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 te = appfs_f
8220: 75 73 65 5f 77 72 69 74 65 2c 0a 09 2e 6d 6b 6e use_write,...mkn
8230: 6f 64 20 20 20 20 20 3d 20 61 70 70 66 73 5f 66 od = appfs_f
8240: 75 73 65 5f 6d 6b 6e 6f 64 2c 0a 09 2e 63 72 65 use_mknod,...cre
8250: 61 74 65 20 20 20 20 3d 20 61 70 70 66 73 5f 66 ate = appfs_f
8260: 75 73 65 5f 63 72 65 61 74 65 2c 0a 09 2e 74 72 use_create,...tr
8270: 75 6e 63 61 74 65 20 20 3d 20 61 70 70 66 73 5f uncate = appfs_
8280: 66 75 73 65 5f 74 72 75 6e 63 61 74 65 2c 0a 09 fuse_truncate,..
8290: 2e 75 6e 6c 69 6e 6b 20 20 20 20 3d 20 61 70 70 .unlink = app
82a0: 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f 72 fs_fuse_unlink_r
82b0: 6d 64 69 72 2c 0a 09 2e 72 6d 64 69 72 20 20 20 mdir,...rmdir
82c0: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 75 = appfs_fuse_u
82d0: 6e 6c 69 6e 6b 5f 72 6d 64 69 72 2c 0a 09 2e 6d nlink_rmdir,...m
82e0: 6b 64 69 72 20 20 20 20 20 3d 20 61 70 70 66 73 kdir = appfs
82f0: 5f 66 75 73 65 5f 6d 6b 64 69 72 2c 0a 09 2e 63 _fuse_mkdir,...c
8300: 68 6d 6f 64 20 20 20 20 20 3d 20 61 70 70 66 73 hmod = appfs
8310: 5f 66 75 73 65 5f 63 68 6d 6f 64 2c 0a 7d 3b 0a _fuse_chmod,.};.
8320: 0a 2f 2a 0a 20 2a 20 46 55 53 45 20 6f 70 74 69 ./*. * FUSE opti
8330: 6f 6e 20 70 61 72 73 69 6e 67 20 63 61 6c 6c 62 on parsing callb
8340: 61 63 6b 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 ack. */.static i
8350: 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f 6f 70 nt appfs_fuse_op
8360: 74 5f 63 62 28 76 6f 69 64 20 2a 64 61 74 61 2c t_cb(void *data,
8370: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 72 67 const char *arg
8380: 2c 20 69 6e 74 20 6b 65 79 2c 20 73 74 72 75 63 , int key, struc
8390: 74 20 66 75 73 65 5f 61 72 67 73 20 2a 6f 75 74 t fuse_args *out
83a0: 61 72 67 73 29 20 7b 0a 09 73 74 61 74 69 63 20 args) {..static
83b0: 69 6e 74 20 73 65 65 6e 5f 63 61 63 68 65 64 69 int seen_cachedi
83c0: 72 20 3d 20 30 3b 0a 0a 09 69 66 20 28 6b 65 79 r = 0;...if (key
83d0: 20 3d 3d 20 46 55 53 45 5f 4f 50 54 5f 4b 45 59 == FUSE_OPT_KEY
83e0: 5f 4e 4f 4e 4f 50 54 20 26 26 20 73 65 65 6e 5f _NONOPT && seen_
83f0: 63 61 63 68 65 64 69 72 20 3d 3d 20 30 29 20 7b cachedir == 0) {
8400: 0a 09 09 73 65 65 6e 5f 63 61 63 68 65 64 69 72 ...seen_cachedir
8410: 20 3d 20 31 3b 0a 0a 09 09 61 70 70 66 73 5f 63 = 1;....appfs_c
8420: 61 63 68 65 64 69 72 20 3d 20 73 74 72 64 75 70 achedir = strdup
8430: 28 61 72 67 29 3b 0a 0a 09 09 72 65 74 75 72 6e (arg);....return
8440: 28 30 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e (0);..}...return
8450: 28 31 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 45 6e (1);.}../*. * En
8460: 74 72 79 20 70 6f 69 6e 74 20 69 6e 74 6f 20 74 try point into t
8470: 68 69 73 20 70 72 6f 67 72 61 6d 2e 0a 20 2a 2f his program.. */
8480: 0a 69 6e 74 20 6d 61 69 6e 28 69 6e 74 20 61 72 .int main(int ar
8490: 67 63 2c 20 63 68 61 72 20 2a 2a 61 72 67 76 29 gc, char **argv)
84a0: 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a {..Tcl_Interp *
84b0: 74 65 73 74 5f 69 6e 74 65 72 70 3b 0a 09 63 68 test_interp;..ch
84c0: 61 72 20 2a 74 65 73 74 5f 69 6e 74 65 72 70 5f ar *test_interp_
84d0: 65 72 72 6f 72 3b 0a 09 73 74 72 75 63 74 20 66 error;..struct f
84e0: 75 73 65 5f 61 72 67 73 20 61 72 67 73 20 3d 20 use_args args =
84f0: 46 55 53 45 5f 41 52 47 53 5f 49 4e 49 54 28 61 FUSE_ARGS_INIT(a
8500: 72 67 63 2c 20 61 72 67 76 29 3b 0a 09 69 6e 74 rgc, argv);..int
8510: 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 pthread_ret;...
8520: 2f 2a 0a 09 20 2a 20 53 6b 69 70 20 70 61 73 73 /*.. * Skip pass
8530: 65 64 20 70 72 6f 67 72 61 6d 20 6e 61 6d 65 0a ed program name.
8540: 09 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d . */..if (argc =
8550: 3d 20 30 20 7c 7c 20 61 72 67 76 20 3d 3d 20 4e = 0 || argv == N
8560: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 ULL) {...return(
8570: 31 29 3b 0a 09 7d 0a 09 61 72 67 63 2d 2d 3b 0a 1);..}..argc--;.
8580: 09 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09 20 .argv++;.../*..
8590: 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 * Set global var
85a0: 69 61 62 6c 65 73 2c 20 74 68 65 73 65 20 73 68 iables, these sh
85b0: 6f 75 6c 64 20 62 65 20 63 6f 6e 66 69 67 75 72 ould be configur
85c0: 61 74 69 6f 6e 20 6f 70 74 69 6f 6e 73 2e 0a 09 ation options...
85d0: 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65 */..appfs_cache
85e0: 64 69 72 20 3d 20 41 50 50 46 53 5f 43 41 43 48 dir = APPFS_CACH
85f0: 45 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53 EDIR;.../*.. * S
8600: 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 et global variab
8610: 6c 65 20 66 6f 72 20 22 62 6f 6f 74 20 74 69 6d le for "boot tim
8620: 65 22 20 74 6f 20 73 65 74 20 61 20 74 69 6d 65 e" to set a time
8630: 20 6f 6e 20 64 69 72 65 63 74 6f 72 69 65 73 0a on directories.
8640: 09 20 2a 20 74 68 61 74 20 77 65 20 66 61 6b 65 . * that we fake
8650: 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 62 6f ... */..appfs_bo
8660: 6f 74 74 69 6d 65 20 3d 20 74 69 6d 65 28 4e 55 ottime = time(NU
8670: 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 LL);.../*.. * Re
8680: 67 69 73 74 65 72 20 22 73 68 61 31 22 20 61 6e gister "sha1" an
8690: 64 20 22 61 70 70 66 73 64 22 20 70 61 63 6b 61 d "appfsd" packa
86a0: 67 65 20 77 69 74 68 20 6c 69 62 74 63 6c 20 73 ge with libtcl s
86b0: 6f 20 74 68 61 74 20 61 6e 79 20 6e 65 77 0a 09 o that any new..
86c0: 20 2a 20 69 6e 74 65 72 70 72 65 74 65 72 73 20 * interpreters
86d0: 63 72 65 61 74 65 64 20 28 77 68 69 63 68 20 61 created (which a
86e0: 72 65 20 64 6f 6e 65 20 64 79 6e 61 6d 69 63 61 re done dynamica
86f0: 6c 6c 79 20 62 79 20 46 55 53 45 29 20 63 61 6e lly by FUSE) can
8700: 20 68 61 76 65 0a 09 20 2a 20 74 68 65 20 61 70 have.. * the ap
8710: 70 72 6f 70 72 69 61 74 65 20 63 6f 6e 66 69 67 propriate config
8720: 75 72 61 74 69 6f 6e 20 64 6f 6e 65 20 61 75 74 uration done aut
8730: 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 09 20 2a 2f omatically... */
8740: 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61 63 6b ..Tcl_StaticPack
8750: 61 67 65 28 4e 55 4c 4c 2c 20 22 73 68 61 31 22 age(NULL, "sha1"
8760: 2c 20 53 68 61 31 5f 49 6e 69 74 2c 20 4e 55 4c , Sha1_Init, NUL
8770: 4c 29 3b 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 L);..Tcl_StaticP
8780: 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 61 70 ackage(NULL, "ap
8790: 70 66 73 64 22 2c 20 41 70 70 66 73 64 5f 49 6e pfsd", Appfsd_In
87a0: 69 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a it, NULL);.../*.
87b0: 09 20 2a 20 43 72 65 61 74 65 20 61 20 74 68 72 . * Create a thr
87c0: 65 61 64 2d 73 70 65 63 69 66 69 63 2d 64 61 74 ead-specific-dat
87d0: 61 20 28 54 53 44 29 20 6b 65 79 20 66 6f 72 20 a (TSD) key for
87e0: 65 61 63 68 20 74 68 72 65 61 64 20 74 6f 20 72 each thread to r
87f0: 65 66 65 72 0a 09 20 2a 20 74 6f 20 69 74 73 20 efer.. * to its
8800: 6f 77 6e 20 54 63 6c 20 69 6e 74 65 72 70 72 65 own Tcl interpre
8810: 74 65 72 2e 20 20 54 63 6c 20 69 6e 74 65 72 70 ter. Tcl interp
8820: 72 65 74 65 72 73 20 6d 75 73 74 20 62 65 20 75 reters must be u
8830: 6e 69 71 75 65 20 70 65 72 0a 09 20 2a 20 74 68 nique per.. * th
8840: 72 65 61 64 20 61 6e 64 20 6e 65 77 20 74 68 72 read and new thr
8850: 65 61 64 73 20 61 72 65 20 64 79 6e 61 6d 69 63 eads are dynamic
8860: 61 6c 6c 79 20 63 72 65 61 74 65 64 20 62 79 20 ally created by
8870: 46 55 53 45 2e 0a 09 20 2a 2f 0a 09 70 74 68 72 FUSE... */..pthr
8880: 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 ead_ret = pthrea
8890: 64 5f 6b 65 79 5f 63 72 65 61 74 65 28 26 69 6e d_key_create(&in
88a0: 74 65 72 70 4b 65 79 2c 20 4e 55 4c 4c 29 3b 0a terpKey, NULL);.
88b0: 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 .if (pthread_ret
88c0: 20 21 3d 20 30 29 20 7b 0a 09 09 66 70 72 69 6e != 0) {...fprin
88d0: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 tf(stderr, "Unab
88e0: 6c 65 20 74 6f 20 63 72 65 61 74 65 20 54 53 44 le to create TSD
88f0: 20 6b 65 79 20 66 6f 72 20 54 63 6c 2e 20 20 41 key for Tcl. A
8900: 62 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 borting.\n");...
8910: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a .return(1);..}..
8920: 09 2f 2a 0a 09 20 2a 20 4d 61 6e 75 61 6c 6c 79 ./*.. * Manually
8930: 20 73 70 65 63 69 66 79 20 63 61 63 68 65 20 64 specify cache d
8940: 69 72 65 63 74 6f 72 79 2c 20 77 69 74 68 6f 75 irectory, withou
8950: 74 20 46 55 53 45 20 63 61 6c 6c 62 61 63 6b 0a t FUSE callback.
8960: 09 20 2a 20 54 68 69 73 20 6f 70 74 69 6f 6e 20 . * This option
8970: 6f 6e 6c 79 20 77 6f 72 6b 73 20 77 68 65 6e 20 only works when
8980: 6e 6f 74 20 75 73 69 6e 67 20 46 55 53 45 2c 20 not using FUSE,
8990: 73 69 6e 63 65 20 77 65 0a 09 20 2a 20 64 6f 20 since we.. * do
89a0: 6e 6f 74 20 70 72 6f 63 65 73 73 20 69 74 20 77 not process it w
89b0: 69 74 68 20 46 55 53 45 73 20 6f 70 74 69 6f 6e ith FUSEs option
89c0: 20 70 72 6f 63 65 73 73 69 6e 67 2e 0a 09 20 2a processing... *
89d0: 2f 0a 09 69 66 20 28 61 72 67 63 20 3e 3d 20 32 /..if (argc >= 2
89e0: 29 20 7b 0a 09 09 69 66 20 28 73 74 72 63 6d 70 ) {...if (strcmp
89f0: 28 61 72 67 76 5b 30 5d 2c 20 22 2d 2d 63 61 63 (argv[0], "--cac
8a00: 68 65 64 69 72 22 29 20 3d 3d 20 30 29 20 7b 0a hedir") == 0) {.
8a10: 09 09 09 61 70 70 66 73 5f 63 61 63 68 65 64 69 ...appfs_cachedi
8a20: 72 20 3d 20 73 74 72 64 75 70 28 61 72 67 76 5b r = strdup(argv[
8a30: 31 5d 29 3b 0a 0a 09 09 09 61 72 67 63 20 2d 3d 1]);.....argc -=
8a40: 20 32 3b 0a 09 09 09 61 72 67 76 20 2b 3d 20 32 2;....argv += 2
8a50: 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 ;...}..}.../*..
8a60: 2a 20 53 51 4c 69 74 65 33 20 6d 6f 64 65 2c 20 * SQLite3 mode,
8a70: 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77 20 for running raw
8a80: 53 51 4c 20 61 67 61 69 6e 73 74 20 74 68 65 20 SQL against the
8a90: 63 61 63 68 65 20 64 61 74 61 62 61 73 65 0a 09 cache database..
8aa0: 20 2a 2f 0a 09 69 66 20 28 61 72 67 63 20 3d 3d */..if (argc ==
8ab0: 20 32 20 26 26 20 73 74 72 63 6d 70 28 61 72 67 2 && strcmp(arg
8ac0: 76 5b 30 5d 2c 20 22 2d 2d 73 71 6c 69 74 65 33 v[0], "--sqlite3
8ad0: 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74 ") == 0) {...ret
8ae0: 75 72 6e 28 61 70 70 66 73 5f 73 71 6c 69 74 65 urn(appfs_sqlite
8af0: 33 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 3(argv[1]));..}.
8b00: 0a 09 2f 2a 0a 09 20 2a 20 54 63 6c 20 6d 6f 64 ../*.. * Tcl mod
8b10: 65 2c 20 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 e, for running r
8b20: 61 77 20 54 63 6c 20 69 6e 20 74 68 65 20 73 61 aw Tcl in the sa
8b30: 6d 65 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 41 me environment A
8b40: 70 70 46 53 64 20 77 6f 75 6c 64 0a 09 20 2a 20 ppFSd would.. *
8b50: 72 75 6e 20 63 6f 64 65 2e 0a 09 20 2a 2f 0a 09 run code... */..
8b60: 69 66 20 28 61 72 67 63 20 3d 3d 20 32 20 26 26 if (argc == 2 &&
8b70: 20 73 74 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c strcmp(argv[0],
8b80: 20 22 2d 2d 74 63 6c 22 29 20 3d 3d 20 30 29 20 "--tcl") == 0)
8b90: 7b 0a 09 09 72 65 74 75 72 6e 28 61 70 70 66 73 {...return(appfs
8ba0: 5f 74 63 6c 28 61 72 67 76 5b 31 5d 29 29 3b 0a _tcl(argv[1]));.
8bb0: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 43 72 65 61 .}.../*.. * Crea
8bc0: 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72 te a Tcl interpr
8bd0: 65 74 65 72 20 6a 75 73 74 20 74 6f 20 76 65 72 eter just to ver
8be0: 69 66 79 20 74 68 61 74 20 74 68 69 6e 67 73 20 ify that things
8bf0: 61 72 65 20 69 6e 20 77 6f 72 6b 69 6e 67 20 0a are in working .
8c00: 09 20 2a 20 6f 72 64 65 72 20 62 65 66 6f 72 65 . * order before
8c10: 20 77 65 20 62 65 63 6f 6d 65 20 61 20 64 61 65 we become a dae
8c20: 6d 6f 6e 2e 0a 09 20 2a 2f 0a 09 74 65 73 74 5f mon... */..test_
8c30: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 interp = appfs_c
8c40: 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 reate_TclInterp(
8c50: 26 74 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 &test_interp_err
8c60: 6f 72 29 3b 0a 09 69 66 20 28 74 65 73 74 5f 69 or);..if (test_i
8c70: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b nterp == NULL) {
8c80: 0a 09 09 69 66 20 28 74 65 73 74 5f 69 6e 74 65 ...if (test_inte
8c90: 72 70 5f 65 72 72 6f 72 20 3d 3d 20 4e 55 4c 4c rp_error == NULL
8ca0: 29 20 7b 0a 09 09 09 74 65 73 74 5f 69 6e 74 65 ) {....test_inte
8cb0: 72 70 5f 65 72 72 6f 72 20 3d 20 22 55 6e 6b 6e rp_error = "Unkn
8cc0: 6f 77 6e 20 65 72 72 6f 72 22 3b 0a 09 09 7d 0a own error";...}.
8cd0: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 ...fprintf(stder
8ce0: 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e r, "Unable to in
8cf0: 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 69 6e 74 itialize Tcl int
8d00: 65 72 70 72 65 74 65 72 20 66 6f 72 20 41 70 70 erpreter for App
8d10: 46 53 64 3a 5c 6e 22 29 3b 0a 09 09 66 70 72 69 FSd:\n");...fpri
8d20: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25 73 5c ntf(stderr, "%s\
8d30: 6e 22 2c 20 74 65 73 74 5f 69 6e 74 65 72 70 5f n", test_interp_
8d40: 65 72 72 6f 72 29 3b 0a 0a 09 09 72 65 74 75 72 error);....retur
8d50: 6e 28 31 29 3b 0a 09 7d 0a 09 54 63 6c 5f 44 65 n(1);..}..Tcl_De
8d60: 6c 65 74 65 49 6e 74 65 72 70 28 74 65 73 74 5f leteInterp(test_
8d70: 69 6e 74 65 72 70 29 3b 0a 0a 09 2f 2a 0a 09 20 interp);.../*..
8d80: 2a 20 41 64 64 20 46 55 53 45 20 61 72 67 75 6d * Add FUSE argum
8d90: 65 6e 74 73 20 77 68 69 63 68 20 77 65 20 61 6c ents which we al
8da0: 77 61 79 73 20 73 75 70 70 6c 79 0a 09 20 2a 2f ways supply.. */
8db0: 0a 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 ..fuse_opt_parse
8dc0: 28 26 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 (&args, NULL, NU
8dd0: 4c 4c 2c 20 61 70 70 66 73 5f 66 75 73 65 5f 6f LL, appfs_fuse_o
8de0: 70 74 5f 63 62 29 3b 0a 09 66 75 73 65 5f 6f 70 pt_cb);..fuse_op
8df0: 74 5f 61 64 64 5f 61 72 67 28 26 61 72 67 73 2c t_add_arg(&args,
8e00: 20 22 2d 6f 64 65 66 61 75 6c 74 5f 70 65 72 6d "-odefault_perm
8e10: 69 73 73 69 6f 6e 73 2c 66 73 6e 61 6d 65 3d 61 issions,fsname=a
8e20: 70 70 66 73 2c 73 75 62 74 79 70 65 3d 61 70 70 ppfs,subtype=app
8e30: 66 73 64 2c 75 73 65 5f 69 6e 6f 2c 6b 65 72 6e fsd,use_ino,kern
8e40: 65 6c 5f 63 61 63 68 65 2c 65 6e 74 72 79 5f 74 el_cache,entry_t
8e50: 69 6d 65 6f 75 74 3d 30 2c 61 74 74 72 5f 74 69 imeout=0,attr_ti
8e60: 6d 65 6f 75 74 3d 30 2c 69 6e 74 72 2c 62 69 67 meout=0,intr,big
8e70: 5f 77 72 69 74 65 73 2c 68 61 72 64 5f 72 65 6d _writes,hard_rem
8e80: 6f 76 65 22 29 3b 0a 0a 09 69 66 20 28 67 65 74 ove");...if (get
8e90: 75 69 64 28 29 20 3d 3d 20 30 29 20 7b 0a 09 09 uid() == 0) {...
8ea0: 66 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 26 fuse_opt_parse(&
8eb0: 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c args, NULL, NULL
8ec0: 2c 20 4e 55 4c 4c 29 3b 0a 09 09 66 75 73 65 5f , NULL);...fuse_
8ed0: 6f 70 74 5f 61 64 64 5f 61 72 67 28 26 61 72 67 opt_add_arg(&arg
8ee0: 73 2c 20 22 2d 6f 61 6c 6c 6f 77 5f 6f 74 68 65 s, "-oallow_othe
8ef0: 72 22 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a r");..}.../*.. *
8f00: 20 45 6e 74 65 72 20 74 68 65 20 46 55 53 45 20 Enter the FUSE
8f10: 6d 61 69 6e 20 6c 6f 6f 70 20 2d 2d 20 74 68 69 main loop -- thi
8f20: 73 20 77 69 6c 6c 20 70 72 6f 63 65 73 73 20 61 s will process a
8f30: 6e 79 20 61 72 67 75 6d 65 6e 74 73 0a 09 20 2a ny arguments.. *
8f40: 20 61 6e 64 20 73 74 61 72 74 20 73 65 72 76 69 and start servi
8f50: 63 69 6e 67 20 72 65 71 75 65 73 74 73 2e 0a 09 cing requests...
8f60: 20 2a 2f 0a 09 61 70 70 66 73 5f 66 75 73 65 5f */..appfs_fuse_
8f70: 73 74 61 72 74 65 64 20 3d 20 31 3b 0a 09 72 65 started = 1;..re
8f80: 74 75 72 6e 28 66 75 73 65 5f 6d 61 69 6e 28 61 turn(fuse_main(a
8f90: 72 67 73 2e 61 72 67 63 2c 20 61 72 67 73 2e 61 rgs.argc, args.a
8fa0: 72 67 76 2c 20 26 61 70 70 66 73 5f 6f 70 65 72 rgv, &appfs_oper
8fb0: 61 74 69 6f 6e 73 2c 20 4e 55 4c 4c 29 29 3b 0a ations, NULL));.
8fc0: 7d 0a 20 0a }. .