0000: 2f 2a 0a 20 2a 20 43 6f 70 79 72 69 67 68 74 20 /*. * Copyright
0010: 28 63 29 20 32 30 31 34 20 20 52 6f 79 20 4b 65 (c) 2014 Roy Ke
0020: 65 6e 65 0a 20 2a 0a 20 2a 20 50 65 72 6d 69 73 ene. *. * Permis
0030: 73 69 6f 6e 20 69 73 20 68 65 72 65 62 79 20 67 sion is hereby g
0040: 72 61 6e 74 65 64 2c 20 66 72 65 65 20 6f 66 20 ranted, free of
0050: 63 68 61 72 67 65 2c 20 74 6f 20 61 6e 79 20 70 charge, to any p
0060: 65 72 73 6f 6e 20 6f 62 74 61 69 6e 69 6e 67 20 erson obtaining
0070: 61 20 63 6f 70 79 0a 20 2a 20 6f 66 20 74 68 69 a copy. * of thi
0080: 73 20 73 6f 66 74 77 61 72 65 20 61 6e 64 20 61 s software and a
0090: 73 73 6f 63 69 61 74 65 64 20 64 6f 63 75 6d 65 ssociated docume
00a0: 6e 74 61 74 69 6f 6e 20 66 69 6c 65 73 20 28 74 ntation files (t
00b0: 68 65 20 22 53 6f 66 74 77 61 72 65 22 29 2c 20 he "Software"),
00c0: 74 6f 20 64 65 61 6c 0a 20 2a 20 69 6e 20 74 68 to deal. * in th
00d0: 65 20 53 6f 66 74 77 61 72 65 20 77 69 74 68 6f e Software witho
00e0: 75 74 20 72 65 73 74 72 69 63 74 69 6f 6e 2c 20 ut restriction,
00f0: 69 6e 63 6c 75 64 69 6e 67 20 77 69 74 68 6f 75 including withou
0100: 74 20 6c 69 6d 69 74 61 74 69 6f 6e 20 74 68 65 t limitation the
0110: 20 72 69 67 68 74 73 0a 20 2a 20 74 6f 20 75 73 rights. * to us
0120: 65 2c 20 63 6f 70 79 2c 20 6d 6f 64 69 66 79 2c e, copy, modify,
0130: 20 6d 65 72 67 65 2c 20 70 75 62 6c 69 73 68 2c merge, publish,
0140: 20 64 69 73 74 72 69 62 75 74 65 2c 20 73 75 62 distribute, sub
0150: 6c 69 63 65 6e 73 65 2c 20 61 6e 64 2f 6f 72 20 license, and/or
0160: 73 65 6c 6c 0a 20 2a 20 63 6f 70 69 65 73 20 6f sell. * copies o
0170: 66 20 74 68 65 20 53 6f 66 74 77 61 72 65 2c 20 f the Software,
0180: 61 6e 64 20 74 6f 20 70 65 72 6d 69 74 20 70 65 and to permit pe
0190: 72 73 6f 6e 73 20 74 6f 20 77 68 6f 6d 20 74 68 rsons to whom th
01a0: 65 20 53 6f 66 74 77 61 72 65 20 69 73 0a 20 2a e Software is. *
01b0: 20 66 75 72 6e 69 73 68 65 64 20 74 6f 20 64 6f furnished to do
01c0: 20 73 6f 2c 20 73 75 62 6a 65 63 74 20 74 6f 20 so, subject to
01d0: 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 63 6f the following co
01e0: 6e 64 69 74 69 6f 6e 73 3a 0a 20 2a 0a 20 2a 20 nditions:. *. *
01f0: 54 68 65 20 61 62 6f 76 65 20 63 6f 70 79 72 69 The above copyri
0200: 67 68 74 20 6e 6f 74 69 63 65 20 61 6e 64 20 74 ght notice and t
0210: 68 69 73 20 70 65 72 6d 69 73 73 69 6f 6e 20 6e his permission n
0220: 6f 74 69 63 65 20 73 68 61 6c 6c 20 62 65 20 69 otice shall be i
0230: 6e 63 6c 75 64 65 64 20 69 6e 0a 20 2a 20 61 6c ncluded in. * al
0240: 6c 20 63 6f 70 69 65 73 20 6f 72 20 73 75 62 73 l copies or subs
0250: 74 61 6e 74 69 61 6c 20 70 6f 72 74 69 6f 6e 73 tantial portions
0260: 20 6f 66 20 74 68 65 20 53 6f 66 74 77 61 72 65 of the Software
0270: 2e 0a 20 2a 0a 20 2a 20 54 48 45 20 53 4f 46 54 .. *. * THE SOFT
0280: 57 41 52 45 20 49 53 20 50 52 4f 56 49 44 45 44 WARE IS PROVIDED
0290: 20 22 41 53 20 49 53 22 2c 20 57 49 54 48 4f 55 "AS IS", WITHOU
02a0: 54 20 57 41 52 52 41 4e 54 59 20 4f 46 20 41 4e T WARRANTY OF AN
02b0: 59 20 4b 49 4e 44 2c 20 45 58 50 52 45 53 53 20 Y KIND, EXPRESS
02c0: 4f 52 0a 20 2a 20 49 4d 50 4c 49 45 44 2c 20 49 OR. * IMPLIED, I
02d0: 4e 43 4c 55 44 49 4e 47 20 42 55 54 20 4e 4f 54 NCLUDING BUT NOT
02e0: 20 4c 49 4d 49 54 45 44 20 54 4f 20 54 48 45 20 LIMITED TO THE
02f0: 57 41 52 52 41 4e 54 49 45 53 20 4f 46 20 4d 45 WARRANTIES OF ME
0300: 52 43 48 41 4e 54 41 42 49 4c 49 54 59 2c 0a 20 RCHANTABILITY,.
0310: 2a 20 46 49 54 4e 45 53 53 20 46 4f 52 20 41 20 * FITNESS FOR A
0320: 50 41 52 54 49 43 55 4c 41 52 20 50 55 52 50 4f PARTICULAR PURPO
0330: 53 45 20 41 4e 44 20 4e 4f 4e 49 4e 46 52 49 4e SE AND NONINFRIN
0340: 47 45 4d 45 4e 54 2e 20 49 4e 20 4e 4f 20 45 56 GEMENT. IN NO EV
0350: 45 4e 54 20 53 48 41 4c 4c 20 54 48 45 0a 20 2a ENT SHALL THE. *
0360: 20 41 55 54 48 4f 52 53 20 4f 52 20 43 4f 50 59 AUTHORS OR COPY
0370: 52 49 47 48 54 20 48 4f 4c 44 45 52 53 20 42 45 RIGHT HOLDERS BE
0380: 20 4c 49 41 42 4c 45 20 46 4f 52 20 41 4e 59 20 LIABLE FOR ANY
0390: 43 4c 41 49 4d 2c 20 44 41 4d 41 47 45 53 20 4f CLAIM, DAMAGES O
03a0: 52 20 4f 54 48 45 52 0a 20 2a 20 4c 49 41 42 49 R OTHER. * LIABI
03b0: 4c 49 54 59 2c 20 57 48 45 54 48 45 52 20 49 4e LITY, WHETHER IN
03c0: 20 41 4e 20 41 43 54 49 4f 4e 20 4f 46 20 43 4f AN ACTION OF CO
03d0: 4e 54 52 41 43 54 2c 20 54 4f 52 54 20 4f 52 20 NTRACT, TORT OR
03e0: 4f 54 48 45 52 57 49 53 45 2c 20 41 52 49 53 49 OTHERWISE, ARISI
03f0: 4e 47 20 46 52 4f 4d 2c 0a 20 2a 20 4f 55 54 20 NG FROM,. * OUT
0400: 4f 46 20 4f 52 20 49 4e 20 43 4f 4e 4e 45 43 54 OF OR IN CONNECT
0410: 49 4f 4e 20 57 49 54 48 20 54 48 45 20 53 4f 46 ION WITH THE SOF
0420: 54 57 41 52 45 20 4f 52 20 54 48 45 20 55 53 45 TWARE OR THE USE
0430: 20 4f 52 20 4f 54 48 45 52 20 44 45 41 4c 49 4e OR OTHER DEALIN
0440: 47 53 20 49 4e 0a 20 2a 20 54 48 45 20 53 4f 46 GS IN. * THE SOF
0450: 54 57 41 52 45 2e 0a 20 2a 2f 0a 23 64 65 66 69 TWARE.. */.#defi
0460: 6e 65 20 46 55 53 45 5f 55 53 45 5f 56 45 52 53 ne FUSE_USE_VERS
0470: 49 4f 4e 20 32 36 0a 0a 23 69 6e 63 6c 75 64 65 ION 26..#include
0480: 20 3c 73 79 73 2f 66 73 75 69 64 2e 68 3e 0a 23 <sys/fsuid.h>.#
0490: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 79 70 include <sys/typ
04a0: 65 73 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c es.h>.#include <
04b0: 70 74 68 72 65 61 64 2e 68 3e 0a 23 69 6e 63 6c pthread.h>.#incl
04c0: 75 64 65 20 3c 73 69 67 6e 61 6c 2e 68 3e 0a 23 ude <signal.h>.#
04d0: 69 6e 63 6c 75 64 65 20 3c 6c 69 6d 69 74 73 2e include <limits.
04e0: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 h>.#include <str
04f0: 69 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 ing.h>.#include
0500: 3c 73 74 64 61 72 67 2e 68 3e 0a 23 69 6e 63 6c <stdarg.h>.#incl
0510: 75 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 ude <stdlib.h>.#
0520: 69 6e 63 6c 75 64 65 20 3c 75 6e 69 73 74 64 2e include <unistd.
0530: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 65 72 72 h>.#include <err
0540: 6e 6f 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c no.h>.#include <
0550: 66 63 6e 74 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64 fcntl.h>.#includ
0560: 65 20 3c 73 74 64 69 6f 2e 68 3e 0a 23 69 6e 63 e <stdio.h>.#inc
0570: 6c 75 64 65 20 3c 66 75 73 65 2e 68 3e 0a 23 69 lude <fuse.h>.#i
0580: 6e 63 6c 75 64 65 20 3c 70 77 64 2e 68 3e 0a 23 nclude <pwd.h>.#
0590: 69 6e 63 6c 75 64 65 20 3c 74 63 6c 2e 68 3e 0a include <tcl.h>.
05a0: 0a 2f 2a 0a 20 2a 20 44 65 66 61 75 6c 74 20 63 ./*. * Default c
05b0: 61 63 68 65 20 64 69 72 65 63 74 6f 72 79 0a 20 ache directory.
05c0: 2a 2f 0a 23 69 66 6e 64 65 66 20 41 50 50 46 53 */.#ifndef APPFS
05d0: 5f 43 41 43 48 45 44 49 52 0a 23 64 65 66 69 6e _CACHEDIR.#defin
05e0: 65 20 41 50 50 46 53 5f 43 41 43 48 45 44 49 52 e APPFS_CACHEDIR
05f0: 20 22 2f 76 61 72 2f 63 61 63 68 65 2f 61 70 70 "/var/cache/app
0600: 66 73 22 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20 44 fs".#endif../* D
0610: 65 62 75 67 67 69 6e 67 20 6d 61 63 72 6f 73 20 ebugging macros
0620: 2a 2f 0a 23 69 66 64 65 66 20 44 45 42 55 47 0a */.#ifdef DEBUG.
0630: 69 6e 74 20 61 70 70 66 73 5f 64 65 62 75 67 5f int appfs_debug_
0640: 66 64 20 3d 20 53 54 44 45 52 52 5f 46 49 4c 45 fd = STDERR_FILE
0650: 4e 4f 3b 0a 23 64 65 66 69 6e 65 20 41 50 50 46 NO;.#define APPF
0660: 53 5f 44 45 42 55 47 28 78 2e 2e 2e 29 20 7b 20 S_DEBUG(x...) {
0670: 5c 0a 09 63 68 61 72 20 62 75 66 5b 38 31 39 32 \..char buf[8192
0680: 5d 3b 20 5c 0a 09 69 6e 74 20 62 75 66 6f 66 66 ]; \..int bufoff
0690: 20 3d 20 30 3b 20 5c 0a 09 69 66 20 28 61 70 70 = 0; \..if (app
06a0: 66 73 5f 64 65 62 75 67 5f 66 64 20 3d 3d 20 2d fs_debug_fd == -
06b0: 31 29 20 7b 20 5c 0a 09 09 61 70 70 66 73 5f 64 1) { \...appfs_d
06c0: 65 62 75 67 5f 66 64 20 3d 20 6f 70 65 6e 28 22 ebug_fd = open("
06d0: 2f 74 6d 70 2f 61 70 70 66 73 64 2e 6c 6f 67 22 /tmp/appfsd.log"
06e0: 2c 20 4f 5f 57 52 4f 4e 4c 59 20 7c 20 4f 5f 41 , O_WRONLY | O_A
06f0: 50 50 45 4e 44 20 7c 20 4f 5f 43 52 45 41 54 2c PPEND | O_CREAT,
0700: 20 30 36 30 30 29 3b 20 5c 0a 09 7d 3b 20 5c 0a 0600); \..}; \.
0710: 09 62 75 66 6f 66 66 20 3d 20 73 6e 70 72 69 6e .bufoff = snprin
0720: 74 66 28 62 75 66 2c 20 73 69 7a 65 6f 66 28 62 tf(buf, sizeof(b
0730: 75 66 29 2c 20 22 5b 64 65 62 75 67 5d 20 5b 74 uf), "[debug] [t
0740: 3d 25 6c 6c 78 5d 20 25 73 3a 25 69 3a 25 73 3a =%llx] %s:%i:%s:
0750: 20 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f ", (unsigned lo
0760: 6e 67 20 6c 6f 6e 67 29 20 70 74 68 72 65 61 64 ng long) pthread
0770: 5f 73 65 6c 66 28 29 2c 20 5f 5f 46 49 4c 45 5f _self(), __FILE_
0780: 5f 2c 20 5f 5f 4c 49 4e 45 5f 5f 2c 20 5f 5f 66 _, __LINE__, __f
0790: 75 6e 63 5f 5f 29 3b 20 5c 0a 09 69 66 20 28 62 unc__); \..if (b
07a0: 75 66 6f 66 66 20 3c 20 73 69 7a 65 6f 66 28 62 ufoff < sizeof(b
07b0: 75 66 29 29 20 7b 20 5c 0a 09 09 62 75 66 6f 66 uf)) { \...bufof
07c0: 66 20 2b 3d 20 73 6e 70 72 69 6e 74 66 28 62 75 f += snprintf(bu
07d0: 66 20 2b 20 62 75 66 6f 66 66 2c 20 73 69 7a 65 f + bufoff, size
07e0: 6f 66 28 62 75 66 29 20 2d 20 62 75 66 6f 66 66 of(buf) - bufoff
07f0: 2c 20 78 29 3b 20 5c 0a 09 7d 3b 20 5c 0a 09 69 , x); \..}; \..i
0800: 66 20 28 62 75 66 6f 66 66 20 3c 20 73 69 7a 65 f (bufoff < size
0810: 6f 66 28 62 75 66 29 29 20 7b 20 5c 0a 09 09 62 of(buf)) { \...b
0820: 75 66 6f 66 66 20 2b 3d 20 73 6e 70 72 69 6e 74 ufoff += snprint
0830: 66 28 62 75 66 20 2b 20 62 75 66 6f 66 66 2c 20 f(buf + bufoff,
0840: 73 69 7a 65 6f 66 28 62 75 66 29 20 2d 20 62 75 sizeof(buf) - bu
0850: 66 6f 66 66 2c 20 22 5c 6e 22 29 3b 5c 0a 09 7d foff, "\n");\..}
0860: 20 5c 0a 09 69 66 20 28 62 75 66 6f 66 66 20 3e \..if (bufoff >
0870: 20 73 69 7a 65 6f 66 28 62 75 66 29 29 20 7b 20 sizeof(buf)) {
0880: 5c 0a 09 09 62 75 66 6f 66 66 20 3d 20 73 69 7a \...bufoff = siz
0890: 65 6f 66 28 62 75 66 29 3b 20 5c 0a 09 7d 3b 20 eof(buf); \..};
08a0: 5c 0a 09 77 72 69 74 65 28 61 70 70 66 73 5f 64 \..write(appfs_d
08b0: 65 62 75 67 5f 66 64 2c 20 62 75 66 2c 20 62 75 ebug_fd, buf, bu
08c0: 66 6f 66 66 29 3b 20 5c 0a 7d 0a 23 65 6c 73 65 foff); \.}.#else
08d0: 0a 23 64 65 66 69 6e 65 20 41 50 50 46 53 5f 44 .#define APPFS_D
08e0: 45 42 55 47 28 78 2e 2e 2e 29 20 2f 2a 2a 2f 0a EBUG(x...) /**/.
08f0: 23 65 6e 64 69 66 0a 0a 2f 2a 0a 20 2a 20 53 48 #endif../*. * SH
0900: 41 31 20 54 63 6c 20 50 61 63 6b 61 67 65 20 69 A1 Tcl Package i
0910: 6e 69 74 69 61 6c 69 7a 65 72 2c 20 66 72 6f 6d nitializer, from
0920: 20 73 68 61 31 2e 6f 0a 20 2a 2f 0a 69 6e 74 20 sha1.o. */.int
0930: 53 68 61 31 5f 49 6e 69 74 28 54 63 6c 5f 49 6e Sha1_Init(Tcl_In
0940: 74 65 72 70 20 2a 69 6e 74 65 72 70 29 3b 0a 0a terp *interp);..
0950: 2f 2a 0a 20 2a 20 54 68 72 65 61 64 20 53 70 65 /*. * Thread Spe
0960: 63 69 66 69 63 20 44 61 74 61 20 28 54 53 44 29 cific Data (TSD)
0970: 20 66 6f 72 20 54 63 6c 20 49 6e 74 65 72 70 72 for Tcl Interpr
0980: 65 74 65 72 20 66 6f 72 20 74 68 65 20 63 75 72 eter for the cur
0990: 72 65 6e 74 20 74 68 72 65 61 64 0a 20 2a 2f 0a rent thread. */.
09a0: 73 74 61 74 69 63 20 70 74 68 72 65 61 64 5f 6b static pthread_k
09b0: 65 79 5f 74 20 69 6e 74 65 72 70 4b 65 79 3b 0a ey_t interpKey;.
09c0: 0a 2f 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20 76 61 ./*. * Global va
09d0: 72 69 61 62 6c 65 73 2c 20 6e 65 65 64 65 64 20 riables, needed
09e0: 66 6f 72 20 61 6c 6c 20 74 68 72 65 61 64 73 20 for all threads
09f0: 62 75 74 20 6f 6e 6c 79 20 69 6e 69 74 69 61 6c but only initial
0a00: 69 7a 65 64 20 62 65 66 6f 72 65 20 61 6e 79 0a ized before any.
0a10: 20 2a 20 46 55 53 45 20 74 68 72 65 61 64 73 20 * FUSE threads
0a20: 61 72 65 20 63 72 65 61 74 65 64 0a 20 2a 2f 0a are created. */.
0a30: 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 70 70 66 const char *appf
0a40: 73 5f 63 61 63 68 65 64 69 72 3b 0a 74 69 6d 65 s_cachedir;.time
0a50: 5f 74 20 61 70 70 66 73 5f 62 6f 6f 74 74 69 6d _t appfs_boottim
0a60: 65 3b 0a 69 6e 74 20 61 70 70 66 73 5f 66 75 73 e;.int appfs_fus
0a70: 65 5f 73 74 61 72 74 65 64 20 3d 20 30 3b 0a 69 e_started = 0;.i
0a80: 6e 74 20 61 70 70 66 73 5f 74 68 72 65 61 64 65 nt appfs_threade
0a90: 64 5f 74 63 6c 3b 0a 0a 2f 2a 0a 20 2a 20 47 6c d_tcl;../*. * Gl
0aa0: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20 66 obal variables f
0ab0: 6f 72 20 41 70 70 46 53 20 63 61 63 68 69 6e 67 or AppFS caching
0ac0: 0a 20 2a 2f 0a 70 74 68 72 65 61 64 5f 6d 75 74 . */.pthread_mut
0ad0: 65 78 5f 74 20 61 70 70 66 73 5f 70 61 74 68 5f ex_t appfs_path_
0ae0: 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 info_cache_mutex
0af0: 20 3d 20 50 54 48 52 45 41 44 5f 4d 55 54 45 58 = PTHREAD_MUTEX
0b00: 5f 49 4e 49 54 49 41 4c 49 5a 45 52 3b 0a 69 6e _INITIALIZER;.in
0b10: 74 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 t appfs_path_inf
0b20: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 38 o_cache_size = 8
0b30: 32 30 39 3b 0a 73 74 72 75 63 74 20 61 70 70 66 209;.struct appf
0b40: 73 5f 70 61 74 68 69 6e 66 6f 20 2a 61 70 70 66 s_pathinfo *appf
0b50: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 s_path_info_cach
0b60: 65 20 3d 20 4e 55 4c 4c 3b 0a 0a 23 69 66 6e 64 e = NULL;..#ifnd
0b70: 65 66 20 54 43 4c 5f 54 48 52 45 41 44 53 0a 2f ef TCL_THREADS./
0b80: 2a 0a 20 2a 20 48 61 6e 64 6c 65 20 75 6e 74 68 *. * Handle unth
0b90: 72 65 61 64 65 64 20 54 63 6c 0a 20 2a 2f 0a 70 readed Tcl. */.p
0ba0: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 74 20 61 thread_mutex_t a
0bb0: 70 70 66 73 5f 74 63 6c 5f 62 69 67 5f 67 6c 6f ppfs_tcl_big_glo
0bc0: 62 61 6c 5f 6c 6f 63 6b 20 3d 20 50 54 48 52 45 bal_lock = PTHRE
0bd0: 41 44 5f 4d 55 54 45 58 5f 49 4e 49 54 49 41 4c AD_MUTEX_INITIAL
0be0: 49 5a 45 52 3b 0a 23 64 65 66 69 6e 65 20 61 70 IZER;.#define ap
0bf0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f pfs_call_libtcl_
0c00: 65 6e 74 65 72 20 70 74 68 72 65 61 64 5f 6d 75 enter pthread_mu
0c10: 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f tex_lock(&appfs_
0c20: 74 63 6c 5f 62 69 67 5f 67 6c 6f 62 61 6c 5f 6c tcl_big_global_l
0c30: 6f 63 6b 29 3b 0a 23 64 65 66 69 6e 65 20 61 70 ock);.#define ap
0c40: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f pfs_call_libtcl_
0c50: 65 78 69 74 20 70 74 68 72 65 61 64 5f 6d 75 74 exit pthread_mut
0c60: 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 73 ex_unlock(&appfs
0c70: 5f 74 63 6c 5f 62 69 67 5f 67 6c 6f 62 61 6c 5f _tcl_big_global_
0c80: 6c 6f 63 6b 29 3b 0a 23 65 6c 73 65 0a 23 64 65 lock);.#else.#de
0c90: 66 69 6e 65 20 61 70 70 66 73 5f 63 61 6c 6c 5f fine appfs_call_
0ca0: 6c 69 62 74 63 6c 5f 65 6e 74 65 72 20 2f 2a 2a libtcl_enter /**
0cb0: 2f 0a 23 64 65 66 69 6e 65 20 61 70 70 66 73 5f /.#define appfs_
0cc0: 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74 call_libtcl_exit
0cd0: 20 2f 2a 2a 2f 0a 23 65 6e 64 69 66 0a 23 64 65 /**/.#endif.#de
0ce0: 66 69 6e 65 20 61 70 70 66 73 5f 63 61 6c 6c 5f fine appfs_call_
0cf0: 6c 69 62 74 63 6c 28 78 2e 2e 2e 29 20 61 70 70 libtcl(x...) app
0d00: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 fs_call_libtcl_e
0d10: 6e 74 65 72 20 78 20 61 70 70 66 73 5f 63 61 6c nter x appfs_cal
0d20: 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74 0a 0a 2f l_libtcl_exit../
0d30: 2a 0a 20 2a 20 47 6c 6f 62 61 6c 20 76 61 72 69 *. * Global vari
0d40: 61 62 6c 65 73 20 66 6f 72 20 41 70 70 46 53 20 ables for AppFS
0d50: 54 63 6c 20 49 6e 74 65 72 70 72 65 74 65 72 20 Tcl Interpreter
0d60: 72 65 73 74 61 72 74 69 6e 67 0a 20 2a 2f 0a 69 restarting. */.i
0d70: 6e 74 20 69 6e 74 65 72 70 5f 72 65 73 65 74 5f nt interp_reset_
0d80: 6b 65 79 20 3d 20 30 3b 0a 0a 2f 2a 0a 20 2a 20 key = 0;../*. *
0d90: 41 70 70 46 53 20 50 61 74 68 20 54 79 70 65 3a AppFS Path Type:
0da0: 20 20 44 65 73 63 72 69 62 65 73 20 74 68 65 20 Describes the
0db0: 74 79 70 65 20 6f 66 20 70 61 74 68 20 61 20 67 type of path a g
0dc0: 69 76 65 6e 20 66 69 6c 65 20 69 73 0a 20 2a 2f iven file is. */
0dd0: 0a 74 79 70 65 64 65 66 20 65 6e 75 6d 20 7b 0a .typedef enum {.
0de0: 09 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f .APPFS_PATHTYPE_
0df0: 49 4e 56 41 4c 49 44 2c 0a 09 41 50 50 46 53 5f INVALID,..APPFS_
0e00: 50 41 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f PATHTYPE_DOES_NO
0e10: 54 5f 45 58 49 53 54 2c 0a 09 41 50 50 46 53 5f T_EXIST,..APPFS_
0e20: 50 41 54 48 54 59 50 45 5f 46 49 4c 45 2c 0a 09 PATHTYPE_FILE,..
0e30: 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 APPFS_PATHTYPE_D
0e40: 49 52 45 43 54 4f 52 59 2c 0a 09 41 50 50 46 53 IRECTORY,..APPFS
0e50: 5f 50 41 54 48 54 59 50 45 5f 53 59 4d 4c 49 4e _PATHTYPE_SYMLIN
0e60: 4b 2c 0a 09 41 50 50 46 53 5f 50 41 54 48 54 59 K,..APPFS_PATHTY
0e70: 50 45 5f 53 4f 43 4b 45 54 2c 0a 09 41 50 50 46 PE_SOCKET,..APPF
0e80: 53 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 2c S_PATHTYPE_FIFO,
0e90: 0a 7d 20 61 70 70 66 73 5f 70 61 74 68 74 79 70 .} appfs_pathtyp
0ea0: 65 5f 74 3b 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 e_t;../*. * AppF
0eb0: 53 20 50 61 74 68 20 49 6e 66 6f 72 6d 61 74 69 S Path Informati
0ec0: 6f 6e 3a 0a 20 2a 20 20 20 20 20 20 20 20 20 43 on:. * C
0ed0: 6f 6d 70 6c 65 74 65 6c 79 20 64 65 73 63 72 69 ompletely descri
0ee0: 62 65 73 20 61 20 73 70 65 63 69 66 69 63 20 70 bes a specific p
0ef0: 61 74 68 2c 20 68 6f 77 20 69 74 20 73 68 6f 75 ath, how it shou
0f00: 6c 64 20 62 65 20 72 65 74 75 72 6e 65 64 20 74 ld be returned t
0f10: 6f 0a 20 2a 20 20 20 20 20 20 20 20 20 74 6f 20 o. * to
0f20: 74 68 65 20 6b 65 72 6e 65 6c 0a 20 2a 2f 0a 73 the kernel. */.s
0f30: 74 72 75 63 74 20 61 70 70 66 73 5f 70 61 74 68 truct appfs_path
0f40: 69 6e 66 6f 20 7b 0a 09 61 70 70 66 73 5f 70 61 info {..appfs_pa
0f50: 74 68 74 79 70 65 5f 74 20 74 79 70 65 3b 0a 09 thtype_t type;..
0f60: 74 69 6d 65 5f 74 20 74 69 6d 65 3b 0a 09 63 68 time_t time;..ch
0f70: 61 72 20 68 6f 73 74 6e 61 6d 65 5b 32 35 36 5d ar hostname[256]
0f80: 3b 0a 09 69 6e 74 20 70 61 63 6b 61 67 65 64 3b ;..int packaged;
0f90: 0a 09 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 ..unsigned long
0fa0: 6c 6f 6e 67 20 69 6e 6f 64 65 3b 0a 09 75 6e 69 long inode;..uni
0fb0: 6f 6e 20 7b 0a 09 09 73 74 72 75 63 74 20 7b 0a on {...struct {.
0fc0: 09 09 09 69 6e 74 20 63 68 69 6c 64 63 6f 75 6e ...int childcoun
0fd0: 74 3b 0a 09 09 7d 20 64 69 72 3b 0a 09 09 73 74 t;...} dir;...st
0fe0: 72 75 63 74 20 7b 0a 09 09 09 69 6e 74 20 65 78 ruct {....int ex
0ff0: 65 63 75 74 61 62 6c 65 3b 0a 09 09 09 6f 66 66 ecutable;....off
1000: 5f 74 20 73 69 7a 65 3b 0a 09 09 7d 20 66 69 6c _t size;...} fil
1010: 65 3b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09 e;...struct {...
1020: 09 6f 66 66 5f 74 20 73 69 7a 65 3b 0a 09 09 09 .off_t size;....
1030: 63 68 61 72 20 73 6f 75 72 63 65 5b 32 35 36 5d char source[256]
1040: 3b 0a 09 09 7d 20 73 79 6d 6c 69 6e 6b 3b 0a 09 ;...} symlink;..
1050: 7d 20 74 79 70 65 69 6e 66 6f 3b 0a 0a 09 2f 2a } typeinfo;.../*
1060: 20 41 74 74 72 69 62 75 74 65 73 20 75 73 65 64 Attributes used
1070: 20 6f 6e 6c 79 20 66 6f 72 20 63 61 63 68 69 6e only for cachin
1080: 67 20 65 6e 74 72 69 65 73 20 2a 2f 0a 09 63 68 g entries */..ch
1090: 61 72 20 2a 5f 63 61 63 68 65 5f 70 61 74 68 3b ar *_cache_path;
10a0: 0a 09 75 69 64 5f 74 20 5f 63 61 63 68 65 5f 75 ..uid_t _cache_u
10b0: 69 64 3b 0a 7d 3b 0a 0a 2f 2a 0a 20 2a 20 43 72 id;.};../*. * Cr
10c0: 65 61 74 65 20 61 20 6e 65 77 20 54 63 6c 20 69 eate a new Tcl i
10d0: 6e 74 65 72 70 72 65 74 65 72 20 61 6e 64 20 63 nterpreter and c
10e0: 6f 6d 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61 ompletely initia
10f0: 6c 69 7a 65 20 69 74 0a 20 2a 2f 0a 73 74 61 74 lize it. */.stat
1100: 69 63 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 61 ic Tcl_Interp *a
1110: 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 ppfs_create_TclI
1120: 6e 74 65 72 70 28 63 68 61 72 20 2a 2a 65 72 72 nterp(char **err
1130: 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 54 63 or_string) {..Tc
1140: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 l_Interp *interp
1150: 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a ;..int tcl_ret;.
1160: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 6c .const char *tcl
1170: 5f 73 65 74 76 61 72 5f 72 65 74 3b 0a 0a 09 41 _setvar_ret;...A
1180: 50 50 46 53 5f 44 45 42 55 47 28 22 43 72 65 61 PPFS_DEBUG("Crea
1190: 74 69 6e 67 20 6e 65 77 20 54 63 6c 20 69 6e 74 ting new Tcl int
11a0: 65 72 70 72 65 74 65 72 20 66 6f 72 20 54 49 44 erpreter for TID
11b0: 20 3d 20 30 78 25 6c 6c 78 22 2c 20 28 75 6e 73 = 0x%llx", (uns
11c0: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 igned long long)
11d0: 20 70 74 68 72 65 61 64 5f 73 65 6c 66 28 29 29 pthread_self())
11e0: 3b 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c ;...appfs_call_l
11f0: 69 62 74 63 6c 28 0a 09 09 69 6e 74 65 72 70 20 ibtcl(...interp
1200: 3d 20 54 63 6c 5f 43 72 65 61 74 65 49 6e 74 65 = Tcl_CreateInte
1210: 72 70 28 29 3b 0a 09 29 0a 09 69 66 20 28 69 6e rp();..)..if (in
1220: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a terp == NULL) {.
1230: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 ..fprintf(stderr
1240: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 , "Unable to cre
1250: 61 74 65 20 54 63 6c 20 49 6e 74 65 72 70 72 65 ate Tcl Interpre
1260: 74 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c ter. Aborting.\
1270: 6e 22 29 3b 0a 0a 09 09 69 66 20 28 65 72 72 6f n");....if (erro
1280: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 2a r_string) {....*
1290: 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 error_string = s
12a0: 74 72 64 75 70 28 22 55 6e 61 62 6c 65 20 74 6f trdup("Unable to
12b0: 20 63 72 65 61 74 65 20 54 63 6c 20 69 6e 74 65 create Tcl inte
12c0: 72 70 72 65 74 65 72 2e 22 29 3b 0a 09 09 7d 0a rpreter.");...}.
12d0: 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b ...return(NULL);
12e0: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c ..}...appfs_call
12f0: 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 _libtcl(Tcl_Pres
1300: 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a erve(interp);)..
1310: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 .appfs_call_libt
1320: 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d 20 cl(...tcl_ret =
1330: 54 63 6c 5f 49 6e 69 74 28 69 6e 74 65 72 70 29 Tcl_Init(interp)
1340: 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 ;..)..if (tcl_re
1350: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 t != TCL_OK) {..
1360: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c .fprintf(stderr,
1370: 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 74 "Unable to init
1380: 69 61 6c 69 7a 65 20 54 63 6c 2e 20 20 41 62 6f ialize Tcl. Abo
1390: 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 rting.\n");...ap
13a0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 pfs_call_libtcl(
13b0: 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 ....fprintf(stde
13c0: 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 rr, "Tcl Error i
13d0: 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 s: %s\n", Tcl_Ge
13e0: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e tStringResult(in
13f0: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69 terp));...)....i
1400: 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 f (error_string)
1410: 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c {....appfs_call
1420: 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72 _libtcl(.....*er
1430: 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 ror_string = str
1440: 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e dup(Tcl_GetStrin
1450: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 gResult(interp))
1460: 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70 ;....)...}....ap
1470: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 pfs_call_libtcl(
1480: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 Tcl_Release(inte
1490: 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44 rp);)....APPFS_D
14a0: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e EBUG("Terminatin
14b0: 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 g Tcl interprete
14c0: 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 r.");....appfs_c
14d0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 all_libtcl(Tcl_D
14e0: 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 eleteInterp(inte
14f0: 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 rp);)....return(
1500: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 NULL);..}...appf
1510: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 s_call_libtcl(..
1520: 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 45 .tcl_ret = Tcl_E
1530: 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 70 61 63 val(interp, "pac
1540: 6b 61 67 65 20 69 66 6e 65 65 64 65 64 20 73 68 kage ifneeded sh
1550: 61 31 20 31 2e 30 20 5b 6c 69 73 74 20 6c 6f 61 a1 1.0 [list loa
1560: 64 20 7b 7d 20 73 68 61 31 5d 22 29 3b 0a 09 29 d {} sha1]");..)
1570: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d ..if (tcl_ret !=
1580: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 TCL_OK) {...fpr
1590: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e intf(stderr, "Un
15a0: 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 able to initiali
15b0: 7a 65 20 54 63 6c 20 53 48 41 31 2e 20 20 41 62 ze Tcl SHA1. Ab
15c0: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 orting.\n");...a
15d0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c ppfs_call_libtcl
15e0: 28 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 (....fprintf(std
15f0: 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 err, "Tcl Error
1600: 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 is: %s\n", Tcl_G
1610: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 etStringResult(i
1620: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 nterp));...)....
1630: 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 if (error_string
1640: 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c ) {....appfs_cal
1650: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 l_libtcl(.....*e
1660: 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 rror_string = st
1670: 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 rdup(Tcl_GetStri
1680: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 ngResult(interp)
1690: 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 );....)...}....a
16a0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c ppfs_call_libtcl
16b0: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 (Tcl_Release(int
16c0: 65 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f erp);)....APPFS_
16d0: 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 DEBUG("Terminati
16e0: 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 ng Tcl interpret
16f0: 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f er.");....appfs_
1700: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f call_libtcl(Tcl_
1710: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 DeleteInterp(int
1720: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e erp);)....return
1730: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 (NULL);..}...app
1740: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a fs_call_libtcl(.
1750: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f ..tcl_ret = Tcl_
1760: 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 22 70 61 Eval(interp, "pa
1770: 63 6b 61 67 65 20 69 66 6e 65 65 64 65 64 20 61 ckage ifneeded a
1780: 70 70 66 73 64 20 31 2e 30 20 5b 6c 69 73 74 20 ppfsd 1.0 [list
1790: 6c 6f 61 64 20 7b 7d 20 61 70 70 66 73 64 5d 22 load {} appfsd]"
17a0: 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 );..)..if (tcl_r
17b0: 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a et != TCL_OK) {.
17c0: 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 ..fprintf(stderr
17d0: 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 69 6e 69 , "Unable to ini
17e0: 74 69 61 6c 69 7a 65 20 54 63 6c 20 41 70 70 46 tialize Tcl AppF
17f0: 53 20 50 61 63 6b 61 67 65 2e 20 20 41 62 6f 72 S Package. Abor
1800: 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 70 ting.\n");...app
1810: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a fs_call_libtcl(.
1820: 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 ...fprintf(stder
1830: 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 69 73 r, "Tcl Error is
1840: 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 : %s\n", Tcl_Get
1850: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 StringResult(int
1860: 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 69 66 erp));...)....if
1870: 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 (error_string)
1880: 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f {....appfs_call_
1890: 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 72 72 libtcl(.....*err
18a0: 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 72 64 or_string = strd
18b0: 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 up(Tcl_GetString
18c0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b Result(interp));
18d0: 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70 ....)...}....app
18e0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 fs_call_libtcl(T
18f0: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 cl_Release(inter
1900: 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f 44 45 p);)....APPFS_DE
1910: 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 BUG("Terminating
1920: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 Tcl interpreter
1930: 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 .");....appfs_ca
1940: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 ll_libtcl(Tcl_De
1950: 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 leteInterp(inter
1960: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e p);)....return(N
1970: 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 ULL);..}.../*..
1980: 2a 20 4c 6f 61 64 20 22 70 6b 69 2e 74 63 6c 22 * Load "pki.tcl"
1990: 20 69 6e 20 74 68 65 20 73 61 6d 65 20 77 61 79 in the same way
19a0: 20 61 73 20 61 70 70 66 73 64 2e 74 63 6c 20 28 as appfsd.tcl (
19b0: 73 65 65 20 62 65 6c 6f 77 29 0a 09 20 2a 2f 0a see below).. */.
19c0: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 .appfs_call_libt
19d0: 63 6c 5f 65 6e 74 65 72 0a 09 09 74 63 6c 5f 72 cl_enter...tcl_r
19e0: 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e et = Tcl_Eval(in
19f0: 74 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 64 terp, "".#includ
1a00: 65 20 22 70 6b 69 2e 74 63 6c 2e 68 22 0a 09 09 e "pki.tcl.h"...
1a10: 22 22 29 3b 0a 09 61 70 70 66 73 5f 63 61 6c 6c "");..appfs_call
1a20: 5f 6c 69 62 74 63 6c 5f 65 78 69 74 0a 09 69 66 _libtcl_exit..if
1a30: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c (tcl_ret != TCL
1a40: 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 _OK) {...fprintf
1a50: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 (stderr, "Unable
1a60: 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 54 to initialize T
1a70: 63 6c 20 50 4b 49 2e 20 20 41 62 6f 72 74 69 6e cl PKI. Abortin
1a80: 67 2e 5c 6e 22 29 3b 0a 09 09 61 70 70 66 73 5f g.\n");...appfs_
1a90: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 call_libtcl(....
1aa0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 fprintf(stderr,
1ab0: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 "Tcl Error is: %
1ac0: 73 5c 6e 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 s\n", Tcl_GetStr
1ad0: 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 ingResult(interp
1ae0: 29 29 3b 0a 09 09 29 0a 0a 09 09 69 66 20 28 65 ));...)....if (e
1af0: 72 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 rror_string) {..
1b00: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 ..appfs_call_lib
1b10: 74 63 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f tcl(.....*error_
1b20: 73 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 string = strdup(
1b30: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 Tcl_GetStringRes
1b40: 75 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 ult(interp));...
1b50: 09 29 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f .)...}....appfs_
1b60: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f call_libtcl(Tcl_
1b70: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b Release(interp);
1b80: 29 0a 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 )....APPFS_DEBUG
1b90: 28 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 ("Terminating Tc
1ba0: 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 l interpreter.")
1bb0: 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f ;....appfs_call_
1bc0: 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 libtcl(Tcl_Delet
1bd0: 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b eInterp(interp);
1be0: 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c )....return(NULL
1bf0: 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 4c );..}.../*.. * L
1c00: 6f 61 64 20 74 68 65 20 22 61 70 70 66 73 64 2e oad the "appfsd.
1c10: 74 63 6c 22 20 73 63 72 69 70 74 2c 20 77 68 69 tcl" script, whi
1c20: 63 68 20 69 73 20 22 63 6f 6d 70 69 6c 65 64 22 ch is "compiled"
1c30: 20 69 6e 74 6f 20 61 20 43 20 68 65 61 64 65 72 into a C header
1c40: 0a 09 20 2a 20 73 6f 20 74 68 61 74 20 69 74 20 .. * so that it
1c50: 64 6f 65 73 20 6e 6f 74 20 6e 65 65 64 20 74 6f does not need to
1c60: 20 65 78 69 73 74 20 6f 6e 20 74 68 65 20 66 69 exist on the fi
1c70: 6c 65 73 79 73 74 65 6d 20 61 6e 64 20 63 61 6e lesystem and can
1c80: 20 62 65 0a 09 20 2a 20 64 69 72 65 63 74 6c 79 be.. * directly
1c90: 20 65 76 61 6c 75 61 74 65 64 2e 0a 09 20 2a 2f evaluated... */
1ca0: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 ..appfs_call_lib
1cb0: 74 63 6c 5f 65 6e 74 65 72 0a 09 09 74 63 6c 5f tcl_enter...tcl_
1cc0: 72 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 ret = Tcl_Eval(i
1cd0: 6e 74 65 72 70 2c 20 22 22 0a 23 69 6e 63 6c 75 nterp, "".#inclu
1ce0: 64 65 20 22 61 70 70 66 73 64 2e 74 63 6c 2e 68 de "appfsd.tcl.h
1cf0: 22 0a 09 09 22 22 29 3b 0a 09 61 70 70 66 73 5f "..."");..appfs_
1d00: 63 61 6c 6c 5f 6c 69 62 74 63 6c 5f 65 78 69 74 call_libtcl_exit
1d10: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d ..if (tcl_ret !=
1d20: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 TCL_OK) {...fpr
1d30: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e intf(stderr, "Un
1d40: 61 62 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 able to initiali
1d50: 7a 65 20 54 63 6c 20 41 70 70 46 53 20 73 63 72 ze Tcl AppFS scr
1d60: 69 70 74 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c ipt. Aborting.\
1d70: 6e 22 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c n");...appfs_cal
1d80: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 66 70 72 l_libtcl(....fpr
1d90: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 54 63 intf(stderr, "Tc
1da0: 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 5c 6e l Error is: %s\n
1db0: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 ", Tcl_GetString
1dc0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b Result(interp));
1dd0: 0a 09 09 29 0a 0a 09 09 69 66 20 28 65 72 72 6f ...)....if (erro
1de0: 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 09 61 r_string) {....a
1df0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c ppfs_call_libtcl
1e00: 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 74 72 (.....*error_str
1e10: 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 63 6c ing = strdup(Tcl
1e20: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 _GetStringResult
1e30: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 29 0a (interp));....).
1e40: 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c ..}....appfs_cal
1e50: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c l_libtcl(Tcl_Rel
1e60: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a ease(interp);)..
1e70: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 ..APPFS_DEBUG("T
1e80: 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c 20 69 erminating Tcl i
1e90: 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b 0a 0a nterpreter.");..
1ea0: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 ..appfs_call_lib
1eb0: 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e tcl(Tcl_DeleteIn
1ec0: 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a terp(interp);)..
1ed0: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a ..return(NULL);.
1ee0: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 65 74 20 .}.../*.. * Set
1ef0: 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 global variables
1f00: 20 66 72 6f 6d 20 43 20 74 6f 20 54 63 6c 0a 09 from C to Tcl..
1f10: 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f */..appfs_call_
1f20: 6c 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 73 65 libtcl(...tcl_se
1f30: 74 76 61 72 5f 72 65 74 20 3d 20 54 63 6c 5f 53 tvar_ret = Tcl_S
1f40: 65 74 56 61 72 28 69 6e 74 65 72 70 2c 20 22 3a etVar(interp, ":
1f50: 3a 61 70 70 66 73 3a 3a 63 61 63 68 65 64 69 72 :appfs::cachedir
1f60: 22 2c 20 61 70 70 66 73 5f 63 61 63 68 65 64 69 ", appfs_cachedi
1f70: 72 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f 4e r, TCL_GLOBAL_ON
1f80: 4c 59 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c LY);..)..if (tcl
1f90: 5f 73 65 74 76 61 72 5f 72 65 74 20 3d 3d 20 4e _setvar_ret == N
1fa0: 55 4c 4c 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 ULL) {...fprintf
1fb0: 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 (stderr, "Unable
1fc0: 20 74 6f 20 73 65 74 20 63 61 63 68 65 20 64 69 to set cache di
1fd0: 72 65 63 74 6f 72 79 2e 20 20 54 68 69 73 20 73 rectory. This s
1fe0: 68 6f 75 6c 64 20 6e 65 76 65 72 20 66 61 69 6c hould never fail
1ff0: 2e 5c 6e 22 29 3b 0a 0a 09 09 69 66 20 28 65 72 .\n");....if (er
2000: 72 6f 72 5f 73 74 72 69 6e 67 29 20 7b 0a 09 09 ror_string) {...
2010: 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 .appfs_call_libt
2020: 63 6c 28 0a 09 09 09 09 2a 65 72 72 6f 72 5f 73 cl(.....*error_s
2030: 74 72 69 6e 67 20 3d 20 73 74 72 64 75 70 28 54 tring = strdup(T
2040: 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 cl_GetStringResu
2050: 6c 74 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 09 lt(interp));....
2060: 29 0a 09 09 7d 0a 0a 09 09 61 70 70 66 73 5f 63 )...}....appfs_c
2070: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 all_libtcl(Tcl_R
2080: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 elease(interp);)
2090: 0a 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 ....APPFS_DEBUG(
20a0: 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 63 6c "Terminating Tcl
20b0: 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 29 3b interpreter.");
20c0: 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c ....appfs_call_l
20d0: 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c 65 74 65 ibtcl(Tcl_Delete
20e0: 49 6e 74 65 72 70 28 69 6e 74 65 72 70 29 3b 29 Interp(interp);)
20f0: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 ....return(NULL)
2100: 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 49 6e ;..}.../*.. * In
2110: 69 74 69 61 6c 69 7a 65 20 74 68 65 20 22 61 70 itialize the "ap
2120: 70 66 73 64 2e 74 63 6c 22 20 65 6e 76 69 72 6f pfsd.tcl" enviro
2130: 6e 6d 65 6e 74 2c 20 77 68 69 63 68 20 6d 75 73 nment, which mus
2140: 74 20 62 65 20 64 6f 6e 65 20 61 66 74 65 72 0a t be done after.
2150: 09 20 2a 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 . * global varia
2160: 62 6c 65 73 20 61 72 65 20 73 65 74 2e 0a 09 20 bles are set...
2170: 2a 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c */..appfs_call_l
2180: 69 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 ibtcl(...tcl_ret
2190: 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 = Tcl_Eval(inte
21a0: 72 70 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 69 6e rp, "::appfs::in
21b0: 69 74 22 29 3b 0a 09 29 0a 09 69 66 20 28 74 63 it");..)..if (tc
21c0: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 l_ret != TCL_OK)
21d0: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 {...fprintf(std
21e0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 err, "Unable to
21f0: 69 6e 69 74 69 61 6c 69 7a 65 20 54 63 6c 20 41 initialize Tcl A
2200: 70 70 46 53 20 73 63 72 69 70 74 20 28 3a 3a 61 ppFS script (::a
2210: 70 70 66 73 3a 3a 69 6e 69 74 29 2e 20 20 41 62 ppfs::init). Ab
2220: 6f 72 74 69 6e 67 2e 5c 6e 22 29 3b 0a 09 09 61 orting.\n");...a
2230: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c ppfs_call_libtcl
2240: 28 0a 09 09 09 66 70 72 69 6e 74 66 28 73 74 64 (....fprintf(std
2250: 65 72 72 2c 20 22 54 63 6c 20 45 72 72 6f 72 20 err, "Tcl Error
2260: 69 73 3a 20 25 73 5c 6e 22 2c 20 54 63 6c 5f 47 is: %s\n", Tcl_G
2270: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 etStringResult(i
2280: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 nterp));...)....
2290: 69 66 20 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 if (error_string
22a0: 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 63 61 6c ) {....appfs_cal
22b0: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 09 2a 65 l_libtcl(.....*e
22c0: 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d 20 73 74 rror_string = st
22d0: 72 64 75 70 28 54 63 6c 5f 47 65 74 53 74 72 69 rdup(Tcl_GetStri
22e0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 ngResult(interp)
22f0: 29 3b 0a 09 09 09 29 0a 09 09 7d 0a 0a 09 09 61 );....)...}....a
2300: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c ppfs_call_libtcl
2310: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 (Tcl_Release(int
2320: 65 72 70 29 3b 29 0a 0a 09 09 41 50 50 46 53 5f erp);)....APPFS_
2330: 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 DEBUG("Terminati
2340: 6e 67 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 ng Tcl interpret
2350: 65 72 2e 22 29 3b 0a 0a 09 09 61 70 70 66 73 5f er.");....appfs_
2360: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f call_libtcl(Tcl_
2370: 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e 74 DeleteInterp(int
2380: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e erp);)....return
2390: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a (NULL);..}.../*.
23a0: 09 20 2a 20 48 69 64 65 20 73 6f 6d 65 20 54 63 . * Hide some Tc
23b0: 6c 20 63 6f 6d 6d 61 6e 64 73 20 74 68 61 74 20 l commands that
23c0: 77 65 20 64 6f 20 6e 6f 74 20 63 61 72 65 20 74 we do not care t
23d0: 6f 20 75 73 65 20 61 6e 64 20 77 68 69 63 68 20 o use and which
23e0: 6d 61 79 0a 09 20 2a 20 73 6c 6f 77 20 64 6f 77 may.. * slow dow
23f0: 6e 20 72 75 6e 2d 74 69 6d 65 20 6f 70 65 72 61 n run-time opera
2400: 74 69 6f 6e 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 tions... */..app
2410: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a fs_call_libtcl(.
2420: 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61 6e ..Tcl_HideComman
2430: 64 28 69 6e 74 65 72 70 2c 20 22 61 75 74 6f 5f d(interp, "auto_
2440: 6c 6f 61 64 5f 69 6e 64 65 78 22 2c 20 22 61 75 load_index", "au
2450: 74 6f 5f 6c 6f 61 64 5f 69 6e 64 65 78 22 29 3b to_load_index");
2460: 0a 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d 61 ...Tcl_HideComma
2470: 6e 64 28 69 6e 74 65 72 70 2c 20 22 75 6e 6b 6e nd(interp, "unkn
2480: 6f 77 6e 22 2c 20 22 75 6e 6b 6e 6f 77 6e 22 29 own", "unknown")
2490: 3b 0a 09 09 54 63 6c 5f 48 69 64 65 43 6f 6d 6d ;...Tcl_HideComm
24a0: 61 6e 64 28 69 6e 74 65 72 70 2c 20 22 65 78 69 and(interp, "exi
24b0: 74 22 2c 20 22 65 78 69 74 22 29 3b 0a 09 29 0a t", "exit");..).
24c0: 0a 09 2f 2a 0a 09 20 2a 20 52 65 6c 65 61 73 65 ../*.. * Release
24d0: 20 74 68 65 20 68 6f 6c 64 20 77 65 20 68 61 76 the hold we hav
24e0: 65 20 6f 6e 20 74 68 65 20 69 6e 74 65 72 70 72 e on the interpr
24f0: 65 74 65 72 20 73 6f 20 74 68 61 74 20 69 74 20 eter so that it
2500: 6d 61 79 20 62 65 0a 09 20 2a 20 64 65 6c 65 74 may be.. * delet
2510: 65 64 20 69 66 20 6e 65 65 64 65 64 0a 09 20 2a ed if needed.. *
2520: 2f 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 /..appfs_call_li
2530: 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 btcl(Tcl_Release
2540: 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 2f 2a 0a (interp);).../*.
2550: 09 20 2a 20 52 65 74 75 72 6e 20 74 68 65 20 63 . * Return the c
2560: 6f 6d 70 6c 65 74 65 6c 79 20 69 6e 69 74 69 61 ompletely initia
2570: 6c 69 7a 65 64 20 69 6e 74 65 72 70 72 65 74 65 lized interprete
2580: 72 0a 09 20 2a 2f 0a 09 72 65 74 75 72 6e 28 69 r.. */..return(i
2590: 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a nterp);.}../*. *
25a0: 20 52 65 74 75 72 6e 20 74 68 65 20 74 68 72 65 Return the thre
25b0: 61 64 2d 73 70 65 63 69 66 69 63 20 54 63 6c 20 ad-specific Tcl
25c0: 69 6e 74 65 72 70 72 65 74 65 72 2c 20 63 72 65 interpreter, cre
25d0: 61 74 69 6e 67 20 69 74 20 69 66 20 6e 65 65 64 ating it if need
25e0: 65 64 0a 20 2a 2f 0a 73 74 61 74 69 63 20 54 63 ed. */.static Tc
25f0: 6c 5f 49 6e 74 65 72 70 20 2a 61 70 70 66 73 5f l_Interp *appfs_
2600: 54 63 6c 49 6e 74 65 72 70 28 76 6f 69 64 29 20 TclInterp(void)
2610: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 {..Tcl_Interp *i
2620: 6e 74 65 72 70 3b 0a 09 69 6e 74 20 70 74 68 72 nterp;..int pthr
2630: 65 61 64 5f 72 65 74 3b 0a 09 73 74 61 74 69 63 ead_ret;..static
2640: 20 5f 5f 74 68 72 65 61 64 20 69 6e 74 20 74 68 __thread int th
2650: 72 65 61 64 5f 69 6e 74 65 72 70 5f 72 65 73 65 read_interp_rese
2660: 74 5f 6b 65 79 20 3d 20 30 3b 0a 09 69 6e 74 20 t_key = 0;..int
2670: 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 global_interp_re
2680: 73 65 74 5f 6b 65 79 3b 0a 0a 09 67 6c 6f 62 61 set_key;...globa
2690: 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b l_interp_reset_k
26a0: 65 79 20 3d 20 5f 5f 73 79 6e 63 5f 66 65 74 63 ey = __sync_fetc
26b0: 68 5f 61 6e 64 5f 61 64 64 28 26 69 6e 74 65 72 h_and_add(&inter
26c0: 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 30 29 3b p_reset_key, 0);
26d0: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 70 74 68 72 ...interp = pthr
26e0: 65 61 64 5f 67 65 74 73 70 65 63 69 66 69 63 28 ead_getspecific(
26f0: 69 6e 74 65 72 70 4b 65 79 29 3b 0a 09 69 66 20 interpKey);..if
2700: 28 69 6e 74 65 72 70 20 21 3d 20 4e 55 4c 4c 20 (interp != NULL
2710: 26 26 20 74 68 72 65 61 64 5f 69 6e 74 65 72 70 && thread_interp
2720: 5f 72 65 73 65 74 5f 6b 65 79 20 21 3d 20 67 6c _reset_key != gl
2730: 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 obal_interp_rese
2740: 74 5f 6b 65 79 29 20 7b 0a 09 09 41 50 50 46 53 t_key) {...APPFS
2750: 5f 44 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 _DEBUG("Terminat
2760: 69 6e 67 20 6f 6c 64 20 69 6e 74 65 72 70 72 65 ing old interpre
2770: 74 65 72 20 61 6e 64 20 72 65 73 74 61 72 74 69 ter and restarti
2780: 6e 67 20 64 75 65 20 74 6f 20 72 65 73 65 74 20 ng due to reset
2790: 72 65 71 75 65 73 74 2e 22 29 3b 0a 0a 09 09 61 request.");....a
27a0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c ppfs_call_libtcl
27b0: 28 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 65 72 (Tcl_DeleteInter
27c0: 70 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 69 p(interp);)....i
27d0: 6e 74 65 72 70 20 3d 20 4e 55 4c 4c 3b 0a 0a 09 nterp = NULL;...
27e0: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 .pthread_ret = p
27f0: 74 68 72 65 61 64 5f 73 65 74 73 70 65 63 69 66 thread_setspecif
2800: 69 63 28 69 6e 74 65 72 70 4b 65 79 2c 20 69 6e ic(interpKey, in
2810: 74 65 72 70 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 terp);..}...if (
2820: 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 65 global_interp_re
2830: 73 65 74 5f 6b 65 79 20 3d 3d 20 2d 31 29 20 7b set_key == -1) {
2840: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 ...APPFS_DEBUG("
2850: 52 65 74 75 72 6e 69 6e 67 20 4e 55 4c 4c 20 73 Returning NULL s
2860: 69 6e 63 65 20 77 65 20 61 72 65 20 69 6e 20 74 ince we are in t
2870: 68 65 20 70 72 6f 63 65 73 73 20 6f 66 20 74 65 he process of te
2880: 72 6d 69 6e 61 74 69 6e 67 20 61 6c 6c 20 74 68 rminating all th
2890: 72 65 61 64 73 2e 22 29 3b 0a 0a 09 09 72 65 74 reads.");....ret
28a0: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 urn(NULL);..}...
28b0: 74 68 72 65 61 64 5f 69 6e 74 65 72 70 5f 72 65 thread_interp_re
28c0: 73 65 74 5f 6b 65 79 20 3d 20 67 6c 6f 62 61 6c set_key = global
28d0: 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 _interp_reset_ke
28e0: 79 3b 0a 0a 09 69 66 20 28 69 6e 74 65 72 70 20 y;...if (interp
28f0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 6e 74 == NULL) {...int
2900: 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 65 61 erp = appfs_crea
2910: 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e 55 4c te_TclInterp(NUL
2920: 4c 29 3b 0a 0a 09 09 69 66 20 28 69 6e 74 65 72 L);....if (inter
2930: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 p == NULL) {....
2940: 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 72 65 APPFS_DEBUG("Cre
2950: 61 74 65 20 69 6e 74 65 72 70 20 66 61 69 6c 65 ate interp faile
2960: 64 2c 20 72 65 74 75 72 6e 69 6e 67 69 6e 20 66 d, returningin f
2970: 61 69 6c 75 72 65 2e 22 29 3b 0a 0a 09 09 09 72 ailure.");.....r
2980: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d eturn(NULL);...}
2990: 0a 0a 09 09 70 74 68 72 65 61 64 5f 72 65 74 20 ....pthread_ret
29a0: 3d 20 70 74 68 72 65 61 64 5f 73 65 74 73 70 65 = pthread_setspe
29b0: 63 69 66 69 63 28 69 6e 74 65 72 70 4b 65 79 2c cific(interpKey,
29c0: 20 69 6e 74 65 72 70 29 3b 0a 09 09 69 66 20 28 interp);...if (
29d0: 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 pthread_ret != 0
29e0: 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 42 ) {....APPFS_DEB
29f0: 55 47 28 22 70 74 68 72 65 61 64 5f 73 65 74 73 UG("pthread_sets
2a00: 70 65 63 69 66 69 63 28 29 20 66 61 69 6c 65 64 pecific() failed
2a10: 2e 20 20 54 65 72 6d 69 6e 61 74 69 6e 67 20 54 . Terminating T
2a20: 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 2e 22 cl interpreter."
2a30: 29 3b 0a 0a 09 09 09 61 70 70 66 73 5f 63 61 6c );.....appfs_cal
2a40: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 44 65 6c l_libtcl(Tcl_Del
2a50: 65 74 65 49 6e 74 65 72 70 28 69 6e 74 65 72 70 eteInterp(interp
2a60: 29 3b 29 0a 0a 09 09 09 72 65 74 75 72 6e 28 4e );).....return(N
2a70: 55 4c 4c 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 ULL);...}..}...r
2a80: 65 74 75 72 6e 28 69 6e 74 65 72 70 29 3b 0a 7d eturn(interp);.}
2a90: 0a 0a 2f 2a 0a 20 2a 20 45 76 61 6c 75 61 74 65 ../*. * Evaluate
2aa0: 20 61 20 54 63 6c 20 73 63 72 69 70 74 20 63 6f a Tcl script co
2ab0: 6e 73 74 72 75 63 74 65 64 20 62 79 20 63 6f 6e nstructed by con
2ac0: 63 61 74 65 6e 61 74 69 6e 67 20 61 20 62 75 6e catenating a bun
2ad0: 63 68 20 6f 66 20 43 20 73 74 72 69 6e 67 73 0a ch of C strings.
2ae0: 20 2a 20 74 6f 67 65 74 68 65 72 2e 0a 20 2a 2f * together.. */
2af0: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 .static int appf
2b00: 73 5f 54 63 6c 5f 45 76 61 6c 28 54 63 6c 5f 49 s_Tcl_Eval(Tcl_I
2b10: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 20 69 nterp *interp, i
2b20: 6e 74 20 6f 62 6a 63 2c 20 63 6f 6e 73 74 20 63 nt objc, const c
2b30: 68 61 72 20 2a 63 6d 64 2c 20 2e 2e 2e 29 20 7b har *cmd, ...) {
2b40: 0a 09 54 63 6c 5f 4f 62 6a 20 2a 2a 6f 62 6a 76 ..Tcl_Obj **objv
2b50: 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 ;..const char *a
2b60: 72 67 3b 0a 09 76 61 5f 6c 69 73 74 20 61 72 67 rg;..va_list arg
2b70: 70 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a p;..int retval;.
2b80: 09 69 6e 74 20 69 3b 0a 0a 09 69 66 20 28 69 6e .int i;...if (in
2b90: 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a terp == NULL) {.
2ba0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 49 ..APPFS_DEBUG("I
2bb0: 6e 76 61 6c 69 64 20 69 6e 74 65 72 70 72 65 74 nvalid interpret
2bc0: 65 72 20 70 61 73 73 65 64 20 69 6e 2c 20 72 65 er passed in, re
2bd0: 74 75 72 6e 69 6e 67 20 69 6e 20 66 61 69 6c 75 turning in failu
2be0: 72 65 2e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e re.");....return
2bf0: 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a (TCL_ERROR);..}.
2c00: 0a 09 6f 62 6a 76 20 3d 20 28 76 6f 69 64 20 2a ..objv = (void *
2c10: 29 20 63 6b 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 ) ckalloc(sizeof
2c20: 28 2a 6f 62 6a 76 29 20 2a 20 6f 62 6a 63 29 3b (*objv) * objc);
2c30: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 ...appfs_call_li
2c40: 62 74 63 6c 28 0a 09 09 6f 62 6a 76 5b 30 5d 20 btcl(...objv[0]
2c50: 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f = Tcl_NewStringO
2c60: 62 6a 28 63 6d 64 2c 20 2d 31 29 3b 0a 0a 09 09 bj(cmd, -1);....
2c70: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 Tcl_IncrRefCount
2c80: 28 6f 62 6a 76 5b 30 5d 29 3b 0a 0a 09 09 76 61 (objv[0]);....va
2c90: 5f 73 74 61 72 74 28 61 72 67 70 2c 20 63 6d 64 _start(argp, cmd
2ca0: 29 3b 0a 09 09 66 6f 72 20 28 69 20 3d 20 31 3b );...for (i = 1;
2cb0: 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29 20 i < objc; i++)
2cc0: 7b 0a 09 09 09 61 72 67 20 3d 20 76 61 5f 61 72 {....arg = va_ar
2cd0: 67 28 61 72 67 70 2c 20 63 6f 6e 73 74 20 63 68 g(argp, const ch
2ce0: 61 72 20 2a 29 3b 0a 0a 09 09 09 6f 62 6a 76 5b ar *);.....objv[
2cf0: 69 5d 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 i] = Tcl_NewStri
2d00: 6e 67 4f 62 6a 28 61 72 67 2c 20 2d 31 29 3b 0a ngObj(arg, -1);.
2d10: 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 ....Tcl_IncrRefC
2d20: 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a 09 ount(objv[i]);..
2d30: 09 7d 0a 09 09 76 61 5f 65 6e 64 28 61 72 67 70 .}...va_end(argp
2d40: 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 5f 63 61 );..)...appfs_ca
2d50: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 74 ll_libtcl(...ret
2d60: 76 61 6c 20 3d 20 54 63 6c 5f 45 76 61 6c 4f 62 val = Tcl_EvalOb
2d70: 6a 76 28 69 6e 74 65 72 70 2c 20 6f 62 6a 63 2c jv(interp, objc,
2d80: 20 6f 62 6a 76 2c 20 30 29 3b 0a 09 29 0a 0a 09 objv, 0);..)...
2d90: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 appfs_call_libtc
2da0: 6c 28 0a 09 09 66 6f 72 20 28 69 20 3d 20 30 3b l(...for (i = 0;
2db0: 20 69 20 3c 20 6f 62 6a 63 3b 20 69 2b 2b 29 20 i < objc; i++)
2dc0: 7b 0a 09 09 09 54 63 6c 5f 44 65 63 72 52 65 66 {....Tcl_DecrRef
2dd0: 43 6f 75 6e 74 28 6f 62 6a 76 5b 69 5d 29 3b 0a Count(objv[i]);.
2de0: 09 09 7d 0a 09 29 0a 0a 09 63 6b 66 72 65 65 28 ..}..)...ckfree(
2df0: 28 76 6f 69 64 20 2a 29 20 6f 62 6a 76 29 3b 0a (void *) objv);.
2e00: 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20 ..if (retval !=
2e10: 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 61 70 70 66 TCL_OK) {...appf
2e20: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 s_call_libtcl(..
2e30: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 54 ..APPFS_DEBUG("T
2e40: 63 6c 20 63 6f 6d 6d 61 6e 64 20 66 61 69 6c 65 cl command faile
2e50: 64 2c 20 3a 3a 65 72 72 6f 72 49 6e 66 6f 20 63 d, ::errorInfo c
2e60: 6f 6e 74 61 69 6e 73 3a 20 25 73 5c 6e 22 2c 20 ontains: %s\n",
2e70: 54 63 6c 5f 47 65 74 56 61 72 28 69 6e 74 65 72 Tcl_GetVar(inter
2e80: 70 2c 20 22 3a 3a 65 72 72 6f 72 49 6e 66 6f 22 p, "::errorInfo"
2e90: 2c 20 30 29 29 3b 0a 09 09 29 0a 09 7d 0a 0a 09 , 0));...)..}...
2ea0: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a return(retval);.
2eb0: 7d 0a 0a 2f 2a 0a 20 2a 20 52 65 71 75 65 73 74 }../*. * Request
2ec0: 20 61 6c 6c 20 54 63 6c 20 69 6e 74 65 72 70 72 all Tcl interpr
2ed0: 65 74 65 72 73 20 72 65 73 74 61 72 74 0a 20 2a eters restart. *
2ee0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 /.static void ap
2ef0: 70 66 73 5f 74 63 6c 5f 52 65 73 65 74 49 6e 74 pfs_tcl_ResetInt
2f00: 65 72 70 73 28 76 6f 69 64 29 20 7b 0a 09 41 50 erps(void) {..AP
2f10: 50 46 53 5f 44 45 42 55 47 28 22 52 65 71 75 65 PFS_DEBUG("Reque
2f20: 73 74 69 6e 67 20 72 65 73 65 74 20 6f 66 20 61 sting reset of a
2f30: 6c 6c 20 69 6e 74 65 72 70 72 65 74 65 72 73 2e ll interpreters.
2f40: 22 29 3b 0a 0a 09 5f 5f 73 79 6e 63 5f 61 64 64 ");...__sync_add
2f50: 5f 61 6e 64 5f 66 65 74 63 68 28 26 69 6e 74 65 _and_fetch(&inte
2f60: 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 31 29 rp_reset_key, 1)
2f70: 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f ;...return;.}../
2f80: 2a 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65 20 74 *. * Determine t
2f90: 68 65 20 55 49 44 20 66 6f 72 20 74 68 65 20 75 he UID for the u
2fa0: 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 63 ser making the c
2fb0: 75 72 72 65 6e 74 20 46 55 53 45 20 66 69 6c 65 urrent FUSE file
2fc0: 73 79 73 74 65 6d 20 72 65 71 75 65 73 74 2e 0a system request..
2fd0: 20 2a 20 54 68 69 73 20 77 69 6c 6c 20 62 65 20 * This will be
2fe0: 75 73 65 64 20 74 6f 20 6c 6f 6f 6b 75 70 20 74 used to lookup t
2ff0: 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64 he user's home d
3000: 69 72 65 63 74 6f 72 79 20 73 6f 20 77 65 20 63 irectory so we c
3010: 61 6e 20 73 65 61 72 63 68 20 66 6f 72 0a 20 2a an search for. *
3020: 20 6c 6f 63 61 6c 6c 79 20 6d 6f 64 69 66 69 65 locally modifie
3030: 64 20 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73 74 61 d files.. */.sta
3040: 74 69 63 20 75 69 64 5f 74 20 61 70 70 66 73 5f tic uid_t appfs_
3050: 67 65 74 5f 66 73 75 69 64 28 76 6f 69 64 29 20 get_fsuid(void)
3060: 7b 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f 63 {..struct fuse_c
3070: 6f 6e 74 65 78 74 20 2a 63 74 78 3b 0a 0a 09 69 ontext *ctx;...i
3080: 66 20 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73 f (!appfs_fuse_s
3090: 74 61 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75 tarted) {...retu
30a0: 72 6e 28 67 65 74 75 69 64 28 29 29 3b 0a 09 7d rn(getuid());..}
30b0: 0a 0a 09 63 74 78 20 3d 20 66 75 73 65 5f 67 65 ...ctx = fuse_ge
30c0: 74 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09 69 66 t_context();..if
30d0: 20 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 20 7b (ctx == NULL) {
30e0: 0a 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74 6f 20 .../* Unable to
30f0: 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20 lookup user for
3100: 73 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f 0a 09 some reason */..
3110: 09 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20 75 6e ./* Return an un
3120: 70 72 69 76 69 6c 65 67 65 64 20 75 73 65 72 20 privileged user
3130: 49 44 20 2a 2f 0a 09 09 41 50 50 46 53 5f 44 45 ID */...APPFS_DE
3140: 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c BUG("Unable to l
3150: 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20 73 ookup user for s
3160: 6f 6d 65 20 72 65 61 73 6f 6e 2c 20 72 65 74 75 ome reason, retu
3170: 72 6e 69 6e 6e 67 20 75 73 65 72 20 49 44 20 6f rninng user ID o
3180: 66 20 31 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e f 1");....return
3190: 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e (1);..}...return
31a0: 28 63 74 78 2d 3e 75 69 64 29 3b 0a 7d 0a 0a 2f (ctx->uid);.}../
31b0: 2a 0a 20 2a 20 44 65 74 65 72 6d 69 6e 65 20 74 *. * Determine t
31c0: 68 65 20 47 49 44 20 66 6f 72 20 74 68 65 20 75 he GID for the u
31d0: 73 65 72 20 6d 61 6b 69 6e 67 20 74 68 65 20 63 ser making the c
31e0: 75 72 72 65 6e 74 20 46 55 53 45 20 66 69 6c 65 urrent FUSE file
31f0: 73 79 73 74 65 6d 20 72 65 71 75 65 73 74 2e 0a system request..
3200: 20 2a 20 54 68 69 73 20 77 69 6c 6c 20 62 65 20 * This will be
3210: 75 73 65 64 20 74 6f 20 6c 6f 6f 6b 75 70 20 74 used to lookup t
3220: 68 65 20 75 73 65 72 27 73 20 68 6f 6d 65 20 64 he user's home d
3230: 69 72 65 63 74 6f 72 79 20 73 6f 20 77 65 20 63 irectory so we c
3240: 61 6e 20 73 65 61 72 63 68 20 66 6f 72 0a 20 2a an search for. *
3250: 20 6c 6f 63 61 6c 6c 79 20 6d 6f 64 69 66 69 65 locally modifie
3260: 64 20 66 69 6c 65 73 2e 0a 20 2a 2f 0a 73 74 61 d files.. */.sta
3270: 74 69 63 20 67 69 64 5f 74 20 61 70 70 66 73 5f tic gid_t appfs_
3280: 67 65 74 5f 66 73 67 69 64 28 76 6f 69 64 29 20 get_fsgid(void)
3290: 7b 0a 09 73 74 72 75 63 74 20 66 75 73 65 5f 63 {..struct fuse_c
32a0: 6f 6e 74 65 78 74 20 2a 63 74 78 3b 0a 0a 09 69 ontext *ctx;...i
32b0: 66 20 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73 f (!appfs_fuse_s
32c0: 74 61 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75 tarted) {...retu
32d0: 72 6e 28 67 65 74 67 69 64 28 29 29 3b 0a 09 7d rn(getgid());..}
32e0: 0a 0a 09 63 74 78 20 3d 20 66 75 73 65 5f 67 65 ...ctx = fuse_ge
32f0: 74 5f 63 6f 6e 74 65 78 74 28 29 3b 0a 09 69 66 t_context();..if
3300: 20 28 63 74 78 20 3d 3d 20 4e 55 4c 4c 29 20 7b (ctx == NULL) {
3310: 0a 09 09 2f 2a 20 55 6e 61 62 6c 65 20 74 6f 20 .../* Unable to
3320: 6c 6f 6f 6b 75 70 20 75 73 65 72 20 66 6f 72 20 lookup user for
3330: 73 6f 6d 65 20 72 65 61 73 6f 6e 20 2a 2f 0a 09 some reason */..
3340: 09 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20 75 6e ./* Return an un
3350: 70 72 69 76 69 6c 65 67 65 64 20 75 73 65 72 20 privileged user
3360: 49 44 20 2a 2f 0a 09 09 41 50 50 46 53 5f 44 45 ID */...APPFS_DE
3370: 42 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c BUG("Unable to l
3380: 6f 6f 6b 75 70 20 67 72 6f 75 70 20 66 6f 72 20 ookup group for
3390: 73 6f 6d 65 20 72 65 61 73 6f 6e 2c 20 72 65 74 some reason, ret
33a0: 75 72 6e 69 6e 6e 67 20 67 72 6f 75 70 20 49 44 urninng group ID
33b0: 20 6f 66 20 31 22 29 3b 0a 0a 09 09 72 65 74 75 of 1");....retu
33c0: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 rn(1);..}...retu
33d0: 72 6e 28 63 74 78 2d 3e 67 69 64 29 3b 0a 7d 0a rn(ctx->gid);.}.
33e0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 .static void app
33f0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 fs_simulate_user
3400: 5f 66 73 5f 65 6e 74 65 72 28 76 6f 69 64 29 20 _fs_enter(void)
3410: 7b 0a 09 73 65 74 66 73 75 69 64 28 61 70 70 66 {..setfsuid(appf
3420: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a s_get_fsuid());.
3430: 09 73 65 74 66 73 67 69 64 28 61 70 70 66 73 5f .setfsgid(appfs_
3440: 67 65 74 5f 66 73 67 69 64 28 29 29 3b 0a 7d 0a get_fsgid());.}.
3450: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 .static void app
3460: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 fs_simulate_user
3470: 5f 66 73 5f 6c 65 61 76 65 28 76 6f 69 64 29 20 _fs_leave(void)
3480: 7b 0a 09 73 65 74 66 73 75 69 64 28 30 29 3b 0a {..setfsuid(0);.
3490: 09 73 65 74 66 73 67 69 64 28 30 29 3b 0a 7d 0a .setfsgid(0);.}.
34a0: 0a 2f 2a 0a 20 2a 20 4c 6f 6f 6b 20 75 70 20 74 ./*. * Look up t
34b0: 68 65 20 68 6f 6d 65 20 64 69 72 65 63 74 6f 72 he home director
34c0: 79 20 66 6f 72 20 61 20 67 69 76 65 6e 20 55 49 y for a given UI
34d0: 44 0a 20 2a 20 20 20 20 20 20 20 20 52 65 74 75 D. * Retu
34e0: 72 6e 73 20 61 20 43 20 73 74 72 69 6e 67 20 63 rns a C string c
34f0: 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 75 73 ontaining the us
3500: 65 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 er's home direct
3510: 6f 72 79 20 6f 72 20 4e 55 4c 4c 20 69 66 0a 20 ory or NULL if.
3520: 2a 20 20 20 20 20 20 20 20 74 68 65 20 75 73 65 * the use
3530: 72 27 73 20 68 6f 6d 65 20 64 69 72 65 63 74 6f r's home directo
3540: 72 79 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 ry does not exis
3550: 74 20 6f 72 20 69 73 20 6e 6f 74 20 63 6f 72 72 t or is not corr
3560: 65 63 74 6c 79 0a 20 2a 20 20 20 20 20 20 20 20 ectly. *
3570: 63 6f 6e 66 69 67 75 72 65 64 0a 20 2a 2f 0a 73 configured. */.s
3580: 74 61 74 69 63 20 63 68 61 72 20 2a 61 70 70 66 tatic char *appf
3590: 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 75 69 s_get_homedir(ui
35a0: 64 5f 74 20 66 73 75 69 64 29 20 7b 0a 09 73 74 d_t fsuid) {..st
35b0: 72 75 63 74 20 70 61 73 73 77 64 20 65 6e 74 72 ruct passwd entr
35c0: 79 2c 20 2a 72 65 73 75 6c 74 3b 0a 09 73 74 72 y, *result;..str
35d0: 75 63 74 20 73 74 61 74 20 73 74 62 75 66 3b 0a uct stat stbuf;.
35e0: 09 63 68 61 72 20 62 75 66 5b 31 30 32 34 5d 2c .char buf[1024],
35f0: 20 2a 72 65 74 76 61 6c 3b 0a 09 69 6e 74 20 67 *retval;..int g
3600: 70 75 5f 72 65 74 2c 20 73 74 61 74 5f 72 65 74 pu_ret, stat_ret
3610: 3b 0a 0a 09 67 70 75 5f 72 65 74 20 3d 20 67 65 ;...gpu_ret = ge
3620: 74 70 77 75 69 64 5f 72 28 66 73 75 69 64 2c 20 tpwuid_r(fsuid,
3630: 26 65 6e 74 72 79 2c 20 62 75 66 2c 20 73 69 7a &entry, buf, siz
3640: 65 6f 66 28 62 75 66 29 2c 20 26 72 65 73 75 6c eof(buf), &resul
3650: 74 29 3b 0a 09 69 66 20 28 67 70 75 5f 72 65 74 t);..if (gpu_ret
3660: 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 != 0) {...APPFS
3670: 5f 44 45 42 55 47 28 22 67 65 74 70 77 75 69 64 _DEBUG("getpwuid
3680: 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 65 _r(%llu, ...) re
3690: 74 75 72 6e 65 64 20 69 6e 20 66 61 69 6c 75 72 turned in failur
36a0: 65 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f e", (unsigned lo
36b0: 6e 67 20 6c 6f 6e 67 29 20 66 73 75 69 64 29 3b ng long) fsuid);
36c0: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 ....return(NULL)
36d0: 3b 0a 09 7d 0a 0a 09 69 66 20 28 72 65 73 75 6c ;..}...if (resul
36e0: 74 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 t == NULL) {...A
36f0: 50 50 46 53 5f 44 45 42 55 47 28 22 67 65 74 70 PPFS_DEBUG("getp
3700: 77 75 69 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e wuid_r(%llu, ...
3710: 29 20 72 65 74 75 72 6e 65 64 20 4e 55 4c 4c 20 ) returned NULL
3720: 72 65 73 75 6c 74 22 2c 20 28 75 6e 73 69 67 6e result", (unsign
3730: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 73 ed long long) fs
3740: 75 69 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 uid);....return(
3750: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 NULL);..}...if (
3760: 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 20 3d result->pw_dir =
3770: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 = NULL) {...APPF
3780: 53 5f 44 45 42 55 47 28 22 67 65 74 70 77 75 69 S_DEBUG("getpwui
3790: 64 5f 72 28 25 6c 6c 75 2c 20 2e 2e 2e 29 20 72 d_r(%llu, ...) r
37a0: 65 74 75 72 6e 65 64 20 4e 55 4c 4c 20 68 6f 6d eturned NULL hom
37b0: 65 20 64 69 72 65 63 74 6f 72 79 22 2c 20 28 75 e directory", (u
37c0: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e nsigned long lon
37d0: 67 29 20 66 73 75 69 64 29 3b 0a 0a 09 09 72 65 g) fsuid);....re
37e0: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a turn(NULL);..}..
37f0: 09 73 74 61 74 5f 72 65 74 20 3d 20 73 74 61 74 .stat_ret = stat
3800: 28 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 2c (result->pw_dir,
3810: 20 26 73 74 62 75 66 29 3b 0a 09 69 66 20 28 73 &stbuf);..if (s
3820: 74 61 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a tat_ret != 0) {.
3830: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 73 ..APPFS_DEBUG("s
3840: 74 61 74 28 25 73 29 20 72 65 74 75 72 6e 65 64 tat(%s) returned
3850: 20 69 6e 20 66 61 69 6c 75 72 65 22 2c 20 72 65 in failure", re
3860: 73 75 6c 74 2d 3e 70 77 5f 64 69 72 29 3b 0a 0a sult->pw_dir);..
3870: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a ..return(NULL);.
3880: 09 7d 0a 0a 09 69 66 20 28 73 74 62 75 66 2e 73 .}...if (stbuf.s
3890: 74 5f 75 69 64 20 21 3d 20 66 73 75 69 64 29 20 t_uid != fsuid)
38a0: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 {...APPFS_DEBUG(
38b0: 22 55 49 44 20 6d 69 73 2d 6d 61 74 63 68 20 6f "UID mis-match o
38c0: 6e 20 75 73 65 72 20 25 6c 6c 75 27 73 20 68 6f n user %llu's ho
38d0: 6d 65 20 64 69 72 65 63 74 6f 72 79 20 28 25 73 me directory (%s
38e0: 29 2e 20 20 49 74 27 73 20 6f 77 6e 65 64 20 62 ). It's owned b
38f0: 79 20 25 6c 6c 75 2e 22 2c 0a 09 09 20 20 20 20 y %llu.",...
3900: 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c (unsigned long l
3910: 6f 6e 67 29 20 66 73 75 69 64 2c 0a 09 09 20 20 ong) fsuid,...
3920: 20 20 72 65 73 75 6c 74 2d 3e 70 77 5f 64 69 72 result->pw_dir
3930: 2c 0a 09 09 20 20 20 20 28 75 6e 73 69 67 6e 65 ,... (unsigne
3940: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 74 62 d long long) stb
3950: 75 66 2e 73 74 5f 75 69 64 0a 09 09 29 3b 0a 0a uf.st_uid...);..
3960: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a ..return(NULL);.
3970: 09 7d 0a 0a 09 72 65 74 76 61 6c 20 3d 20 73 74 .}...retval = st
3980: 72 64 75 70 28 72 65 73 75 6c 74 2d 3e 70 77 5f rdup(result->pw_
3990: 64 69 72 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72 dir);...return(r
39a0: 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a etval);.}../*. *
39b0: 20 47 65 6e 65 72 61 74 65 20 61 6e 20 69 6e 6f Generate an ino
39c0: 64 65 20 66 6f 72 20 61 20 67 69 76 65 6e 20 70 de for a given p
39d0: 61 74 68 2e 20 20 54 68 65 20 69 6e 6f 64 65 20 ath. The inode
39e0: 73 68 6f 75 6c 64 20 62 65 20 63 6f 6d 70 75 74 should be comput
39f0: 65 64 20 69 6e 20 73 75 63 68 0a 20 2a 20 61 20 ed in such. * a
3a00: 77 61 79 20 74 68 61 74 20 69 74 20 69 73 20 75 way that it is u
3a10: 6e 6c 69 6b 65 6c 79 20 74 6f 20 62 65 20 64 75 nlikely to be du
3a20: 70 6c 69 63 61 74 65 64 20 61 6e 64 20 72 65 6d plicated and rem
3a30: 61 69 6e 73 20 74 68 65 20 73 61 6d 65 20 66 6f ains the same fo
3a40: 72 20 61 20 67 69 76 65 6e 0a 20 2a 20 66 69 6c r a given. * fil
3a50: 65 0a 20 2a 0a 20 2a 20 43 75 72 72 65 6e 74 20 e. *. * Current
3a60: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 69 implementation i
3a70: 73 20 61 6e 20 46 4e 56 2d 31 61 20 33 32 2d 62 s an FNV-1a 32-b
3a80: 69 74 0a 20 2a 2f 0a 23 69 66 20 55 49 4e 54 5f it. */.#if UINT_
3a90: 4d 41 58 20 3c 20 34 32 39 34 39 36 37 32 39 35 MAX < 4294967295
3aa0: 0a 23 65 72 72 6f 72 20 49 6e 74 65 67 65 72 20 .#error Integer
3ab0: 73 69 7a 65 20 69 73 20 74 6f 6f 20 73 6d 61 6c size is too smal
3ac0: 6c 20 0a 23 65 6e 64 69 66 0a 73 74 61 74 69 63 l .#endif.static
3ad0: 20 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c unsigned long l
3ae0: 6f 6e 67 20 61 70 70 66 73 5f 67 65 74 5f 70 61 ong appfs_get_pa
3af0: 74 68 5f 69 6e 6f 64 65 28 63 6f 6e 73 74 20 63 th_inode(const c
3b00: 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 75 6e har *path) {..un
3b10: 73 69 67 6e 65 64 20 69 6e 74 20 72 65 74 76 61 signed int retva
3b20: 6c 3b 0a 09 63 6f 6e 73 74 20 75 6e 73 69 67 6e l;..const unsign
3b30: 65 64 20 63 68 61 72 20 2a 70 3b 0a 0a 09 72 65 ed char *p;...re
3b40: 74 76 61 6c 20 3d 20 32 31 36 36 31 33 36 32 36 tval = 216613626
3b50: 31 3b 20 2f 2a 20 46 4e 56 2d 31 61 20 33 32 2d 1; /* FNV-1a 32-
3b60: 62 69 74 20 6f 66 66 73 65 74 5f 62 61 73 69 73 bit offset_basis
3b70: 20 2a 2f 0a 0a 09 66 6f 72 20 28 70 20 3d 20 28 */...for (p = (
3b80: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 29 unsigned char *)
3b90: 20 70 61 74 68 3b 20 2a 70 3b 20 70 2b 2b 29 20 path; *p; p++)
3ba0: 7b 0a 09 09 72 65 74 76 61 6c 20 5e 3d 20 28 69 {...retval ^= (i
3bb0: 6e 74 29 20 2a 70 3b 0a 23 69 66 20 30 0a 09 09 nt) *p;.#if 0...
3bc0: 72 65 74 76 61 6c 20 2a 3d 20 31 36 37 37 37 36 retval *= 167776
3bd0: 31 39 3b 20 2f 2a 20 46 4e 56 2d 31 61 20 33 32 19; /* FNV-1a 32
3be0: 2d 62 69 74 20 70 72 69 6d 65 20 2a 2f 0a 23 65 -bit prime */.#e
3bf0: 6c 73 65 0a 09 09 2f 2a 20 47 43 43 20 4f 70 74 lse.../* GCC Opt
3c00: 69 6d 69 7a 65 64 20 72 65 70 6c 61 63 65 6d 65 imized replaceme
3c10: 6e 74 20 2a 2f 0a 09 09 72 65 74 76 61 6c 20 2b nt */...retval +
3c20: 3d 20 28 72 65 74 76 61 6c 20 3c 3c 20 31 29 20 = (retval << 1)
3c30: 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 34 29 20 + (retval << 4)
3c40: 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 37 29 20 + (retval << 7)
3c50: 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 38 29 20 + (retval << 8)
3c60: 2b 20 28 72 65 74 76 61 6c 20 3c 3c 20 32 34 29 + (retval << 24)
3c70: 3b 0a 23 65 6e 64 69 66 0a 09 7d 0a 0a 09 72 65 ;.#endif..}...re
3c80: 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a turn(retval);.}.
3c90: 0a 2f 2a 0a 20 2a 20 43 61 63 68 65 20 47 65 74 ./*. * Cache Get
3ca0: 20 50 61 74 68 20 49 6e 66 6f 20 6c 6f 6f 6b 75 Path Info looku
3cb0: 70 73 20 66 6f 72 20 73 70 65 65 64 0a 20 2a 2f ps for speed. */
3cc0: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 .static int appf
3cd0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f s_get_path_info_
3ce0: 63 61 63 68 65 5f 67 65 74 28 63 6f 6e 73 74 20 cache_get(const
3cf0: 63 68 61 72 20 2a 70 61 74 68 2c 20 75 69 64 5f char *path, uid_
3d00: 74 20 75 69 64 2c 20 73 74 72 75 63 74 20 61 70 t uid, struct ap
3d10: 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a 70 61 pfs_pathinfo *pa
3d20: 74 68 69 6e 66 6f 29 20 7b 0a 09 75 6e 73 69 67 thinfo) {..unsig
3d30: 6e 65 64 20 69 6e 74 20 68 61 73 68 5f 69 64 78 ned int hash_idx
3d40: 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 ;..int pthread_r
3d50: 65 74 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b et;..int retval;
3d60: 0a 0a 09 72 65 74 76 61 6c 20 3d 20 31 3b 0a 0a ...retval = 1;..
3d70: 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 .pthread_ret = p
3d80: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 thread_mutex_loc
3d90: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e k(&appfs_path_in
3da0: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b fo_cache_mutex);
3db0: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 ..if (pthread_re
3dc0: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 t != 0) {...APPF
3dd0: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 S_DEBUG("Unable
3de0: 74 6f 20 6c 6f 63 6b 20 70 61 74 68 5f 69 6e 66 to lock path_inf
3df0: 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 21 22 o cache mutex !"
3e00: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 31 29 );....return(-1)
3e10: 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73 ;..}...if (appfs
3e20: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 _path_info_cache
3e30: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 61 != NULL) {...ha
3e40: 73 68 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f sh_idx = (appfs_
3e50: 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 get_path_inode(p
3e60: 61 74 68 29 20 2b 20 75 69 64 29 20 25 20 61 70 ath) + uid) % ap
3e70: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 pfs_path_info_ca
3e80: 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 09 69 66 20 che_size;....if
3e90: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f (appfs_path_info
3ea0: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d _cache[hash_idx]
3eb0: 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20 ._cache_path !=
3ec0: 4e 55 4c 4c 29 20 7b 0a 09 09 09 69 66 20 28 73 NULL) {....if (s
3ed0: 74 72 63 6d 70 28 61 70 70 66 73 5f 70 61 74 68 trcmp(appfs_path
3ee0: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 _info_cache[hash
3ef0: 5f 69 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 _idx]._cache_pat
3f00: 68 2c 20 70 61 74 68 29 20 3d 3d 20 30 20 26 26 h, path) == 0 &&
3f10: 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f appfs_path_info
3f20: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d _cache[hash_idx]
3f30: 2e 5f 63 61 63 68 65 5f 75 69 64 20 3d 3d 20 75 ._cache_uid == u
3f40: 69 64 29 20 7b 0a 09 09 09 09 72 65 74 76 61 6c id) {.....retval
3f50: 20 3d 20 30 3b 0a 0a 09 09 09 09 6d 65 6d 63 70 = 0;......memcp
3f60: 79 28 70 61 74 68 69 6e 66 6f 2c 20 26 61 70 70 y(pathinfo, &app
3f70: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 fs_path_info_cac
3f80: 68 65 5b 68 61 73 68 5f 69 64 78 5d 2c 20 73 69 he[hash_idx], si
3f90: 7a 65 6f 66 28 2a 70 61 74 68 69 6e 66 6f 29 29 zeof(*pathinfo))
3fa0: 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e ;.....pathinfo->
3fb0: 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20 4e 55 _cache_path = NU
3fc0: 4c 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a LL;....}...}..}.
3fd0: 0a 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 ..pthread_ret =
3fe0: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e pthread_mutex_un
3ff0: 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 lock(&appfs_path
4000: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 _info_cache_mute
4010: 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 x);..if (pthread
4020: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 _ret != 0) {...A
4030: 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 PPFS_DEBUG("Unab
4040: 6c 65 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 le to unlock pat
4050: 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 h_info cache mut
4060: 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 ex !");....retur
4070: 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 n(-1);..}...if (
4080: 72 65 74 76 61 6c 20 3d 3d 20 30 29 20 7b 0a 09 retval == 0) {..
4090: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 61 .APPFS_DEBUG("Ca
40a0: 63 68 65 20 68 69 74 20 6f 6e 20 25 73 22 2c 20 che hit on %s",
40b0: 70 61 74 68 29 3b 0a 09 7d 20 65 6c 73 65 20 7b path);..} else {
40c0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 ...APPFS_DEBUG("
40d0: 43 61 63 68 65 20 6d 69 73 73 20 6f 6e 20 25 73 Cache miss on %s
40e0: 22 2c 20 70 61 74 68 29 3b 0a 09 7d 0a 0a 09 72 ", path);..}...r
40f0: 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d eturn(retval);.}
4100: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 ..static void ap
4110: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 pfs_get_path_inf
4120: 6f 5f 63 61 63 68 65 5f 61 64 64 28 63 6f 6e 73 o_cache_add(cons
4130: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 75 69 t char *path, ui
4140: 64 5f 74 20 75 69 64 2c 20 73 74 72 75 63 74 20 d_t uid, struct
4150: 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f 20 2a appfs_pathinfo *
4160: 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 75 6e 73 pathinfo) {..uns
4170: 69 67 6e 65 64 20 69 6e 74 20 68 61 73 68 5f 69 igned int hash_i
4180: 64 78 3b 0a 09 69 6e 74 20 70 74 68 72 65 61 64 dx;..int pthread
4190: 5f 72 65 74 3b 0a 0a 09 70 74 68 72 65 61 64 5f _ret;...pthread_
41a0: 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 ret = pthread_mu
41b0: 74 65 78 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f tex_lock(&appfs_
41c0: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f path_info_cache_
41d0: 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 74 68 mutex);..if (pth
41e0: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b read_ret != 0) {
41f0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 ...APPFS_DEBUG("
4200: 55 6e 61 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 Unable to lock p
4210: 61 74 68 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d ath_info cache m
4220: 75 74 65 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 utex !");....ret
4230: 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 urn;..}...if (ap
4240: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 pfs_path_info_ca
4250: 63 68 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 che == NULL) {..
4260: 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f .appfs_path_info
4270: 5f 63 61 63 68 65 20 3d 20 63 61 6c 6c 6f 63 28 _cache = calloc(
4280: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f appfs_path_info_
4290: 63 61 63 68 65 5f 73 69 7a 65 2c 20 73 69 7a 65 cache_size, size
42a0: 6f 66 28 2a 61 70 70 66 73 5f 70 61 74 68 5f 69 of(*appfs_path_i
42b0: 6e 66 6f 5f 63 61 63 68 65 29 29 3b 0a 09 7d 0a nfo_cache));..}.
42c0: 0a 09 68 61 73 68 5f 69 64 78 20 3d 20 28 61 70 ..hash_idx = (ap
42d0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 6f pfs_get_path_ino
42e0: 64 65 28 70 61 74 68 29 20 2b 20 75 69 64 29 20 de(path) + uid)
42f0: 25 20 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 % appfs_path_inf
4300: 6f 5f 63 61 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 o_cache_size;...
4310: 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 if (appfs_path_i
4320: 6e 66 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 nfo_cache[hash_i
4330: 64 78 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 dx]._cache_path
4340: 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 72 65 != NULL) {...fre
4350: 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 e(appfs_path_inf
4360: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 o_cache[hash_idx
4370: 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a ]._cache_path);.
4380: 09 7d 0a 0a 09 6d 65 6d 63 70 79 28 26 61 70 70 .}...memcpy(&app
4390: 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 fs_path_info_cac
43a0: 68 65 5b 68 61 73 68 5f 69 64 78 5d 2c 20 70 61 he[hash_idx], pa
43b0: 74 68 69 6e 66 6f 2c 20 73 69 7a 65 6f 66 28 2a thinfo, sizeof(*
43c0: 70 61 74 68 69 6e 66 6f 29 29 3b 0a 0a 09 61 70 pathinfo));...ap
43d0: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 pfs_path_info_ca
43e0: 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 che[hash_idx]._c
43f0: 61 63 68 65 5f 70 61 74 68 20 3d 20 73 74 72 64 ache_path = strd
4400: 75 70 28 70 61 74 68 29 3b 0a 09 61 70 70 66 73 up(path);..appfs
4410: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 _path_info_cache
4420: 5b 68 61 73 68 5f 69 64 78 5d 2e 5f 63 61 63 68 [hash_idx]._cach
4430: 65 5f 75 69 64 20 20 3d 20 75 69 64 3b 0a 0a 09 e_uid = uid;...
4440: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 pthread_ret = pt
4450: 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f hread_mutex_unlo
4460: 63 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 ck(&appfs_path_i
4470: 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 nfo_cache_mutex)
4480: 3b 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 ;..if (pthread_r
4490: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 et != 0) {...APP
44a0: 46 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 FS_DEBUG("Unable
44b0: 20 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f to unlock path_
44c0: 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 info cache mutex
44d0: 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b !");....return;
44e0: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a ..}...return;.}.
44f0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 .static void app
4500: 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f fs_get_path_info
4510: 5f 63 61 63 68 65 5f 72 6d 28 63 6f 6e 73 74 20 _cache_rm(const
4520: 63 68 61 72 20 2a 70 61 74 68 2c 20 75 69 64 5f char *path, uid_
4530: 74 20 75 69 64 29 20 7b 0a 09 75 6e 73 69 67 6e t uid) {..unsign
4540: 65 64 20 69 6e 74 20 68 61 73 68 5f 69 64 78 3b ed int hash_idx;
4550: 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 ..int pthread_re
4560: 74 3b 0a 0a 09 70 74 68 72 65 61 64 5f 72 65 74 t;...pthread_ret
4570: 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 = pthread_mutex
4580: 5f 6c 6f 63 6b 28 26 61 70 70 66 73 5f 70 61 74 _lock(&appfs_pat
4590: 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 6d 75 74 h_info_cache_mut
45a0: 65 78 29 3b 0a 09 69 66 20 28 70 74 68 72 65 61 ex);..if (pthrea
45b0: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 d_ret != 0) {...
45c0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 55 6e 61 APPFS_DEBUG("Una
45d0: 62 6c 65 20 74 6f 20 6c 6f 63 6b 20 70 61 74 68 ble to lock path
45e0: 5f 69 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 _info cache mute
45f0: 78 20 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e x !");....return
4600: 3b 0a 09 7d 0a 0a 09 69 66 20 28 61 70 70 66 73 ;..}...if (appfs
4610: 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 _path_info_cache
4620: 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 68 61 != NULL) {...ha
4630: 73 68 5f 69 64 78 20 3d 20 28 61 70 70 66 73 5f sh_idx = (appfs_
4640: 67 65 74 5f 70 61 74 68 5f 69 6e 6f 64 65 28 70 get_path_inode(p
4650: 61 74 68 29 20 2b 20 75 69 64 29 20 25 20 61 70 ath) + uid) % ap
4660: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 pfs_path_info_ca
4670: 63 68 65 5f 73 69 7a 65 3b 0a 0a 09 09 69 66 20 che_size;....if
4680: 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f (appfs_path_info
4690: 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d _cache[hash_idx]
46a0: 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20 ._cache_path !=
46b0: 4e 55 4c 4c 29 20 7b 0a 09 09 09 66 72 65 65 28 NULL) {....free(
46c0: 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f appfs_path_info_
46d0: 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 5d 2e cache[hash_idx].
46e0: 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a 0a 09 _cache_path);...
46f0: 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 ..appfs_path_inf
4700: 6f 5f 63 61 63 68 65 5b 68 61 73 68 5f 69 64 78 o_cache[hash_idx
4710: 5d 2e 5f 63 61 63 68 65 5f 70 61 74 68 20 3d 20 ]._cache_path =
4720: 4e 55 4c 4c 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 70 NULL;...}..}...p
4730: 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 thread_ret = pth
4740: 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 read_mutex_unloc
4750: 6b 28 26 61 70 70 66 73 5f 70 61 74 68 5f 69 6e k(&appfs_path_in
4760: 66 6f 5f 63 61 63 68 65 5f 6d 75 74 65 78 29 3b fo_cache_mutex);
4770: 0a 09 69 66 20 28 70 74 68 72 65 61 64 5f 72 65 ..if (pthread_re
4780: 74 20 21 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 t != 0) {...APPF
4790: 53 5f 44 45 42 55 47 28 22 55 6e 61 62 6c 65 20 S_DEBUG("Unable
47a0: 74 6f 20 75 6e 6c 6f 63 6b 20 70 61 74 68 5f 69 to unlock path_i
47b0: 6e 66 6f 20 63 61 63 68 65 20 6d 75 74 65 78 20 nfo cache mutex
47c0: 21 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a !");....return;.
47d0: 09 7d 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a .}...return;.}..
47e0: 73 74 61 74 69 63 20 76 6f 69 64 20 61 70 70 66 static void appf
47f0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f s_get_path_info_
4800: 63 61 63 68 65 5f 66 6c 75 73 68 28 75 69 64 5f cache_flush(uid_
4810: 74 20 75 69 64 2c 20 69 6e 74 20 6e 65 77 5f 73 t uid, int new_s
4820: 69 7a 65 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64 ize) {..unsigned
4830: 20 69 6e 74 20 69 64 78 3b 0a 09 69 6e 74 20 70 int idx;..int p
4840: 74 68 72 65 61 64 5f 72 65 74 3b 0a 0a 09 41 50 thread_ret;...AP
4850: 50 46 53 5f 44 45 42 55 47 28 22 46 6c 75 73 68 PFS_DEBUG("Flush
4860: 69 6e 67 20 41 70 70 46 53 20 63 61 63 68 65 20 ing AppFS cache
4870: 28 75 69 64 20 3d 20 25 6c 6c 69 2c 20 6e 65 77 (uid = %lli, new
4880: 5f 73 69 7a 65 20 3d 20 25 69 29 22 2c 20 28 6c _size = %i)", (l
4890: 6f 6e 67 20 6c 6f 6e 67 29 20 75 69 64 2c 20 6e ong long) uid, n
48a0: 65 77 5f 73 69 7a 65 29 3b 0a 0a 09 70 74 68 72 ew_size);...pthr
48b0: 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 ead_ret = pthrea
48c0: 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 61 70 d_mutex_lock(&ap
48d0: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 pfs_path_info_ca
48e0: 63 68 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 che_mutex);..if
48f0: 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 (pthread_ret !=
4900: 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 0) {...APPFS_DEB
4910: 55 47 28 22 55 6e 61 62 6c 65 20 74 6f 20 6c 6f UG("Unable to lo
4920: 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 ck path_info cac
4930: 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 he mutex !");...
4940: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 69 66 .return;..}...if
4950: 20 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 (appfs_path_inf
4960: 6f 5f 63 61 63 68 65 20 21 3d 20 4e 55 4c 4c 29 o_cache != NULL)
4970: 20 7b 0a 09 09 66 6f 72 20 28 69 64 78 20 3d 20 {...for (idx =
4980: 30 3b 20 69 64 78 20 3c 20 61 70 70 66 73 5f 70 0; idx < appfs_p
4990: 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 ath_info_cache_s
49a0: 69 7a 65 3b 20 69 64 78 2b 2b 29 20 7b 0a 09 09 ize; idx++) {...
49b0: 09 69 66 20 28 61 70 70 66 73 5f 70 61 74 68 5f .if (appfs_path_
49c0: 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e info_cache[idx].
49d0: 5f 63 61 63 68 65 5f 70 61 74 68 20 21 3d 20 4e _cache_path != N
49e0: 55 4c 4c 29 20 7b 0a 09 09 09 09 69 66 20 28 75 ULL) {.....if (u
49f0: 69 64 20 21 3d 20 28 28 75 69 64 5f 74 29 20 2d id != ((uid_t) -
4a00: 31 29 29 20 7b 0a 09 09 09 09 09 69 66 20 28 61 1)) {......if (a
4a10: 70 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 ppfs_path_info_c
4a20: 61 63 68 65 5b 69 64 78 5d 2e 5f 63 61 63 68 65 ache[idx]._cache
4a30: 5f 75 69 64 20 21 3d 20 75 69 64 29 20 7b 0a 09 _uid != uid) {..
4a40: 09 09 09 09 09 63 6f 6e 74 69 6e 75 65 3b 0a 09 .....continue;..
4a50: 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a 09 09 09 ....}.....}.....
4a60: 09 66 72 65 65 28 61 70 70 66 73 5f 70 61 74 68 .free(appfs_path
4a70: 5f 69 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d _info_cache[idx]
4a80: 2e 5f 63 61 63 68 65 5f 70 61 74 68 29 3b 0a 0a ._cache_path);..
4a90: 09 09 09 09 61 70 70 66 73 5f 70 61 74 68 5f 69 ....appfs_path_i
4aa0: 6e 66 6f 5f 63 61 63 68 65 5b 69 64 78 5d 2e 5f nfo_cache[idx]._
4ab0: 63 61 63 68 65 5f 70 61 74 68 20 3d 20 4e 55 4c cache_path = NUL
4ac0: 4c 3b 0a 09 09 09 7d 0a 09 09 7d 0a 09 7d 0a 0a L;....}...}..}..
4ad0: 09 69 66 20 28 75 69 64 20 3d 3d 20 28 28 75 69 .if (uid == ((ui
4ae0: 64 5f 74 29 20 2d 31 29 29 20 7b 0a 09 09 66 72 d_t) -1)) {...fr
4af0: 65 65 28 61 70 70 66 73 5f 70 61 74 68 5f 69 6e ee(appfs_path_in
4b00: 66 6f 5f 63 61 63 68 65 29 3b 0a 0a 09 09 61 70 fo_cache);....ap
4b10: 70 66 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 pfs_path_info_ca
4b20: 63 68 65 20 3d 20 4e 55 4c 4c 3b 0a 0a 09 09 69 che = NULL;....i
4b30: 66 20 28 6e 65 77 5f 73 69 7a 65 20 21 3d 20 2d f (new_size != -
4b40: 31 29 20 7b 0a 09 09 09 61 70 70 66 73 5f 70 61 1) {....appfs_pa
4b50: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 73 69 th_info_cache_si
4b60: 7a 65 20 3d 20 6e 65 77 5f 73 69 7a 65 3b 0a 09 ze = new_size;..
4b70: 09 7d 0a 09 7d 0a 0a 09 70 74 68 72 65 61 64 5f .}..}...pthread_
4b80: 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75 ret = pthread_mu
4b90: 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 61 70 70 66 tex_unlock(&appf
4ba0: 73 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 s_path_info_cach
4bb0: 65 5f 6d 75 74 65 78 29 3b 0a 09 69 66 20 28 70 e_mutex);..if (p
4bc0: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 thread_ret != 0)
4bd0: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 {...APPFS_DEBUG
4be0: 28 22 55 6e 61 62 6c 65 20 74 6f 20 75 6e 6c 6f ("Unable to unlo
4bf0: 63 6b 20 70 61 74 68 5f 69 6e 66 6f 20 63 61 63 ck path_info cac
4c00: 68 65 20 6d 75 74 65 78 20 21 22 29 3b 0a 0a 09 he mutex !");...
4c10: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 72 65 .return;..}...re
4c20: 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20 47 65 74 20 turn;.}../* Get
4c30: 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 information abou
4c40: 74 20 61 20 70 61 74 68 2c 20 61 6e 64 20 6f 70 t a path, and op
4c50: 74 69 6f 6e 61 6c 6c 79 20 6c 69 73 74 20 63 68 tionally list ch
4c60: 69 6c 64 72 65 6e 20 2a 2f 0a 73 74 61 74 69 63 ildren */.static
4c70: 20 69 6e 74 20 61 70 70 66 73 5f 67 65 74 5f 70 int appfs_get_p
4c80: 61 74 68 5f 69 6e 66 6f 28 63 6f 6e 73 74 20 63 ath_info(const c
4c90: 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 har *path, struc
4ca0: 74 20 61 70 70 66 73 5f 70 61 74 68 69 6e 66 6f t appfs_pathinfo
4cb0: 20 2a 70 61 74 68 69 6e 66 6f 29 20 7b 0a 09 54 *pathinfo) {..T
4cc0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 cl_Interp *inter
4cd0: 70 3b 0a 09 54 63 6c 5f 4f 62 6a 20 2a 61 74 74 p;..Tcl_Obj *att
4ce0: 72 73 5f 64 69 63 74 2c 20 2a 61 74 74 72 5f 76 rs_dict, *attr_v
4cf0: 61 6c 75 65 3b 0a 09 63 6f 6e 73 74 20 63 68 61 alue;..const cha
4d00: 72 20 2a 61 74 74 72 5f 76 61 6c 75 65 5f 73 74 r *attr_value_st
4d10: 72 3b 0a 09 54 63 6c 5f 57 69 64 65 49 6e 74 20 r;..Tcl_WideInt
4d20: 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b attr_value_wide;
4d30: 0a 09 69 6e 74 20 61 74 74 72 5f 76 61 6c 75 65 ..int attr_value
4d40: 5f 69 6e 74 3b 0a 09 73 74 61 74 69 63 20 5f 5f _int;..static __
4d50: 74 68 72 65 61 64 20 54 63 6c 5f 4f 62 6a 20 2a thread Tcl_Obj *
4d60: 61 74 74 72 5f 6b 65 79 5f 74 79 70 65 20 3d 20 attr_key_type =
4d70: 4e 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f NULL, *attr_key_
4d80: 70 65 72 6d 73 20 3d 20 4e 55 4c 4c 2c 20 2a 61 perms = NULL, *a
4d90: 74 74 72 5f 6b 65 79 5f 73 69 7a 65 20 3d 20 4e ttr_key_size = N
4da0: 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 74 ULL, *attr_key_t
4db0: 69 6d 65 20 3d 20 4e 55 4c 4c 2c 20 2a 61 74 74 ime = NULL, *att
4dc0: 72 5f 6b 65 79 5f 73 6f 75 72 63 65 20 3d 20 4e r_key_source = N
4dd0: 55 4c 4c 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 63 ULL, *attr_key_c
4de0: 68 69 6c 64 63 6f 75 6e 74 20 3d 20 4e 55 4c 4c hildcount = NULL
4df0: 2c 20 2a 61 74 74 72 5f 6b 65 79 5f 70 61 63 6b , *attr_key_pack
4e00: 61 67 65 64 20 3d 20 4e 55 4c 4c 3b 0a 09 69 6e aged = NULL;..in
4e10: 74 20 63 61 63 68 65 5f 72 65 74 3b 0a 09 69 6e t cache_ret;..in
4e20: 74 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 t tcl_ret;..int
4e30: 72 65 74 76 61 6c 3b 0a 09 75 69 64 5f 74 20 66 retval;..uid_t f
4e40: 73 75 69 64 3b 0a 0a 09 72 65 74 76 61 6c 20 3d suid;...retval =
4e50: 20 30 3b 0a 0a 09 66 73 75 69 64 20 3d 20 61 70 0;...fsuid = ap
4e60: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 3b pfs_get_fsuid();
4e70: 0a 0a 09 63 61 63 68 65 5f 72 65 74 20 3d 20 61 ...cache_ret = a
4e80: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e ppfs_get_path_in
4e90: 66 6f 5f 63 61 63 68 65 5f 67 65 74 28 70 61 74 fo_cache_get(pat
4ea0: 68 2c 20 66 73 75 69 64 2c 20 70 61 74 68 69 6e h, fsuid, pathin
4eb0: 66 6f 29 3b 0a 09 69 66 20 28 63 61 63 68 65 5f fo);..if (cache_
4ec0: 72 65 74 20 3d 3d 20 30 29 20 7b 0a 09 09 69 66 ret == 0) {...if
4ed0: 20 28 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 (pathinfo->type
4ee0: 20 3d 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 == APPFS_PATHTY
4ef0: 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 PE_DOES_NOT_EXIS
4f00: 54 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 45 T) {....APPFS_DE
4f10: 42 55 47 28 22 52 65 74 75 72 6e 69 6e 67 20 66 BUG("Returning f
4f20: 72 6f 6d 20 63 61 63 68 65 3a 20 64 6f 65 73 20 rom cache: does
4f30: 6e 6f 74 20 65 78 69 73 74 20 5c 22 25 73 5c 22 not exist \"%s\"
4f40: 22 2c 20 70 61 74 68 29 3b 0a 0a 09 09 09 72 65 ", path);.....re
4f50: 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b 0a 09 turn(-ENOENT);..
4f60: 09 7d 0a 0a 09 09 69 66 20 28 70 61 74 68 69 6e .}....if (pathin
4f70: 66 6f 2d 3e 74 79 70 65 20 3d 3d 20 41 50 50 46 fo->type == APPF
4f80: 53 5f 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c S_PATHTYPE_INVAL
4f90: 49 44 29 20 7b 0a 09 09 09 41 50 50 46 53 5f 44 ID) {....APPFS_D
4fa0: 45 42 55 47 28 22 52 65 74 75 72 6e 69 6e 67 20 EBUG("Returning
4fb0: 66 72 6f 6d 20 63 61 63 68 65 3a 20 69 6e 76 61 from cache: inva
4fc0: 6c 69 64 20 6f 62 6a 65 63 74 20 5c 22 25 73 5c lid object \"%s\
4fd0: 22 22 2c 20 70 61 74 68 29 3b 0a 0a 09 09 09 72 "", path);.....r
4fe0: 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 09 7d eturn(-EIO);...}
4ff0: 0a 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09 ....return(0);..
5000: 7d 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 }...interp = app
5010: 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 29 3b 0a fs_TclInterp();.
5020: 09 69 66 20 28 69 6e 74 65 72 70 20 3d 3d 20 4e .if (interp == N
5030: 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 ULL) {...APPFS_D
5040: 45 42 55 47 28 22 65 72 72 6f 72 3a 20 55 6e 61 EBUG("error: Una
5050: 62 6c 65 20 74 6f 20 67 65 74 20 61 6e 20 69 6e ble to get an in
5060: 74 65 72 70 72 65 74 65 72 22 29 3b 0a 0a 09 09 terpreter");....
5070: 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d return(-EIO);..}
5080: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 ...appfs_call_li
5090: 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 76 btcl(Tcl_Preserv
50a0: 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74 63 e(interp);)...tc
50b0: 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 63 l_ret = appfs_Tc
50c0: 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 32 l_Eval(interp, 2
50d0: 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 61 , "::appfs::geta
50e0: 74 74 72 22 2c 20 70 61 74 68 29 3b 0a 09 69 66 ttr", path);..if
50f0: 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c (tcl_ret != TCL
5100: 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 _OK) {...APPFS_D
5110: 45 42 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 67 EBUG("::appfs::g
5120: 65 74 61 74 74 72 28 25 73 29 20 66 61 69 6c 65 etattr(%s) faile
5130: 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61 70 d.", path);...ap
5140: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 pfs_call_libtcl(
5150: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 ....APPFS_DEBUG(
5160: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 "Tcl Error is: %
5170: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e s", Tcl_GetStrin
5180: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 gResult(interp))
5190: 3b 0a 09 09 29 0a 0a 09 09 70 61 74 68 69 6e 66 ;...)....pathinf
51a0: 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f o->type = APPFS_
51b0: 50 41 54 48 54 59 50 45 5f 44 4f 45 53 5f 4e 4f PATHTYPE_DOES_NO
51c0: 54 5f 45 58 49 53 54 3b 0a 0a 09 09 61 70 70 66 T_EXIST;....appf
51d0: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f s_get_path_info_
51e0: 63 61 63 68 65 5f 61 64 64 28 70 61 74 68 2c 20 cache_add(path,
51f0: 66 73 75 69 64 2c 20 70 61 74 68 69 6e 66 6f 29 fsuid, pathinfo)
5200: 3b 0a 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f ;....appfs_call_
5210: 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 libtcl(Tcl_Relea
5220: 73 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 se(interp);)....
5230: 72 65 74 75 72 6e 28 2d 45 4e 4f 45 4e 54 29 3b return(-ENOENT);
5240: 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 6b ..}...if (attr_k
5250: 65 79 5f 74 79 70 65 20 3d 3d 20 4e 55 4c 4c 29 ey_type == NULL)
5260: 20 7b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f {...appfs_call_
5270: 6c 69 62 74 63 6c 28 0a 09 09 09 61 74 74 72 5f libtcl(....attr_
5280: 6b 65 79 5f 74 79 70 65 20 20 20 20 20 20 20 3d key_type =
5290: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 Tcl_NewStringOb
52a0: 6a 28 22 74 79 70 65 22 2c 20 2d 31 29 3b 0a 09 j("type", -1);..
52b0: 09 09 61 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 ..attr_key_perms
52c0: 20 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 = Tcl_NewS
52d0: 74 72 69 6e 67 4f 62 6a 28 22 70 65 72 6d 73 22 tringObj("perms"
52e0: 2c 20 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b , -1);....attr_k
52f0: 65 79 5f 73 69 7a 65 20 20 20 20 20 20 20 3d 20 ey_size =
5300: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a Tcl_NewStringObj
5310: 28 22 73 69 7a 65 22 2c 20 2d 31 29 3b 0a 09 09 ("size", -1);...
5320: 09 61 74 74 72 5f 6b 65 79 5f 74 69 6d 65 20 20 .attr_key_time
5330: 20 20 20 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 = Tcl_NewSt
5340: 72 69 6e 67 4f 62 6a 28 22 74 69 6d 65 22 2c 20 ringObj("time",
5350: 2d 31 29 3b 0a 09 09 09 61 74 74 72 5f 6b 65 79 -1);....attr_key
5360: 5f 73 6f 75 72 63 65 20 20 20 20 20 3d 20 54 63 _source = Tc
5370: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 l_NewStringObj("
5380: 73 6f 75 72 63 65 22 2c 20 2d 31 29 3b 0a 09 09 source", -1);...
5390: 09 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 .attr_key_childc
53a0: 6f 75 6e 74 20 3d 20 54 63 6c 5f 4e 65 77 53 74 ount = Tcl_NewSt
53b0: 72 69 6e 67 4f 62 6a 28 22 63 68 69 6c 64 63 6f ringObj("childco
53c0: 75 6e 74 22 2c 20 2d 31 29 3b 0a 09 09 09 61 74 unt", -1);....at
53d0: 74 72 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 20 tr_key_packaged
53e0: 20 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e = Tcl_NewStrin
53f0: 67 4f 62 6a 28 22 70 61 63 6b 61 67 65 64 22 2c gObj("packaged",
5400: 20 2d 31 29 3b 0a 0a 09 09 09 54 63 6c 5f 49 6e -1);.....Tcl_In
5410: 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 5f crRefCount(attr_
5420: 6b 65 79 5f 74 79 70 65 29 3b 0a 09 09 09 54 63 key_type);....Tc
5430: 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 l_IncrRefCount(a
5440: 74 74 72 5f 6b 65 79 5f 70 65 72 6d 73 29 3b 0a ttr_key_perms);.
5450: 09 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f ...Tcl_IncrRefCo
5460: 75 6e 74 28 61 74 74 72 5f 6b 65 79 5f 73 69 7a unt(attr_key_siz
5470: 65 29 3b 0a 09 09 09 54 63 6c 5f 49 6e 63 72 52 e);....Tcl_IncrR
5480: 65 66 43 6f 75 6e 74 28 61 74 74 72 5f 6b 65 79 efCount(attr_key
5490: 5f 74 69 6d 65 29 3b 0a 09 09 09 54 63 6c 5f 49 _time);....Tcl_I
54a0: 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 ncrRefCount(attr
54b0: 5f 6b 65 79 5f 73 6f 75 72 63 65 29 3b 0a 09 09 _key_source);...
54c0: 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e .Tcl_IncrRefCoun
54d0: 74 28 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 t(attr_key_child
54e0: 63 6f 75 6e 74 29 3b 0a 09 09 09 54 63 6c 5f 49 count);....Tcl_I
54f0: 6e 63 72 52 65 66 43 6f 75 6e 74 28 61 74 74 72 ncrRefCount(attr
5500: 5f 6b 65 79 5f 70 61 63 6b 61 67 65 64 29 3b 0a _key_packaged);.
5510: 09 09 29 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 ..)..}...appfs_c
5520: 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 61 74 all_libtcl(...at
5530: 74 72 73 5f 64 69 63 74 20 3d 20 54 63 6c 5f 47 trs_dict = Tcl_G
5540: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 etObjResult(inte
5550: 72 70 29 3b 0a 09 09 74 63 6c 5f 72 65 74 20 3d rp);...tcl_ret =
5560: 20 54 63 6c 5f 44 69 63 74 4f 62 6a 47 65 74 28 Tcl_DictObjGet(
5570: 69 6e 74 65 72 70 2c 20 61 74 74 72 73 5f 64 69 interp, attrs_di
5580: 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f 74 79 70 ct, attr_key_typ
5590: 65 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 29 3b e, &attr_value);
55a0: 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 ..)..if (tcl_ret
55b0: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 != TCL_OK) {...
55c0: 41 50 50 46 53 5f 44 45 42 55 47 28 22 5b 64 69 APPFS_DEBUG("[di
55d0: 63 74 20 67 65 74 20 5c 22 74 79 70 65 5c 22 5d ct get \"type\"]
55e0: 20 66 61 69 6c 65 64 22 29 3b 0a 09 09 61 70 70 failed");...app
55f0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a fs_call_libtcl(.
5600: 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 ...APPFS_DEBUG("
5610: 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 73 Tcl Error is: %s
5620: 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 ", Tcl_GetString
5630: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 3b Result(interp));
5640: 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f 63 61 ...)....appfs_ca
5650: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 65 ll_libtcl(Tcl_Re
5660: 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 0a lease(interp);).
5670: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b ...return(-EIO);
5680: 0a 09 7d 0a 0a 09 69 66 20 28 61 74 74 72 5f 76 ..}...if (attr_v
5690: 61 6c 75 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a alue == NULL) {.
56a0: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 ..APPFS_DEBUG("e
56b0: 72 72 6f 72 3a 20 55 6e 61 62 6c 65 20 74 6f 20 rror: Unable to
56c0: 67 65 74 20 74 79 70 65 20 66 6f 72 20 5c 22 25 get type for \"%
56d0: 73 5c 22 20 66 72 6f 6d 20 54 63 6c 22 2c 20 70 s\" from Tcl", p
56e0: 61 74 68 29 3b 0a 0a 09 09 61 70 70 66 73 5f 63 ath);....appfs_c
56f0: 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 52 all_libtcl(Tcl_R
5700: 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b 29 elease(interp);)
5710: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 ....return(-EIO)
5720: 3b 0a 09 7d 0a 0a 09 70 61 74 68 69 6e 66 6f 2d ;..}...pathinfo-
5730: 3e 70 61 63 6b 61 67 65 64 20 3d 20 30 3b 0a 09 >packaged = 0;..
5740: 70 61 74 68 69 6e 66 6f 2d 3e 69 6e 6f 64 65 20 pathinfo->inode
5750: 3d 20 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 = appfs_get_path
5760: 5f 69 6e 6f 64 65 28 70 61 74 68 29 3b 0a 0a 09 _inode(path);...
5770: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 appfs_call_libtc
5780: 6c 28 0a 09 09 61 74 74 72 5f 76 61 6c 75 65 5f l(...attr_value_
5790: 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 str = Tcl_GetStr
57a0: 69 6e 67 28 61 74 74 72 5f 76 61 6c 75 65 29 3b ing(attr_value);
57b0: 0a 0a 09 09 73 77 69 74 63 68 20 28 61 74 74 72 ....switch (attr
57c0: 5f 76 61 6c 75 65 5f 73 74 72 5b 30 5d 29 20 7b _value_str[0]) {
57d0: 0a 09 09 09 63 61 73 65 20 27 64 27 3a 20 2f 2a ....case 'd': /*
57e0: 20 64 69 72 65 63 74 6f 72 79 20 2a 2f 0a 09 09 directory */...
57f0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 ..pathinfo->type
5800: 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 = APPFS_PATHTYP
5810: 45 5f 44 49 52 45 43 54 4f 52 59 3b 0a 09 09 09 E_DIRECTORY;....
5820: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 .pathinfo->typei
5830: 6e 66 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 nfo.dir.childcou
5840: 6e 74 20 3d 20 30 3b 0a 0a 09 09 09 09 54 63 6c nt = 0;......Tcl
5850: 5f 44 69 63 74 4f 62 6a 47 65 74 28 69 6e 74 65 _DictObjGet(inte
5860: 72 70 2c 20 61 74 74 72 73 5f 64 69 63 74 2c 20 rp, attrs_dict,
5870: 61 74 74 72 5f 6b 65 79 5f 63 68 69 6c 64 63 6f attr_key_childco
5880: 75 6e 74 2c 20 26 61 74 74 72 5f 76 61 6c 75 65 unt, &attr_value
5890: 29 3b 0a 09 09 09 09 69 66 20 28 61 74 74 72 5f );.....if (attr_
58a0: 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 20 7b value != NULL) {
58b0: 0a 09 09 09 09 09 74 63 6c 5f 72 65 74 20 3d 20 ......tcl_ret =
58c0: 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72 Tcl_GetWideIntFr
58d0: 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 72 omObj(NULL, attr
58e0: 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 61 _value, &attr_va
58f0: 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 09 09 lue_wide);......
5900: 69 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 if (tcl_ret == T
5910: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 09 09 70 CL_OK) {.......p
5920: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 athinfo->typeinf
5930: 6f 2e 64 69 72 2e 63 68 69 6c 64 63 6f 75 6e 74 o.dir.childcount
5940: 20 3d 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 = attr_value_wi
5950: 64 65 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d de;......}.....}
5960: 0a 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 ......break;....
5970: 63 61 73 65 20 27 66 27 3a 20 2f 2a 20 66 69 6c case 'f': /* fil
5980: 65 20 2a 2f 0a 09 09 09 09 70 61 74 68 69 6e 66 e */.....pathinf
5990: 6f 2d 3e 74 79 70 65 20 3d 20 41 50 50 46 53 5f o->type = APPFS_
59a0: 50 41 54 48 54 59 50 45 5f 46 49 4c 45 3b 0a 09 PATHTYPE_FILE;..
59b0: 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 ...pathinfo->typ
59c0: 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 einfo.file.size
59d0: 3d 20 30 3b 0a 09 09 09 09 70 61 74 68 69 6e 66 = 0;.....pathinf
59e0: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 o->typeinfo.file
59f0: 2e 65 78 65 63 75 74 61 62 6c 65 20 3d 20 30 3b .executable = 0;
5a00: 0a 0a 09 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 ......Tcl_DictOb
5a10: 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 jGet(interp, att
5a20: 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 rs_dict, attr_ke
5a30: 79 5f 73 69 7a 65 2c 20 26 61 74 74 72 5f 76 61 y_size, &attr_va
5a40: 6c 75 65 29 3b 0a 09 09 09 09 69 66 20 28 61 74 lue);.....if (at
5a50: 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c tr_value != NULL
5a60: 29 20 7b 0a 09 09 09 09 09 74 63 6c 5f 72 65 74 ) {......tcl_ret
5a70: 20 3d 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e = Tcl_GetWideIn
5a80: 74 46 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 tFromObj(NULL, a
5a90: 74 74 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 ttr_value, &attr
5aa0: 5f 76 61 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 _value_wide);...
5ab0: 09 09 09 69 66 20 28 74 63 6c 5f 72 65 74 20 3d ...if (tcl_ret =
5ac0: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 = TCL_OK) {.....
5ad0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 ..pathinfo->type
5ae0: 69 6e 66 6f 2e 66 69 6c 65 2e 73 69 7a 65 20 3d info.file.size =
5af0: 20 61 74 74 72 5f 76 61 6c 75 65 5f 77 69 64 65 attr_value_wide
5b00: 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 0a ;......}.....}..
5b10: 09 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 6a 47 ....Tcl_DictObjG
5b20: 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 72 73 et(interp, attrs
5b30: 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 79 5f _dict, attr_key_
5b40: 70 65 72 6d 73 2c 20 26 61 74 74 72 5f 76 61 6c perms, &attr_val
5b50: 75 65 29 3b 0a 09 09 09 09 69 66 20 28 61 74 74 ue);.....if (att
5b60: 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c 29 r_value != NULL)
5b70: 20 7b 0a 09 09 09 09 09 61 74 74 72 5f 76 61 6c {......attr_val
5b80: 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f 47 65 74 ue_str = Tcl_Get
5b90: 53 74 72 69 6e 67 28 61 74 74 72 5f 76 61 6c 75 String(attr_valu
5ba0: 65 29 3b 0a 09 09 09 09 09 69 66 20 28 61 74 74 e);......if (att
5bb0: 72 5f 76 61 6c 75 65 5f 73 74 72 5b 30 5d 20 3d r_value_str[0] =
5bc0: 3d 20 27 78 27 29 20 7b 0a 09 09 09 09 09 09 70 = 'x') {.......p
5bd0: 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 athinfo->typeinf
5be0: 6f 2e 66 69 6c 65 2e 65 78 65 63 75 74 61 62 6c o.file.executabl
5bf0: 65 20 3d 20 31 3b 0a 09 09 09 09 09 7d 0a 09 09 e = 1;......}...
5c00: 09 09 7d 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 ..}.....break;..
5c10: 09 09 63 61 73 65 20 27 73 27 3a 20 2f 2a 20 73 ..case 's': /* s
5c20: 79 6d 6c 69 6e 6b 20 2a 2f 0a 09 09 09 09 70 61 ymlink */.....pa
5c30: 74 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 thinfo->type = A
5c40: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 59 PPFS_PATHTYPE_SY
5c50: 4d 4c 49 4e 4b 3b 0a 09 09 09 09 70 61 74 68 69 MLINK;.....pathi
5c60: 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 nfo->typeinfo.sy
5c70: 6d 6c 69 6e 6b 2e 73 69 7a 65 20 3d 20 30 3b 0a mlink.size = 0;.
5c80: 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 ....pathinfo->ty
5c90: 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 peinfo.symlink.s
5ca0: 6f 75 72 63 65 5b 30 5d 20 3d 20 27 5c 30 27 3b ource[0] = '\0';
5cb0: 0a 0a 09 09 09 09 54 63 6c 5f 44 69 63 74 4f 62 ......Tcl_DictOb
5cc0: 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 jGet(interp, att
5cd0: 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 rs_dict, attr_ke
5ce0: 79 5f 73 6f 75 72 63 65 2c 20 26 61 74 74 72 5f y_source, &attr_
5cf0: 76 61 6c 75 65 29 3b 0a 09 09 09 09 69 66 20 28 value);.....if (
5d00: 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 attr_value != NU
5d10: 4c 4c 29 20 7b 0a 09 09 09 09 09 61 74 74 72 5f LL) {......attr_
5d20: 76 61 6c 75 65 5f 73 74 72 20 3d 20 54 63 6c 5f value_str = Tcl_
5d30: 47 65 74 53 74 72 69 6e 67 46 72 6f 6d 4f 62 6a GetStringFromObj
5d40: 28 61 74 74 72 5f 76 61 6c 75 65 2c 20 26 61 74 (attr_value, &at
5d50: 74 72 5f 76 61 6c 75 65 5f 69 6e 74 29 3b 20 0a tr_value_int); .
5d60: 0a 09 09 09 09 09 69 66 20 28 28 61 74 74 72 5f ......if ((attr_
5d70: 76 61 6c 75 65 5f 69 6e 74 20 2b 20 31 29 20 3c value_int + 1) <
5d80: 3d 20 73 69 7a 65 6f 66 28 70 61 74 68 69 6e 66 = sizeof(pathinf
5d90: 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c o->typeinfo.syml
5da0: 69 6e 6b 2e 73 6f 75 72 63 65 29 29 20 7b 0a 09 ink.source)) {..
5db0: 09 09 09 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 .....pathinfo->t
5dc0: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e ypeinfo.symlink.
5dd0: 73 69 7a 65 20 3d 20 61 74 74 72 5f 76 61 6c 75 size = attr_valu
5de0: 65 5f 69 6e 74 3b 0a 09 09 09 09 09 09 70 61 74 e_int;.......pat
5df0: 68 69 6e 66 6f 2d 3e 74 79 70 65 69 6e 66 6f 2e hinfo->typeinfo.
5e00: 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 5b 61 symlink.source[a
5e10: 74 74 72 5f 76 61 6c 75 65 5f 69 6e 74 5d 20 3d ttr_value_int] =
5e20: 20 27 5c 30 27 3b 0a 0a 09 09 09 09 09 09 6d 65 '\0';........me
5e30: 6d 63 70 79 28 70 61 74 68 69 6e 66 6f 2d 3e 74 mcpy(pathinfo->t
5e40: 79 70 65 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e ypeinfo.symlink.
5e50: 73 6f 75 72 63 65 2c 20 61 74 74 72 5f 76 61 6c source, attr_val
5e60: 75 65 5f 73 74 72 2c 20 61 74 74 72 5f 76 61 6c ue_str, attr_val
5e70: 75 65 5f 69 6e 74 29 3b 0a 09 09 09 09 09 7d 0a ue_int);......}.
5e80: 09 09 09 09 7d 0a 09 09 09 09 62 72 65 61 6b 3b ....}.....break;
5e90: 0a 09 09 09 63 61 73 65 20 27 46 27 3a 20 2f 2a ....case 'F': /*
5ea0: 20 70 69 70 65 2f 66 69 66 6f 20 2a 2f 0a 09 09 pipe/fifo */...
5eb0: 09 09 70 61 74 68 69 6e 66 6f 2d 3e 74 79 70 65 ..pathinfo->type
5ec0: 20 3d 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 = APPFS_PATHTYP
5ed0: 45 5f 46 49 46 4f 3b 0a 09 09 09 09 62 72 65 61 E_FIFO;.....brea
5ee0: 6b 3b 0a 09 09 09 63 61 73 65 20 27 53 27 3a 20 k;....case 'S':
5ef0: 2f 2a 20 55 4e 49 58 20 64 6f 6d 61 69 6e 20 73 /* UNIX domain s
5f00: 6f 63 6b 65 74 20 2a 2f 0a 09 09 09 09 70 61 74 ocket */.....pat
5f10: 68 69 6e 66 6f 2d 3e 74 79 70 65 20 3d 20 41 50 hinfo->type = AP
5f20: 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 4f 43 PFS_PATHTYPE_SOC
5f30: 4b 45 54 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a KET;.....break;.
5f40: 09 09 09 64 65 66 61 75 6c 74 3a 0a 09 09 09 09 ...default:.....
5f50: 72 65 74 76 61 6c 20 3d 20 2d 45 49 4f 3b 0a 09 retval = -EIO;..
5f60: 09 7d 0a 0a 09 09 54 63 6c 5f 44 69 63 74 4f 62 .}....Tcl_DictOb
5f70: 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 74 74 jGet(interp, att
5f80: 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f 6b 65 rs_dict, attr_ke
5f90: 79 5f 70 61 63 6b 61 67 65 64 2c 20 26 61 74 74 y_packaged, &att
5fa0: 72 5f 76 61 6c 75 65 29 3b 0a 09 09 69 66 20 28 r_value);...if (
5fb0: 61 74 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 attr_value != NU
5fc0: 4c 4c 29 20 7b 0a 09 09 09 70 61 74 68 69 6e 66 LL) {....pathinf
5fd0: 6f 2d 3e 70 61 63 6b 61 67 65 64 20 3d 20 31 3b o->packaged = 1;
5fe0: 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 44 69 63 74 ...}....Tcl_Dict
5ff0: 4f 62 6a 47 65 74 28 69 6e 74 65 72 70 2c 20 61 ObjGet(interp, a
6000: 74 74 72 73 5f 64 69 63 74 2c 20 61 74 74 72 5f ttrs_dict, attr_
6010: 6b 65 79 5f 74 69 6d 65 2c 20 26 61 74 74 72 5f key_time, &attr_
6020: 76 61 6c 75 65 29 3b 0a 09 09 69 66 20 28 61 74 value);...if (at
6030: 74 72 5f 76 61 6c 75 65 20 21 3d 20 4e 55 4c 4c tr_value != NULL
6040: 29 20 7b 0a 09 09 09 74 63 6c 5f 72 65 74 20 3d ) {....tcl_ret =
6050: 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 Tcl_GetWideIntF
6060: 72 6f 6d 4f 62 6a 28 4e 55 4c 4c 2c 20 61 74 74 romObj(NULL, att
6070: 72 5f 76 61 6c 75 65 2c 20 26 61 74 74 72 5f 76 r_value, &attr_v
6080: 61 6c 75 65 5f 77 69 64 65 29 3b 0a 09 09 09 69 alue_wide);....i
6090: 66 20 28 74 63 6c 5f 72 65 74 20 3d 3d 20 54 43 f (tcl_ret == TC
60a0: 4c 5f 4f 4b 29 20 7b 0a 09 09 09 09 70 61 74 68 L_OK) {.....path
60b0: 69 6e 66 6f 2d 3e 74 69 6d 65 20 3d 20 61 74 74 info->time = att
60c0: 72 5f 76 61 6c 75 65 5f 77 69 64 65 3b 0a 09 09 r_value_wide;...
60d0: 09 7d 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 .}...} else {...
60e0: 09 70 61 74 68 69 6e 66 6f 2d 3e 74 69 6d 65 20 .pathinfo->time
60f0: 3d 20 61 70 70 66 73 5f 62 6f 6f 74 74 69 6d 65 = appfs_boottime
6100: 3b 0a 09 09 7d 0a 0a 09 09 54 63 6c 5f 52 65 6c ;...}....Tcl_Rel
6110: 65 61 73 65 28 69 6e 74 65 72 70 29 3b 0a 09 29 ease(interp);..)
6120: 0a 0a 09 69 66 20 28 72 65 74 76 61 6c 20 3d 3d ...if (retval ==
6130: 20 30 29 20 7b 0a 09 09 61 70 70 66 73 5f 67 65 0) {...appfs_ge
6140: 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 t_path_info_cach
6150: 65 5f 61 64 64 28 70 61 74 68 2c 20 66 73 75 69 e_add(path, fsui
6160: 64 2c 20 70 61 74 68 69 6e 66 6f 29 3b 0a 09 7d d, pathinfo);..}
6170: 20 65 6c 73 65 20 7b 0a 09 09 41 50 50 46 53 5f else {...APPFS_
6180: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 49 6e DEBUG("error: In
6190: 76 61 6c 69 64 20 74 79 70 65 20 66 6f 72 20 5c valid type for \
61a0: 22 25 73 5c 22 20 66 72 6f 6d 20 54 63 6c 22 2c "%s\" from Tcl",
61b0: 20 70 61 74 68 29 3b 0a 09 7d 0a 0a 09 72 65 74 path);..}...ret
61c0: 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a urn(retval);.}..
61d0: 73 74 61 74 69 63 20 63 68 61 72 20 2a 61 70 70 static char *app
61e0: 66 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 fs_prepare_to_cr
61f0: 65 61 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 eate(const char
6200: 2a 70 61 74 68 29 20 7b 0a 09 54 63 6c 5f 49 6e *path) {..Tcl_In
6210: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 terp *interp;..c
6220: 6f 6e 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f onst char *real_
6230: 70 61 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 path;..int tcl_r
6240: 65 74 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f et;...appfs_get_
6250: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f path_info_cache_
6260: 66 6c 75 73 68 28 61 70 70 66 73 5f 67 65 74 5f flush(appfs_get_
6270: 66 73 75 69 64 28 29 2c 20 2d 31 29 3b 0a 0a 09 fsuid(), -1);...
6280: 69 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 interp = appfs_T
6290: 63 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 clInterp();..if
62a0: 28 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 (interp == NULL)
62b0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c {...return(NULL
62c0: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 );..}...appfs_ca
62d0: 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 ll_libtcl(Tcl_Pr
62e0: 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 eserve(interp);)
62f0: 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 ...appfs_call_li
6300: 62 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20 btcl(...tcl_ret
6310: 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c = appfs_Tcl_Eval
6320: 28 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 (interp, 2, "::a
6330: 70 70 66 73 3a 3a 70 72 65 70 61 72 65 5f 74 6f ppfs::prepare_to
6340: 5f 63 72 65 61 74 65 22 2c 20 70 61 74 68 29 3b _create", path);
6350: 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 ..)..if (tcl_ret
6360: 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 != TCL_OK) {...
6370: 41 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 APPFS_DEBUG("::a
6380: 70 70 66 73 3a 3a 70 72 65 70 61 72 65 5f 74 6f ppfs::prepare_to
6390: 5f 63 72 65 61 74 65 28 25 73 29 20 66 61 69 6c _create(%s) fail
63a0: 65 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61 ed.", path);...a
63b0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c ppfs_call_libtcl
63c0: 28 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 (....APPFS_DEBUG
63d0: 28 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 ("Tcl Error is:
63e0: 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 %s", Tcl_GetStri
63f0: 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 ngResult(interp)
6400: 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 66 73 5f );...)....appfs_
6410: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f call_libtcl(Tcl_
6420: 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 3b Release(interp);
6430: 29 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c )....return(NULL
6440: 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 );..}...appfs_ca
6450: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 72 65 61 ll_libtcl(...rea
6460: 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f 47 65 74 l_path = Tcl_Get
6470: 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 StringResult(int
6480: 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 73 erp);..)...appfs
6490: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c _call_libtcl(Tcl
64a0: 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 70 29 _Release(interp)
64b0: 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 ;)...if (real_pa
64c0: 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 th == NULL) {...
64d0: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d return(NULL);..}
64e0: 0a 0a 09 72 65 74 75 72 6e 28 73 74 72 64 75 70 ...return(strdup
64f0: 28 72 65 61 6c 5f 70 61 74 68 29 29 3b 0a 7d 0a (real_path));.}.
6500: 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 61 70 .static char *ap
6510: 70 66 73 5f 6c 6f 63 61 6c 70 61 74 68 28 63 6f pfs_localpath(co
6520: 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 29 20 nst char *path)
6530: 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 {..Tcl_Interp *i
6540: 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 63 68 nterp;..const ch
6550: 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 ar *real_path;..
6560: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 int tcl_ret;...i
6570: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 nterp = appfs_Tc
6580: 6c 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 lInterp();..if (
6590: 69 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 interp == NULL)
65a0: 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 {...return(NULL)
65b0: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c ;..}...appfs_cal
65c0: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 l_libtcl(Tcl_Pre
65d0: 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a serve(interp);).
65e0: 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 ..appfs_call_lib
65f0: 74 63 6c 28 0a 09 09 74 63 6c 5f 72 65 74 20 3d tcl(...tcl_ret =
6600: 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 appfs_Tcl_Eval(
6610: 69 6e 74 65 72 70 2c 20 32 2c 20 22 3a 3a 61 70 interp, 2, "::ap
6620: 70 66 73 3a 3a 6c 6f 63 61 6c 70 61 74 68 22 2c pfs::localpath",
6630: 20 70 61 74 68 29 3b 0a 09 29 0a 09 69 66 20 28 path);..)..if (
6640: 74 63 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f tcl_ret != TCL_O
6650: 4b 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 K) {...APPFS_DEB
6660: 55 47 28 22 3a 3a 61 70 70 66 73 3a 3a 6c 6f 63 UG("::appfs::loc
6670: 61 6c 70 61 74 68 28 25 73 29 20 66 61 69 6c 65 alpath(%s) faile
6680: 64 2e 22 2c 20 70 61 74 68 29 3b 0a 09 09 61 70 d.", path);...ap
6690: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 pfs_call_libtcl(
66a0: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 ....APPFS_DEBUG(
66b0: 22 54 63 6c 20 45 72 72 6f 72 20 69 73 3a 20 25 "Tcl Error is: %
66c0: 73 22 2c 20 54 63 6c 5f 47 65 74 53 74 72 69 6e s", Tcl_GetStrin
66d0: 67 52 65 73 75 6c 74 28 69 6e 74 65 72 70 29 29 gResult(interp))
66e0: 3b 0a 09 09 29 0a 0a 09 09 72 65 74 75 72 6e 28 ;...)....return(
66f0: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 NULL);..}...appf
6700: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 s_call_libtcl(..
6710: 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c .real_path = Tcl
6720: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 _GetStringResult
6730: 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61 (interp);..)...a
6740: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c ppfs_call_libtcl
6750: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 (Tcl_Release(int
6760: 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72 65 61 erp);)...if (rea
6770: 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 l_path == NULL)
6780: 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 {...return(NULL)
6790: 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 73 74 ;..}...return(st
67a0: 72 64 75 70 28 72 65 61 6c 5f 70 61 74 68 29 29 rdup(real_path))
67b0: 3b 0a 7d 0a 0a 23 69 66 20 28 64 65 66 69 6e 65 ;.}..#if (define
67c0: 64 28 44 45 42 55 47 29 20 26 26 20 64 65 66 69 d(DEBUG) && defi
67d0: 6e 65 64 28 41 50 50 46 53 5f 45 58 49 54 5f 50 ned(APPFS_EXIT_P
67e0: 41 54 48 29 29 20 7c 7c 20 64 65 66 69 6e 65 64 ATH)) || defined
67f0: 28 41 50 50 46 53 5f 45 58 49 54 5f 50 41 54 48 (APPFS_EXIT_PATH
6800: 5f 45 4e 41 42 4c 45 5f 4d 41 4a 4f 52 5f 53 45 _ENABLE_MAJOR_SE
6810: 43 55 52 49 54 59 5f 48 4f 4c 45 29 0a 73 74 61 CURITY_HOLE).sta
6820: 74 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 65 tic void appfs_e
6830: 78 69 74 28 76 6f 69 64 29 20 7b 0a 09 69 6e 74 xit(void) {..int
6840: 20 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 5f 72 global_interp_r
6850: 65 73 65 74 5f 6b 65 79 3b 0a 0a 09 67 6c 6f 62 eset_key;...glob
6860: 61 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f al_interp_reset_
6870: 6b 65 79 20 3d 20 5f 5f 73 79 6e 63 5f 66 65 74 key = __sync_fet
6880: 63 68 5f 61 6e 64 5f 61 64 64 28 26 69 6e 74 65 ch_and_add(&inte
6890: 72 70 5f 72 65 73 65 74 5f 6b 65 79 2c 20 30 29 rp_reset_key, 0)
68a0: 3b 0a 09 5f 5f 73 79 6e 63 5f 66 65 74 63 68 5f ;..__sync_fetch_
68b0: 61 6e 64 5f 73 75 62 28 26 69 6e 74 65 72 70 5f and_sub(&interp_
68c0: 72 65 73 65 74 5f 6b 65 79 2c 20 67 6c 6f 62 61 reset_key, globa
68d0: 6c 5f 69 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b l_interp_reset_k
68e0: 65 79 29 3b 0a 0a 09 77 68 69 6c 65 20 28 5f 5f ey);...while (__
68f0: 73 79 6e 63 5f 73 75 62 5f 61 6e 64 5f 66 65 74 sync_sub_and_fet
6900: 63 68 28 26 69 6e 74 65 72 70 5f 72 65 73 65 74 ch(&interp_reset
6910: 5f 6b 65 79 2c 20 31 29 20 3e 3d 20 30 29 20 7b _key, 1) >= 0) {
6920: 0a 09 09 2f 2a 20 42 75 73 79 20 4c 6f 6f 70 20 .../* Busy Loop
6930: 2a 2f 0a 09 7d 0a 0a 09 67 6c 6f 62 61 6c 5f 69 */..}...global_i
6940: 6e 74 65 72 70 5f 72 65 73 65 74 5f 6b 65 79 20 nterp_reset_key
6950: 3d 20 5f 5f 73 79 6e 63 5f 66 65 74 63 68 5f 61 = __sync_fetch_a
6960: 6e 64 5f 61 64 64 28 26 69 6e 74 65 72 70 5f 72 nd_add(&interp_r
6970: 65 73 65 74 5f 6b 65 79 2c 20 30 29 3b 0a 09 69 eset_key, 0);..i
6980: 66 20 28 67 6c 6f 62 61 6c 5f 69 6e 74 65 72 70 f (global_interp
6990: 5f 72 65 73 65 74 5f 6b 65 79 20 21 3d 20 2d 31 _reset_key != -1
69a0: 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 ) {...APPFS_DEBU
69b0: 47 28 22 45 72 72 6f 72 20 73 65 6e 64 69 6e 67 G("Error sending
69c0: 20 6b 69 6c 6c 20 73 69 67 6e 61 6c 20 74 6f 20 kill signal to
69d0: 61 6c 6c 20 74 68 72 65 61 64 73 2c 20 61 62 6f all threads, abo
69e0: 72 74 69 6e 67 20 61 6e 79 77 61 79 2e 22 29 3b rting anyway.");
69f0: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f ..}...appfs_get_
6a00: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f path_info_cache_
6a10: 66 6c 75 73 68 28 2d 31 2c 20 2d 31 29 3b 0a 0a flush(-1, -1);..
6a20: 09 66 75 73 65 5f 65 78 69 74 28 66 75 73 65 5f .fuse_exit(fuse_
6a30: 67 65 74 5f 63 6f 6e 74 65 78 74 28 29 2d 3e 66 get_context()->f
6a40: 75 73 65 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a use);...return;.
6a50: 7d 0a 23 65 6e 64 69 66 0a 0a 73 74 61 74 69 63 }.#endif..static
6a60: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f int appfs_fuse_
6a70: 72 65 61 64 6c 69 6e 6b 28 63 6f 6e 73 74 20 63 readlink(const c
6a80: 68 61 72 20 2a 70 61 74 68 2c 20 63 68 61 72 20 har *path, char
6a90: 2a 62 75 66 2c 20 73 69 7a 65 5f 74 20 73 69 7a *buf, size_t siz
6aa0: 65 29 20 7b 0a 09 73 74 72 75 63 74 20 61 70 70 e) {..struct app
6ab0: 66 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74 68 fs_pathinfo path
6ac0: 69 6e 66 6f 3b 0a 09 69 6e 74 20 72 65 74 76 61 info;..int retva
6ad0: 6c 20 3d 20 30 3b 0a 0a 09 41 50 50 46 53 5f 44 l = 0;...APPFS_D
6ae0: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 EBUG("Enter (pat
6af0: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 h = %s, ...)", p
6b00: 61 74 68 29 3b 0a 0a 09 70 61 74 68 69 6e 66 6f ath);...pathinfo
6b10: 2e 74 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 .type = APPFS_PA
6b20: 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b 0a THTYPE_INVALID;.
6b30: 0a 09 72 65 74 76 61 6c 20 3d 20 61 70 70 66 73 ..retval = appfs
6b40: 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 _get_path_info(p
6b50: 61 74 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b ath, &pathinfo);
6b60: 0a 09 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20 ..if (retval !=
6b70: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 72 65 0) {...return(re
6b80: 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 tval);..}...if (
6b90: 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 20 21 3d pathinfo.type !=
6ba0: 20 41 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f APPFS_PATHTYPE_
6bb0: 53 59 4d 4c 49 4e 4b 29 20 7b 0a 09 09 72 65 74 SYMLINK) {...ret
6bc0: 75 72 6e 28 2d 45 49 4e 56 41 4c 29 3b 0a 09 7d urn(-EINVAL);..}
6bd0: 0a 0a 09 69 66 20 28 28 73 74 72 6c 65 6e 28 70 ...if ((strlen(p
6be0: 61 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f athinfo.typeinfo
6bf0: 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 72 63 65 29 .symlink.source)
6c00: 20 2b 20 31 29 20 3e 20 73 69 7a 65 29 20 7b 0a + 1) > size) {.
6c10: 09 09 72 65 74 75 72 6e 28 2d 45 4e 41 4d 45 54 ..return(-ENAMET
6c20: 4f 4f 4c 4f 4e 47 29 3b 0a 09 7d 0a 0a 09 6d 65 OOLONG);..}...me
6c30: 6d 63 70 79 28 62 75 66 2c 20 70 61 74 68 69 6e mcpy(buf, pathin
6c40: 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 73 79 6d 6c fo.typeinfo.syml
6c50: 69 6e 6b 2e 73 6f 75 72 63 65 2c 20 73 74 72 6c ink.source, strl
6c60: 65 6e 28 70 61 74 68 69 6e 66 6f 2e 74 79 70 65 en(pathinfo.type
6c70: 69 6e 66 6f 2e 73 79 6d 6c 69 6e 6b 2e 73 6f 75 info.symlink.sou
6c80: 72 63 65 29 20 2b 20 31 29 3b 0a 0a 09 72 65 74 rce) + 1);...ret
6c90: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 urn(0);.}..stati
6ca0: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 c int appfs_fuse
6cb0: 5f 67 65 74 61 74 74 72 28 63 6f 6e 73 74 20 63 _getattr(const c
6cc0: 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 har *path, struc
6cd0: 74 20 73 74 61 74 20 2a 73 74 62 75 66 29 20 7b t stat *stbuf) {
6ce0: 0a 09 73 74 72 75 63 74 20 61 70 70 66 73 5f 70 ..struct appfs_p
6cf0: 61 74 68 69 6e 66 6f 20 70 61 74 68 69 6e 66 6f athinfo pathinfo
6d00: 3b 0a 09 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a ;..int retval;..
6d10: 09 72 65 74 76 61 6c 20 3d 20 30 3b 0a 0a 09 41 .retval = 0;...A
6d20: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 PPFS_DEBUG("Ente
6d30: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e r (path = %s, ..
6d40: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 23 69 66 .)", path);..#if
6d50: 20 28 64 65 66 69 6e 65 64 28 44 45 42 55 47 29 (defined(DEBUG)
6d60: 20 26 26 20 64 65 66 69 6e 65 64 28 41 50 50 46 && defined(APPF
6d70: 53 5f 45 58 49 54 5f 50 41 54 48 29 29 20 7c 7c S_EXIT_PATH)) ||
6d80: 20 64 65 66 69 6e 65 64 28 41 50 50 46 53 5f 45 defined(APPFS_E
6d90: 58 49 54 5f 50 41 54 48 5f 45 4e 41 42 4c 45 5f XIT_PATH_ENABLE_
6da0: 4d 41 4a 4f 52 5f 53 45 43 55 52 49 54 59 5f 48 MAJOR_SECURITY_H
6db0: 4f 4c 45 29 0a 09 2f 2a 0a 09 20 2a 20 54 68 69 OLE)../*.. * Thi
6dc0: 73 20 69 73 20 61 20 6d 61 6a 6f 72 20 73 65 63 s is a major sec
6dd0: 75 72 69 74 79 20 69 73 73 75 65 20 73 6f 20 77 urity issue so w
6de0: 65 20 63 61 6e 6e 6f 74 20 6c 65 74 20 69 74 20 e cannot let it
6df0: 62 65 20 63 6f 6d 70 69 6c 65 64 20 69 6e 74 6f be compiled into
6e00: 0a 09 20 2a 20 61 6e 79 20 72 65 6c 65 61 73 65 .. * any release
6e10: 0a 09 20 2a 2f 0a 0a 09 69 66 20 28 73 74 72 63 .. */...if (strc
6e20: 6d 70 28 70 61 74 68 2c 20 22 2f 65 78 69 74 22 mp(path, "/exit"
6e30: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 61 70 70 66 ) == 0) {...appf
6e40: 73 5f 65 78 69 74 28 29 3b 0a 09 7d 0a 23 65 6e s_exit();..}.#en
6e50: 64 69 66 0a 0a 09 70 61 74 68 69 6e 66 6f 2e 74 dif...pathinfo.t
6e60: 79 70 65 20 3d 20 41 50 50 46 53 5f 50 41 54 48 ype = APPFS_PATH
6e70: 54 59 50 45 5f 49 4e 56 41 4c 49 44 3b 0a 0a 09 TYPE_INVALID;...
6e80: 72 65 74 76 61 6c 20 3d 20 61 70 70 66 73 5f 67 retval = appfs_g
6e90: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 28 70 61 74 et_path_info(pat
6ea0: 68 2c 20 26 70 61 74 68 69 6e 66 6f 29 3b 0a 09 h, &pathinfo);..
6eb0: 69 66 20 28 72 65 74 76 61 6c 20 21 3d 20 30 29 if (retval != 0)
6ec0: 20 7b 0a 09 09 69 66 20 28 72 65 74 76 61 6c 20 {...if (retval
6ed0: 3d 3d 20 2d 45 4e 4f 45 4e 54 29 20 7b 0a 09 09 == -ENOENT) {...
6ee0: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 67 65 .APPFS_DEBUG("ge
6ef0: 74 5f 70 61 74 68 5f 69 6e 66 6f 20 72 65 74 75 t_path_info retu
6f00: 72 6e 65 64 20 45 4e 4f 45 4e 54 2c 20 72 65 74 rned ENOENT, ret
6f10: 75 72 6e 69 6e 67 20 69 74 20 61 73 20 77 65 6c urning it as wel
6f20: 6c 2e 22 29 3b 0a 09 09 7d 20 65 6c 73 65 20 7b l.");...} else {
6f30: 0a 09 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 ....APPFS_DEBUG(
6f40: 22 65 72 72 6f 72 3a 20 67 65 74 5f 70 61 74 68 "error: get_path
6f50: 5f 69 6e 66 6f 20 66 61 69 6c 65 64 22 29 3b 0a _info failed");.
6f60: 09 09 7d 0a 0a 09 09 72 65 74 75 72 6e 28 72 65 ..}....return(re
6f70: 74 76 61 6c 29 3b 0a 09 7d 0a 0a 09 6d 65 6d 73 tval);..}...mems
6f80: 65 74 28 73 74 62 75 66 2c 20 30 2c 20 73 69 7a et(stbuf, 0, siz
6f90: 65 6f 66 28 73 74 72 75 63 74 20 73 74 61 74 29 eof(struct stat)
6fa0: 29 3b 0a 0a 09 73 74 62 75 66 2d 3e 73 74 5f 6d );...stbuf->st_m
6fb0: 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66 6f 2e time = pathinfo.
6fc0: 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e 73 74 time;..stbuf->st
6fd0: 5f 63 74 69 6d 65 20 3d 20 70 61 74 68 69 6e 66 _ctime = pathinf
6fe0: 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 2d 3e o.time;..stbuf->
6ff0: 73 74 5f 61 74 69 6d 65 20 3d 20 70 61 74 68 69 st_atime = pathi
7000: 6e 66 6f 2e 74 69 6d 65 3b 0a 09 73 74 62 75 66 nfo.time;..stbuf
7010: 2d 3e 73 74 5f 69 6e 6f 20 20 20 3d 20 70 61 74 ->st_ino = pat
7020: 68 69 6e 66 6f 2e 69 6e 6f 64 65 3b 0a 09 73 74 hinfo.inode;..st
7030: 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 20 3d 20 buf->st_mode =
7040: 30 3b 0a 0a 09 73 77 69 74 63 68 20 28 70 61 74 0;...switch (pat
7050: 68 69 6e 66 6f 2e 74 79 70 65 29 20 7b 0a 09 09 hinfo.type) {...
7060: 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 case APPFS_PATHT
7070: 59 50 45 5f 44 49 52 45 43 54 4f 52 59 3a 0a 09 YPE_DIRECTORY:..
7080: 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 ..stbuf->st_mode
7090: 20 3d 20 53 5f 49 46 44 49 52 20 7c 20 30 35 35 = S_IFDIR | 055
70a0: 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 5;....stbuf->st_
70b0: 6e 6c 69 6e 6b 20 3d 20 32 20 2b 20 70 61 74 68 nlink = 2 + path
70c0: 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 64 69 info.typeinfo.di
70d0: 72 2e 63 68 69 6c 64 63 6f 75 6e 74 3b 0a 09 09 r.childcount;...
70e0: 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 .break;...case A
70f0: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 46 49 PPFS_PATHTYPE_FI
7100: 4c 45 3a 0a 09 09 09 69 66 20 28 70 61 74 68 69 LE:....if (pathi
7110: 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c nfo.typeinfo.fil
7120: 65 2e 65 78 65 63 75 74 61 62 6c 65 29 20 7b 0a e.executable) {.
7130: 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f ....stbuf->st_mo
7140: 64 65 20 3d 20 53 5f 49 46 52 45 47 20 7c 20 30 de = S_IFREG | 0
7150: 35 35 35 3b 0a 09 09 09 7d 20 65 6c 73 65 20 7b 555;....} else {
7160: 0a 09 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d .....stbuf->st_m
7170: 6f 64 65 20 3d 20 53 5f 49 46 52 45 47 20 7c 20 ode = S_IFREG |
7180: 30 34 34 34 3b 0a 09 09 09 7d 0a 0a 09 09 09 73 0444;....}.....s
7190: 74 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d tbuf->st_nlink =
71a0: 20 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 1;....stbuf->st
71b0: 5f 73 69 7a 65 20 3d 20 70 61 74 68 69 6e 66 6f _size = pathinfo
71c0: 2e 74 79 70 65 69 6e 66 6f 2e 66 69 6c 65 2e 73 .typeinfo.file.s
71d0: 69 7a 65 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 ize;....break;..
71e0: 09 63 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 .case APPFS_PATH
71f0: 54 59 50 45 5f 53 59 4d 4c 49 4e 4b 3a 0a 09 09 TYPE_SYMLINK:...
7200: 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 .stbuf->st_mode
7210: 3d 20 53 5f 49 46 4c 4e 4b 20 7c 20 30 35 35 35 = S_IFLNK | 0555
7220: 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6e ;....stbuf->st_n
7230: 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 74 62 link = 1;....stb
7240: 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 70 61 uf->st_size = pa
7250: 74 68 69 6e 66 6f 2e 74 79 70 65 69 6e 66 6f 2e thinfo.typeinfo.
7260: 73 79 6d 6c 69 6e 6b 2e 73 69 7a 65 3b 0a 09 09 symlink.size;...
7270: 09 62 72 65 61 6b 3b 0a 09 09 63 61 73 65 20 41 .break;...case A
7280: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 53 4f PPFS_PATHTYPE_SO
7290: 43 4b 45 54 3a 0a 09 09 09 73 74 62 75 66 2d 3e CKET:....stbuf->
72a0: 73 74 5f 6d 6f 64 65 20 3d 20 53 5f 49 46 53 4f st_mode = S_IFSO
72b0: 43 4b 20 7c 20 30 35 35 35 3b 0a 09 09 09 73 74 CK | 0555;....st
72c0: 62 75 66 2d 3e 73 74 5f 6e 6c 69 6e 6b 20 3d 20 buf->st_nlink =
72d0: 31 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 1;....stbuf->st_
72e0: 73 69 7a 65 20 3d 20 30 3b 0a 09 09 09 62 72 65 size = 0;....bre
72f0: 61 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 ak;...case APPFS
7300: 5f 50 41 54 48 54 59 50 45 5f 46 49 46 4f 3a 0a _PATHTYPE_FIFO:.
7310: 09 09 09 73 74 62 75 66 2d 3e 73 74 5f 6d 6f 64 ...stbuf->st_mod
7320: 65 20 3d 20 53 5f 49 46 49 46 4f 20 7c 20 30 35 e = S_IFIFO | 05
7330: 35 35 3b 0a 09 09 09 73 74 62 75 66 2d 3e 73 74 55;....stbuf->st
7340: 5f 6e 6c 69 6e 6b 20 3d 20 31 3b 0a 09 09 09 73 _nlink = 1;....s
7350: 74 62 75 66 2d 3e 73 74 5f 73 69 7a 65 20 3d 20 tbuf->st_size =
7360: 30 3b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 63 0;....break;...c
7370: 61 73 65 20 41 50 50 46 53 5f 50 41 54 48 54 59 ase APPFS_PATHTY
7380: 50 45 5f 44 4f 45 53 5f 4e 4f 54 5f 45 58 49 53 PE_DOES_NOT_EXIS
7390: 54 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20 2d T:....retval = -
73a0: 45 4e 4f 45 4e 54 3b 0a 0a 09 09 09 62 72 65 61 ENOENT;.....brea
73b0: 6b 3b 0a 09 09 63 61 73 65 20 41 50 50 46 53 5f k;...case APPFS_
73c0: 50 41 54 48 54 59 50 45 5f 49 4e 56 41 4c 49 44 PATHTYPE_INVALID
73d0: 3a 0a 09 09 09 72 65 74 76 61 6c 20 3d 20 2d 45 :....retval = -E
73e0: 49 4f 3b 0a 0a 09 09 09 62 72 65 61 6b 3b 0a 09 IO;.....break;..
73f0: 7d 0a 0a 09 69 66 20 28 70 61 74 68 69 6e 66 6f }...if (pathinfo
7400: 2e 70 61 63 6b 61 67 65 64 29 20 7b 0a 09 09 73 .packaged) {...s
7410: 74 62 75 66 2d 3e 73 74 5f 75 69 64 20 20 20 3d tbuf->st_uid =
7420: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 appfs_get_fsuid
7430: 28 29 3b 0a 09 09 73 74 62 75 66 2d 3e 73 74 5f ();...stbuf->st_
7440: 67 69 64 20 20 20 3d 20 61 70 70 66 73 5f 67 65 gid = appfs_ge
7450: 74 5f 66 73 67 69 64 28 29 3b 0a 09 09 73 74 62 t_fsgid();...stb
7460: 75 66 2d 3e 73 74 5f 6d 6f 64 65 20 7c 3d 20 30 uf->st_mode |= 0
7470: 32 30 30 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 200;..}...return
7480: 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 (retval);.}..sta
7490: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 tic int appfs_fu
74a0: 73 65 5f 72 65 61 64 64 69 72 28 63 6f 6e 73 74 se_readdir(const
74b0: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 76 6f 69 char *path, voi
74c0: 64 20 2a 62 75 66 2c 20 66 75 73 65 5f 66 69 6c d *buf, fuse_fil
74d0: 6c 5f 64 69 72 5f 74 20 66 69 6c 6c 65 72 2c 20 l_dir_t filler,
74e0: 6f 66 66 5f 74 20 6f 66 66 73 65 74 2c 20 73 74 off_t offset, st
74f0: 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 ruct fuse_file_i
7500: 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 54 63 6c 5f nfo *fi) {..Tcl_
7510: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a Interp *interp;.
7520: 09 54 63 6c 5f 4f 62 6a 20 2a 2a 63 68 69 6c 64 .Tcl_Obj **child
7530: 72 65 6e 3b 0a 09 69 6e 74 20 63 68 69 6c 64 72 ren;..int childr
7540: 65 6e 5f 63 6f 75 6e 74 2c 20 69 64 78 3b 0a 09 en_count, idx;..
7550: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 41 int tcl_ret;...A
7560: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 PPFS_DEBUG("Ente
7570: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e r (path = %s, ..
7580: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 69 6e .)", path);...in
7590: 74 65 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c terp = appfs_Tcl
75a0: 49 6e 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 Interp();..if (i
75b0: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b nterp == NULL) {
75c0: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 ...APPFS_DEBUG("
75d0: 65 72 72 6f 72 3a 20 55 6e 61 62 6c 65 20 74 6f error: Unable to
75e0: 20 67 65 74 20 61 6e 20 69 6e 74 65 72 70 72 65 get an interpre
75f0: 74 65 72 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e ter");....return
7600: 28 30 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f (0);..}...appfs_
7610: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f call_libtcl(Tcl_
7620: 50 72 65 73 65 72 76 65 28 69 6e 74 65 72 70 29 Preserve(interp)
7630: 3b 29 0a 0a 09 66 69 6c 6c 65 72 28 62 75 66 2c ;)...filler(buf,
7640: 20 22 2e 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a ".", NULL, 0);.
7650: 09 66 69 6c 6c 65 72 28 62 75 66 2c 20 22 2e 2e .filler(buf, "..
7660: 22 2c 20 4e 55 4c 4c 2c 20 30 29 3b 0a 0a 09 74 ", NULL, 0);...t
7670: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 cl_ret = appfs_T
7680: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 cl_Eval(interp,
7690: 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 67 65 74 2, "::appfs::get
76a0: 63 68 69 6c 64 72 65 6e 22 2c 20 70 61 74 68 29 children", path)
76b0: 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 ;..if (tcl_ret !
76c0: 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 = TCL_OK) {...AP
76d0: 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 PFS_DEBUG("::app
76e0: 66 73 3a 3a 67 65 74 63 68 69 6c 64 72 65 6e 28 fs::getchildren(
76f0: 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 %s) failed.", pa
7700: 74 68 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c th);...appfs_cal
7710: 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 l_libtcl(....APP
7720: 46 53 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 FS_DEBUG("Tcl Er
7730: 72 6f 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c ror is: %s", Tcl
7740: 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 _GetStringResult
7750: 28 69 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a (interp));...)..
7760: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 ..appfs_call_lib
7770: 74 63 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 tcl(Tcl_Release(
7780: 69 6e 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 interp);)....ret
7790: 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 61 70 70 urn(0);..}...app
77a0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a fs_call_libtcl(.
77b0: 09 09 74 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f ..tcl_ret = Tcl_
77c0: 4c 69 73 74 4f 62 6a 47 65 74 45 6c 65 6d 65 6e ListObjGetElemen
77d0: 74 73 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 ts(interp, Tcl_G
77e0: 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 etObjResult(inte
77f0: 72 70 29 2c 20 26 63 68 69 6c 64 72 65 6e 5f 63 rp), &children_c
7800: 6f 75 6e 74 2c 20 26 63 68 69 6c 64 72 65 6e 29 ount, &children)
7810: 3b 0a 09 29 0a 09 69 66 20 28 74 63 6c 5f 72 65 ;..)..if (tcl_re
7820: 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 t != TCL_OK) {..
7830: 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 50 61 .APPFS_DEBUG("Pa
7840: 72 73 69 6e 67 20 6c 69 73 74 20 6f 66 20 63 68 rsing list of ch
7850: 69 6c 64 72 65 6e 20 6f 6e 20 70 61 74 68 20 25 ildren on path %
7860: 73 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 s failed.", path
7870: 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f );...appfs_call_
7880: 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 libtcl(....APPFS
7890: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f _DEBUG("Tcl Erro
78a0: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 r is: %s", Tcl_G
78b0: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 etStringResult(i
78c0: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 nterp));...)....
78d0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 appfs_call_libtc
78e0: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e l(Tcl_Release(in
78f0: 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 terp);)....retur
7900: 6e 28 30 29 3b 0a 09 7d 0a 0a 09 66 6f 72 20 28 n(0);..}...for (
7910: 69 64 78 20 3d 20 30 3b 20 69 64 78 20 3c 20 63 idx = 0; idx < c
7920: 68 69 6c 64 72 65 6e 5f 63 6f 75 6e 74 3b 20 69 hildren_count; i
7930: 64 78 2b 2b 29 20 7b 0a 09 09 61 70 70 66 73 5f dx++) {...appfs_
7940: 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 09 call_libtcl(....
7950: 66 69 6c 6c 65 72 28 62 75 66 2c 20 54 63 6c 5f filler(buf, Tcl_
7960: 47 65 74 53 74 72 69 6e 67 28 63 68 69 6c 64 72 GetString(childr
7970: 65 6e 5b 69 64 78 5d 29 2c 20 4e 55 4c 4c 2c 20 en[idx]), NULL,
7980: 30 29 3b 0a 09 09 29 0a 09 7d 0a 0a 09 61 70 70 0);...)..}...app
7990: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 fs_call_libtcl(T
79a0: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 cl_Release(inter
79b0: 70 29 3b 29 0a 0a 09 72 65 74 75 72 6e 28 30 29 p);)...return(0)
79c0: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 ;.}..static int
79d0: 61 70 70 66 73 5f 66 75 73 65 5f 6f 70 65 6e 28 appfs_fuse_open(
79e0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 const char *path
79f0: 2c 20 73 74 72 75 63 74 20 66 75 73 65 5f 66 69 , struct fuse_fi
7a00: 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 le_info *fi) {..
7a10: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 Tcl_Interp *inte
7a20: 72 70 3b 0a 09 73 74 72 75 63 74 20 61 70 70 66 rp;..struct appf
7a30: 73 5f 70 61 74 68 69 6e 66 6f 20 70 61 74 68 69 s_pathinfo pathi
7a40: 6e 66 6f 3b 0a 09 63 6f 6e 73 74 20 63 68 61 72 nfo;..const char
7a50: 20 2a 72 65 61 6c 5f 70 61 74 68 2c 20 2a 6d 6f *real_path, *mo
7a60: 64 65 3b 0a 09 69 6e 74 20 67 70 69 5f 72 65 74 de;..int gpi_ret
7a70: 2c 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 , tcl_ret;..int
7a80: 66 68 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 fh;...APPFS_DEBU
7a90: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d G("Enter (path =
7aa0: 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 %s, ...)", path
7ab0: 29 3b 0a 0a 09 67 70 69 5f 72 65 74 20 3d 20 61 );...gpi_ret = a
7ac0: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e ppfs_get_path_in
7ad0: 66 6f 28 70 61 74 68 2c 20 26 70 61 74 68 69 6e fo(path, &pathin
7ae0: 66 6f 29 3b 0a 0a 09 69 66 20 28 28 66 69 2d 3e fo);...if ((fi->
7af0: 66 6c 61 67 73 20 26 20 28 4f 5f 57 52 4f 4e 4c flags & (O_WRONL
7b00: 59 7c 4f 5f 43 52 45 41 54 29 29 20 3d 3d 20 28 Y|O_CREAT)) == (
7b10: 4f 5f 43 52 45 41 54 7c 4f 5f 57 52 4f 4e 4c 59 O_CREAT|O_WRONLY
7b20: 29 29 20 7b 0a 09 09 2f 2a 20 54 68 65 20 66 69 )) {.../* The fi
7b30: 6c 65 20 77 69 6c 6c 20 62 65 20 63 72 65 61 74 le will be creat
7b40: 65 64 20 69 66 20 69 74 20 64 6f 65 73 20 6e 6f ed if it does no
7b50: 74 20 65 78 69 73 74 20 2a 2f 0a 09 09 69 66 20 t exist */...if
7b60: 28 67 70 69 5f 72 65 74 20 21 3d 20 30 20 26 26 (gpi_ret != 0 &&
7b70: 20 67 70 69 5f 72 65 74 20 21 3d 20 2d 45 4e 4f gpi_ret != -ENO
7b80: 45 4e 54 29 20 7b 0a 09 09 09 41 50 50 46 53 5f ENT) {....APPFS_
7b90: 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 67 65 DEBUG("error: ge
7ba0: 74 5f 70 61 74 68 5f 69 6e 66 6f 20 66 61 69 6c t_path_info fail
7bb0: 65 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e ed");.....return
7bc0: 28 67 70 69 5f 72 65 74 29 3b 0a 09 09 7d 0a 0a (gpi_ret);...}..
7bd0: 09 09 6d 6f 64 65 20 3d 20 22 63 72 65 61 74 65 ..mode = "create
7be0: 22 3b 0a 0a 09 09 2f 2a 0a 09 09 20 2a 20 57 65 ";..../*... * We
7bf0: 20 68 61 76 65 20 74 6f 20 63 6c 65 61 72 20 74 have to clear t
7c00: 68 65 20 63 61 63 68 65 20 68 65 72 65 20 73 6f he cache here so
7c10: 20 74 68 61 74 20 74 68 65 20 6e 75 6d 62 65 72 that the number
7c20: 20 6f 66 0a 09 09 20 2a 20 6c 69 6e 6b 73 20 67 of... * links g
7c30: 65 74 73 20 6d 61 69 6e 74 61 69 6e 65 64 20 6f ets maintained o
7c40: 6e 20 74 68 65 20 70 61 72 65 6e 74 20 64 69 72 n the parent dir
7c50: 65 63 74 6f 72 79 0a 09 09 20 2a 2f 0a 09 09 61 ectory... */...a
7c60: 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e ppfs_get_path_in
7c70: 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 61 fo_cache_flush(a
7c80: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 ppfs_get_fsuid()
7c90: 2c 20 2d 31 29 3b 0a 09 7d 20 65 6c 73 65 20 7b , -1);..} else {
7ca0: 0a 09 09 2f 2a 20 54 68 65 20 66 69 6c 65 20 6d .../* The file m
7cb0: 75 73 74 20 61 6c 72 65 61 64 79 20 65 78 69 73 ust already exis
7cc0: 74 20 2a 2f 0a 09 09 69 66 20 28 67 70 69 5f 72 t */...if (gpi_r
7cd0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 41 50 et != 0) {....AP
7ce0: 50 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 PFS_DEBUG("error
7cf0: 3a 20 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 20 : get_path_info
7d00: 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09 09 72 65 failed");.....re
7d10: 74 75 72 6e 28 67 70 69 5f 72 65 74 29 3b 0a 09 turn(gpi_ret);..
7d20: 09 7d 0a 0a 09 09 6d 6f 64 65 20 3d 20 22 22 3b .}....mode = "";
7d30: 0a 0a 09 09 69 66 20 28 28 66 69 2d 3e 66 6c 61 ....if ((fi->fla
7d40: 67 73 20 26 20 4f 5f 57 52 4f 4e 4c 59 29 20 3d gs & O_WRONLY) =
7d50: 3d 20 4f 5f 57 52 4f 4e 4c 59 29 20 7b 0a 09 09 = O_WRONLY) {...
7d60: 09 6d 6f 64 65 20 3d 20 22 77 72 69 74 65 22 3b .mode = "write";
7d70: 0a 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 28 70 61 ...}..}...if (pa
7d80: 74 68 69 6e 66 6f 2e 74 79 70 65 20 3d 3d 20 41 thinfo.type == A
7d90: 50 50 46 53 5f 50 41 54 48 54 59 50 45 5f 44 49 PPFS_PATHTYPE_DI
7da0: 52 45 43 54 4f 52 59 29 20 7b 0a 09 09 41 50 50 RECTORY) {...APP
7db0: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a FS_DEBUG("error:
7dc0: 20 41 73 6b 65 64 20 74 6f 20 6f 70 65 6e 20 61 Asked to open a
7dd0: 20 64 69 72 65 63 74 6f 72 79 2e 22 29 3b 0a 0a directory.");..
7de0: 09 09 72 65 74 75 72 6e 28 2d 45 49 53 44 49 52 ..return(-EISDIR
7df0: 29 3b 0a 09 7d 0a 0a 09 69 6e 74 65 72 70 20 3d );..}...interp =
7e00: 20 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 appfs_TclInterp
7e10: 28 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 ();..if (interp
7e20: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 41 50 50 == NULL) {...APP
7e30: 46 53 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a FS_DEBUG("error:
7e40: 20 55 6e 61 62 6c 65 20 74 6f 20 67 65 74 20 61 Unable to get a
7e50: 6e 20 69 6e 74 65 72 70 72 65 74 65 72 22 29 3b n interpreter");
7e60: 0a 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 ....return(-EIO)
7e70: 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c ;..}...appfs_cal
7e80: 6c 5f 6c 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 l_libtcl(Tcl_Pre
7e90: 73 65 72 76 65 28 69 6e 74 65 72 70 29 3b 29 0a serve(interp);).
7ea0: 0a 09 74 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 ..tcl_ret = appf
7eb0: 73 5f 54 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 s_Tcl_Eval(inter
7ec0: 70 2c 20 33 2c 20 22 3a 3a 61 70 70 66 73 3a 3a p, 3, "::appfs::
7ed0: 6f 70 65 6e 70 61 74 68 22 2c 20 70 61 74 68 2c openpath", path,
7ee0: 20 6d 6f 64 65 29 3b 0a 09 69 66 20 28 74 63 6c mode);..if (tcl
7ef0: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 _ret != TCL_OK)
7f00: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 {...APPFS_DEBUG(
7f10: 22 3a 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 "::appfs::openpa
7f20: 74 68 28 25 73 2c 20 25 73 29 20 66 61 69 6c 65 th(%s, %s) faile
7f30: 64 2e 22 2c 20 70 61 74 68 2c 20 6d 6f 64 65 29 d.", path, mode)
7f40: 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c ;...appfs_call_l
7f50: 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f ibtcl(....APPFS_
7f60: 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 DEBUG("Tcl Error
7f70: 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 is: %s", Tcl_Ge
7f80: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e tStringResult(in
7f90: 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 terp));...)....a
7fa0: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c ppfs_call_libtcl
7fb0: 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 (Tcl_Release(int
7fc0: 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e erp);)....return
7fd0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 (-EIO);..}...app
7fe0: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a fs_call_libtcl(.
7ff0: 09 09 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 ..real_path = Tc
8000: 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c l_GetStringResul
8010: 74 28 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 t(interp);..)...
8020: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 appfs_call_libtc
8030: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e l(Tcl_Release(in
8040: 74 65 72 70 29 3b 29 0a 0a 09 69 66 20 28 72 65 terp);)...if (re
8050: 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 al_path == NULL)
8060: 20 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 {...APPFS_DEBUG
8070: 28 22 65 72 72 6f 72 3a 20 72 65 61 6c 5f 70 61 ("error: real_pa
8080: 74 68 20 77 61 73 20 4e 55 4c 4c 2e 22 29 0a 0a th was NULL.")..
8090: 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a ..return(-EIO);.
80a0: 09 7d 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 .}...APPFS_DEBUG
80b0: 28 22 54 72 61 6e 73 6c 61 74 65 64 20 72 65 71 ("Translated req
80c0: 75 65 73 74 20 74 6f 20 6f 70 65 6e 20 25 73 20 uest to open %s
80d0: 74 6f 20 6f 70 65 6e 69 6e 67 20 25 73 20 28 6d to opening %s (m
80e0: 6f 64 65 20 3d 20 5c 22 25 73 5c 22 29 22 2c 20 ode = \"%s\")",
80f0: 70 61 74 68 2c 20 72 65 61 6c 5f 70 61 74 68 2c path, real_path,
8100: 20 6d 6f 64 65 29 3b 0a 0a 09 66 68 20 3d 20 6f mode);...fh = o
8110: 70 65 6e 28 72 65 61 6c 5f 70 61 74 68 2c 20 66 pen(real_path, f
8120: 69 2d 3e 66 6c 61 67 73 2c 20 30 36 30 30 29 3b i->flags, 0600);
8130: 0a 0a 09 69 66 20 28 66 68 20 3c 20 30 29 20 7b ...if (fh < 0) {
8140: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 ...APPFS_DEBUG("
8150: 65 72 72 6f 72 3a 20 6f 70 65 6e 20 66 61 69 6c error: open fail
8160: 65 64 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 ed");....return(
8170: 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 7d 0a errno * -1);..}.
8180: 0a 09 66 69 2d 3e 66 68 20 3d 20 66 68 3b 0a 0a ..fi->fh = fh;..
8190: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 .return(0);.}..s
81a0: 74 61 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f tatic int appfs_
81b0: 66 75 73 65 5f 63 6c 6f 73 65 28 63 6f 6e 73 74 fuse_close(const
81c0: 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74 72 char *path, str
81d0: 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e uct fuse_file_in
81e0: 66 6f 20 2a 66 69 29 20 7b 0a 09 69 6e 74 20 63 fo *fi) {..int c
81f0: 6c 6f 73 65 5f 72 65 74 3b 0a 0a 09 61 70 70 66 lose_ret;...appf
8200: 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f s_get_path_info_
8210: 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 cache_rm(path, a
8220: 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 ppfs_get_fsuid()
8230: 29 3b 0a 0a 09 63 6c 6f 73 65 5f 72 65 74 20 3d );...close_ret =
8240: 20 63 6c 6f 73 65 28 66 69 2d 3e 66 68 29 3b 0a close(fi->fh);.
8250: 09 69 66 20 28 63 6c 6f 73 65 5f 72 65 74 20 21 .if (close_ret !
8260: 3d 20 30 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 = 0) {...APPFS_D
8270: 45 42 55 47 28 22 65 72 72 6f 72 3a 20 63 6c 6f EBUG("error: clo
8280: 73 65 20 66 61 69 6c 65 64 22 29 3b 0a 0a 09 09 se failed");....
8290: 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d return(errno * -
82a0: 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 1);..}...return(
82b0: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 0);.}..static in
82c0: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 t appfs_fuse_rea
82d0: 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 d(const char *pa
82e0: 74 68 2c 20 63 68 61 72 20 2a 62 75 66 2c 20 73 th, char *buf, s
82f0: 69 7a 65 5f 74 20 73 69 7a 65 2c 20 6f 66 66 5f ize_t size, off_
8300: 74 20 6f 66 66 73 65 74 2c 20 73 74 72 75 63 74 t offset, struct
8310: 20 66 75 73 65 5f 66 69 6c 65 5f 69 6e 66 6f 20 fuse_file_info
8320: 2a 66 69 29 20 7b 0a 09 73 73 69 7a 65 5f 74 20 *fi) {..ssize_t
8330: 72 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20 72 read_ret;..int r
8340: 65 74 76 61 6c 3b 0a 0a 09 41 50 50 46 53 5f 44 etval;...APPFS_D
8350: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 EBUG("Enter (pat
8360: 68 20 3d 20 25 73 2c 20 62 75 66 2c 20 25 6c 6c h = %s, buf, %ll
8370: 69 2c 20 25 6c 6c 69 2c 20 66 64 3d 25 6c 6c 69 i, %lli, fd=%lli
8380: 29 22 2c 20 70 61 74 68 2c 20 28 6c 6f 6e 67 20 )", path, (long
8390: 6c 6f 6e 67 29 20 73 69 7a 65 2c 20 28 6c 6f 6e long) size, (lon
83a0: 67 20 6c 6f 6e 67 29 20 6f 66 66 73 65 74 2c 20 g long) offset,
83b0: 28 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 69 2d 3e (long long) fi->
83c0: 66 68 29 3b 0a 0a 09 72 65 74 76 61 6c 20 3d 20 fh);...retval =
83d0: 30 3b 0a 0a 09 77 68 69 6c 65 20 28 73 69 7a 65 0;...while (size
83e0: 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 61 64 5f != 0) {...read_
83f0: 72 65 74 20 3d 20 70 72 65 61 64 28 66 69 2d 3e ret = pread(fi->
8400: 66 68 2c 20 62 75 66 2c 20 73 69 7a 65 2c 20 6f fh, buf, size, o
8410: 66 66 73 65 74 29 3b 0a 0a 09 09 69 66 20 28 72 ffset);....if (r
8420: 65 61 64 5f 72 65 74 20 3c 20 30 29 20 7b 0a 09 ead_ret < 0) {..
8430: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 65 ..APPFS_DEBUG("e
8440: 72 72 6f 72 3a 20 72 65 61 64 20 66 61 69 6c 65 rror: read faile
8450: 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 d");.....return(
8460: 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 09 7d errno * -1);...}
8470: 0a 0a 09 09 69 66 20 28 72 65 61 64 5f 72 65 74 ....if (read_ret
8480: 20 3d 3d 20 30 29 20 7b 0a 09 09 09 62 72 65 61 == 0) {....brea
8490: 6b 3b 0a 09 09 7d 0a 0a 09 09 73 69 7a 65 20 2d k;...}....size -
84a0: 3d 20 72 65 61 64 5f 72 65 74 3b 0a 09 09 62 75 = read_ret;...bu
84b0: 66 20 20 2b 3d 20 72 65 61 64 5f 72 65 74 3b 0a f += read_ret;.
84c0: 09 09 6f 66 66 73 65 74 20 2b 3d 20 72 65 61 64 ..offset += read
84d0: 5f 72 65 74 3b 0a 09 09 72 65 74 76 61 6c 20 2b _ret;...retval +
84e0: 3d 20 72 65 61 64 5f 72 65 74 3b 0a 09 7d 0a 0a = read_ret;..}..
84f0: 09 69 66 20 28 73 69 7a 65 20 21 3d 20 30 29 20 .if (size != 0)
8500: 7b 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 {...APPFS_DEBUG(
8510: 22 65 72 72 6f 72 3a 20 69 6e 63 6f 6d 70 6c 65 "error: incomple
8520: 74 65 20 72 65 61 64 20 28 74 68 69 73 20 6d 69 te read (this mi
8530: 67 68 74 20 62 65 20 61 6e 20 65 72 72 6f 72 20 ght be an error
8540: 62 65 63 61 75 73 65 20 46 55 53 45 20 77 69 6c because FUSE wil
8550: 6c 20 72 65 71 75 65 73 74 20 74 68 65 20 65 78 l request the ex
8560: 61 63 74 20 6c 65 6e 67 74 68 20 6f 66 20 74 68 act length of th
8570: 65 20 66 69 6c 65 29 22 29 3b 0a 09 7d 0a 0a 09 e file)");..}...
8580: 41 50 50 46 53 5f 44 45 42 55 47 28 22 52 65 74 APPFS_DEBUG("Ret
8590: 75 72 6e 69 6e 67 3a 20 25 69 22 2c 20 72 65 74 urning: %i", ret
85a0: 76 61 6c 29 3b 0a 0a 09 72 65 74 75 72 6e 28 72 val);...return(r
85b0: 65 74 76 61 6c 29 3b 0a 7d 0a 0a 73 74 61 74 69 etval);.}..stati
85c0: 63 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 c int appfs_fuse
85d0: 5f 77 72 69 74 65 28 63 6f 6e 73 74 20 63 68 61 _write(const cha
85e0: 72 20 2a 70 61 74 68 2c 20 63 6f 6e 73 74 20 63 r *path, const c
85f0: 68 61 72 20 2a 62 75 66 2c 20 73 69 7a 65 5f 74 har *buf, size_t
8600: 20 73 69 7a 65 2c 20 6f 66 66 5f 74 20 6f 66 66 size, off_t off
8610: 73 65 74 2c 20 73 74 72 75 63 74 20 66 75 73 65 set, struct fuse
8620: 5f 66 69 6c 65 5f 69 6e 66 6f 20 2a 66 69 29 20 _file_info *fi)
8630: 7b 0a 09 73 73 69 7a 65 5f 74 20 77 72 69 74 65 {..ssize_t write
8640: 5f 72 65 74 3b 0a 09 69 6e 74 20 72 65 74 76 61 _ret;..int retva
8650: 6c 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 l;...APPFS_DEBUG
8660: 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 ("Enter (path =
8670: 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 %s, ...)", path)
8680: 3b 0a 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 ;...appfs_get_pa
8690: 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 72 6d th_info_cache_rm
86a0: 28 70 61 74 68 2c 20 61 70 70 66 73 5f 67 65 74 (path, appfs_get
86b0: 5f 66 73 75 69 64 28 29 29 3b 0a 0a 09 72 65 74 _fsuid());...ret
86c0: 76 61 6c 20 3d 20 30 3b 0a 0a 09 77 68 69 6c 65 val = 0;...while
86d0: 20 28 73 69 7a 65 20 21 3d 20 30 29 20 7b 0a 09 (size != 0) {..
86e0: 09 77 72 69 74 65 5f 72 65 74 20 3d 20 70 77 72 .write_ret = pwr
86f0: 69 74 65 28 66 69 2d 3e 66 68 2c 20 62 75 66 2c ite(fi->fh, buf,
8700: 20 73 69 7a 65 2c 20 6f 66 66 73 65 74 29 3b 0a size, offset);.
8710: 0a 09 09 69 66 20 28 77 72 69 74 65 5f 72 65 74 ...if (write_ret
8720: 20 3c 20 30 29 20 7b 0a 09 09 09 41 50 50 46 53 < 0) {....APPFS
8730: 5f 44 45 42 55 47 28 22 65 72 72 6f 72 3a 20 77 _DEBUG("error: w
8740: 72 69 74 65 20 66 61 69 6c 65 64 22 29 3b 0a 0a rite failed");..
8750: 09 09 09 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 ...return(errno
8760: 2a 20 2d 31 29 3b 0a 09 09 7d 0a 0a 09 09 69 66 * -1);...}....if
8770: 20 28 77 72 69 74 65 5f 72 65 74 20 3d 3d 20 30 (write_ret == 0
8780: 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 ) {....break;...
8790: 7d 0a 0a 09 09 73 69 7a 65 20 2d 3d 20 77 72 69 }....size -= wri
87a0: 74 65 5f 72 65 74 3b 0a 09 09 62 75 66 20 20 2b te_ret;...buf +
87b0: 3d 20 77 72 69 74 65 5f 72 65 74 3b 0a 09 09 6f = write_ret;...o
87c0: 66 66 73 65 74 20 2b 3d 20 77 72 69 74 65 5f 72 ffset += write_r
87d0: 65 74 3b 0a 09 09 72 65 74 76 61 6c 20 2b 3d 20 et;...retval +=
87e0: 77 72 69 74 65 5f 72 65 74 3b 0a 09 7d 0a 0a 09 write_ret;..}...
87f0: 69 66 20 28 73 69 7a 65 20 21 3d 20 30 29 20 7b if (size != 0) {
8800: 0a 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 ...APPFS_DEBUG("
8810: 65 72 72 6f 72 3a 20 69 6e 63 6f 6d 70 6c 65 74 error: incomplet
8820: 65 20 77 72 69 74 65 22 29 3b 0a 09 7d 0a 0a 09 e write");..}...
8830: 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 3b 0a return(retval);.
8840: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 }..static int ap
8850: 70 66 73 5f 66 75 73 65 5f 6d 6b 6e 6f 64 28 63 pfs_fuse_mknod(c
8860: 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 2c onst char *path,
8870: 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 64 65 mode_t mode, de
8880: 76 5f 74 20 64 65 76 69 63 65 29 20 7b 0a 09 63 v_t device) {..c
8890: 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a har *real_path;.
88a0: 09 69 6e 74 20 6d 6b 6e 6f 64 5f 72 65 74 3b 0a .int mknod_ret;.
88b0: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 45 ..APPFS_DEBUG("E
88c0: 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 2c nter (path = %s,
88d0: 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a ...)", path);..
88e0: 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f 49 .if ((mode & S_I
88f0: 46 43 48 52 29 20 3d 3d 20 53 5f 49 46 43 48 52 FCHR) == S_IFCHR
8900: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 50 ) {...return(-EP
8910: 45 52 4d 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 28 ERM);..}...if ((
8920: 6d 6f 64 65 20 26 20 53 5f 49 46 42 4c 4b 29 20 mode & S_IFBLK)
8930: 3d 3d 20 53 5f 49 46 42 4c 4b 29 20 7b 0a 09 09 == S_IFBLK) {...
8940: 72 65 74 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a return(-EPERM);.
8950: 09 7d 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 3d .}...real_path =
8960: 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f 74 appfs_prepare_t
8970: 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b 0a o_create(path);.
8980: 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d .if (real_path =
8990: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 = NULL) {...retu
89a0: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 rn(-EIO);..}...a
89b0: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 ppfs_simulate_us
89c0: 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a er_fs_enter();..
89d0: 09 6d 6b 6e 6f 64 5f 72 65 74 20 3d 20 6d 6b 6e .mknod_ret = mkn
89e0: 6f 64 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f od(real_path, mo
89f0: 64 65 2c 20 64 65 76 69 63 65 29 3b 0a 0a 09 61 de, device);...a
8a00: 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 ppfs_simulate_us
8a10: 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a er_fs_leave();..
8a20: 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68 29 .free(real_path)
8a30: 3b 0a 0a 09 69 66 20 28 6d 6b 6e 6f 64 5f 72 65 ;...if (mknod_re
8a40: 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 t != 0) {...retu
8a50: 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a rn(errno * -1);.
8a60: 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a .}...return(0);.
8a70: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 }..static int ap
8a80: 70 66 73 5f 66 75 73 65 5f 63 72 65 61 74 65 28 pfs_fuse_create(
8a90: 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 68 const char *path
8aa0: 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 73 , mode_t mode, s
8ab0: 74 72 75 63 74 20 66 75 73 65 5f 66 69 6c 65 5f truct fuse_file_
8ac0: 69 6e 66 6f 20 2a 66 69 29 20 7b 0a 09 63 68 61 info *fi) {..cha
8ad0: 72 20 2a 72 65 61 6c 5f 70 61 74 68 3b 0a 09 69 r *real_path;..i
8ae0: 6e 74 20 66 64 3b 0a 0a 09 41 50 50 46 53 5f 44 nt fd;...APPFS_D
8af0: 45 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 EBUG("Enter (pat
8b00: 68 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 h = %s, ...)", p
8b10: 61 74 68 29 3b 0a 0a 09 69 66 20 28 28 6d 6f 64 ath);...if ((mod
8b20: 65 20 26 20 53 5f 49 46 43 48 52 29 20 3d 3d 20 e & S_IFCHR) ==
8b30: 53 5f 49 46 43 48 52 29 20 7b 0a 09 09 72 65 74 S_IFCHR) {...ret
8b40: 75 72 6e 28 2d 45 50 45 52 4d 29 3b 0a 09 7d 0a urn(-EPERM);..}.
8b50: 0a 09 69 66 20 28 28 6d 6f 64 65 20 26 20 53 5f ..if ((mode & S_
8b60: 49 46 42 4c 4b 29 20 3d 3d 20 53 5f 49 46 42 4c IFBLK) == S_IFBL
8b70: 4b 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 K) {...return(-E
8b80: 50 45 52 4d 29 3b 0a 09 7d 0a 0a 09 72 65 61 6c PERM);..}...real
8b90: 5f 70 61 74 68 20 3d 20 61 70 70 66 73 5f 70 72 _path = appfs_pr
8ba0: 65 70 61 72 65 5f 74 6f 5f 63 72 65 61 74 65 28 epare_to_create(
8bb0: 70 61 74 68 29 3b 0a 09 69 66 20 28 72 65 61 6c path);..if (real
8bc0: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b _path == NULL) {
8bd0: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b ...return(-EIO);
8be0: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 ..}...appfs_simu
8bf0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 late_user_fs_ent
8c00: 65 72 28 29 3b 0a 0a 09 66 64 20 3d 20 63 72 65 er();...fd = cre
8c10: 61 74 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d 6f at(real_path, mo
8c20: 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 6d de);...appfs_sim
8c30: 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c 65 ulate_user_fs_le
8c40: 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 65 ave();...free(re
8c50: 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 28 al_path);...if (
8c60: 66 64 20 3c 20 30 29 20 7b 0a 09 09 72 65 74 75 fd < 0) {...retu
8c70: 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a rn(errno * -1);.
8c80: 09 7d 0a 0a 09 66 69 2d 3e 66 68 20 3d 20 66 64 .}...fi->fh = fd
8c90: 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d ;...return(0);.}
8ca0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 70 ..static int app
8cb0: 66 73 5f 66 75 73 65 5f 74 72 75 6e 63 61 74 65 fs_fuse_truncate
8cc0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 (const char *pat
8cd0: 68 2c 20 6f 66 66 5f 74 20 73 69 7a 65 29 20 7b h, off_t size) {
8ce0: 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 ..char *real_pat
8cf0: 68 3b 0a 09 69 6e 74 20 74 72 75 6e 63 61 74 65 h;..int truncate
8d00: 5f 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 _ret;...APPFS_DE
8d10: 42 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 BUG("Enter (path
8d20: 20 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 = %s, ...)", pa
8d30: 74 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68 th);...real_path
8d40: 20 3d 20 61 70 70 66 73 5f 6c 6f 63 61 6c 70 61 = appfs_localpa
8d50: 74 68 28 70 61 74 68 29 3b 0a 09 69 66 20 28 72 th(path);..if (r
8d60: 65 61 6c 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c eal_path == NULL
8d70: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 ) {...return(-EI
8d80: 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 67 O);..}...appfs_g
8d90: 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 et_path_info_cac
8da0: 68 65 5f 72 6d 28 70 61 74 68 2c 20 61 70 70 66 he_rm(path, appf
8db0: 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 3b 0a s_get_fsuid());.
8dc0: 0a 09 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 ..appfs_simulate
8dd0: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 _user_fs_enter()
8de0: 3b 0a 0a 09 74 72 75 6e 63 61 74 65 5f 72 65 74 ;...truncate_ret
8df0: 20 3d 20 74 72 75 6e 63 61 74 65 28 72 65 61 6c = truncate(real
8e00: 5f 70 61 74 68 2c 20 73 69 7a 65 29 3b 0a 0a 09 _path, size);...
8e10: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 appfs_simulate_u
8e20: 73 65 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a ser_fs_leave();.
8e30: 0a 09 66 72 65 65 28 72 65 61 6c 5f 70 61 74 68 ..free(real_path
8e40: 29 3b 0a 0a 09 69 66 20 28 74 72 75 6e 63 61 74 );...if (truncat
8e50: 65 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 e_ret != 0) {...
8e60: 72 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d return(errno * -
8e70: 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 1);..}...return(
8e80: 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 0);.}..static in
8e90: 74 20 61 70 70 66 73 5f 66 75 73 65 5f 75 6e 6c t appfs_fuse_unl
8ea0: 69 6e 6b 5f 72 6d 64 69 72 28 63 6f 6e 73 74 20 ink_rmdir(const
8eb0: 63 68 61 72 20 2a 70 61 74 68 29 20 7b 0a 09 54 char *path) {..T
8ec0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 cl_Interp *inter
8ed0: 70 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b p;..int tcl_ret;
8ee0: 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 ...APPFS_DEBUG("
8ef0: 45 6e 74 65 72 20 28 70 61 74 68 20 3d 20 25 73 Enter (path = %s
8f00: 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 68 29 3b 0a , ...)", path);.
8f10: 0a 09 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 ..appfs_get_path
8f20: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 _info_cache_flus
8f30: 68 28 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 h(appfs_get_fsui
8f40: 64 28 29 2c 20 2d 31 29 3b 0a 0a 09 69 6e 74 65 d(), -1);...inte
8f50: 72 70 20 3d 20 61 70 70 66 73 5f 54 63 6c 49 6e rp = appfs_TclIn
8f60: 74 65 72 70 28 29 3b 0a 09 69 66 20 28 69 6e 74 terp();..if (int
8f70: 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 erp == NULL) {..
8f80: 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 .return(-EIO);..
8f90: 7d 0a 0a 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c }...appfs_call_l
8fa0: 69 62 74 63 6c 28 54 63 6c 5f 50 72 65 73 65 72 ibtcl(Tcl_Preser
8fb0: 76 65 28 69 6e 74 65 72 70 29 3b 29 0a 0a 09 74 ve(interp);)...t
8fc0: 63 6c 5f 72 65 74 20 3d 20 61 70 70 66 73 5f 54 cl_ret = appfs_T
8fd0: 63 6c 5f 45 76 61 6c 28 69 6e 74 65 72 70 2c 20 cl_Eval(interp,
8fe0: 32 2c 20 22 3a 3a 61 70 70 66 73 3a 3a 75 6e 6c 2, "::appfs::unl
8ff0: 69 6e 6b 70 61 74 68 22 2c 20 70 61 74 68 29 3b inkpath", path);
9000: 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d ..if (tcl_ret !=
9010: 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 50 50 TCL_OK) {...APP
9020: 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 70 66 FS_DEBUG("::appf
9030: 73 3a 3a 75 6e 6c 69 6e 6b 70 61 74 68 28 25 73 s::unlinkpath(%s
9040: 29 20 66 61 69 6c 65 64 2e 22 2c 20 70 61 74 68 ) failed.", path
9050: 29 3b 0a 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f );...appfs_call_
9060: 6c 69 62 74 63 6c 28 0a 09 09 09 41 50 50 46 53 libtcl(....APPFS
9070: 5f 44 45 42 55 47 28 22 54 63 6c 20 45 72 72 6f _DEBUG("Tcl Erro
9080: 72 20 69 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 r is: %s", Tcl_G
9090: 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 etStringResult(i
90a0: 6e 74 65 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 nterp));...)....
90b0: 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 appfs_call_libtc
90c0: 6c 28 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e l(Tcl_Release(in
90d0: 74 65 72 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 terp);)....retur
90e0: 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 n(-EIO);..}...ap
90f0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 pfs_call_libtcl(
9100: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 Tcl_Release(inte
9110: 72 70 29 3b 29 0a 0a 09 72 65 74 75 72 6e 28 30 rp);)...return(0
9120: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 );.}..static int
9130: 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b 64 69 appfs_fuse_mkdi
9140: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 r(const char *pa
9150: 74 68 2c 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 29 th, mode_t mode)
9160: 20 7b 0a 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 {..char *real_p
9170: 61 74 68 3b 0a 09 69 6e 74 20 6d 6b 64 69 72 5f ath;..int mkdir_
9180: 72 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 ret;...APPFS_DEB
9190: 55 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 UG("Enter (path
91a0: 3d 20 25 73 2c 20 2e 2e 2e 29 22 2c 20 70 61 74 = %s, ...)", pat
91b0: 68 29 3b 0a 0a 09 72 65 61 6c 5f 70 61 74 68 20 h);...real_path
91c0: 3d 20 61 70 70 66 73 5f 70 72 65 70 61 72 65 5f = appfs_prepare_
91d0: 74 6f 5f 63 72 65 61 74 65 28 70 61 74 68 29 3b to_create(path);
91e0: 0a 09 69 66 20 28 72 65 61 6c 5f 70 61 74 68 20 ..if (real_path
91f0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 == NULL) {...ret
9200: 75 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 urn(-EIO);..}...
9210: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 appfs_simulate_u
9220: 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a ser_fs_enter();.
9230: 0a 09 6d 6b 64 69 72 5f 72 65 74 20 3d 20 6d 6b ..mkdir_ret = mk
9240: 64 69 72 28 72 65 61 6c 5f 70 61 74 68 2c 20 6d dir(real_path, m
9250: 6f 64 65 29 3b 0a 0a 09 61 70 70 66 73 5f 73 69 ode);...appfs_si
9260: 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 6c mulate_user_fs_l
9270: 65 61 76 65 28 29 3b 0a 0a 09 66 72 65 65 28 72 eave();...free(r
9280: 65 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 69 66 20 eal_path);...if
9290: 28 6d 6b 64 69 72 5f 72 65 74 20 21 3d 20 30 29 (mkdir_ret != 0)
92a0: 20 7b 0a 09 09 69 66 20 28 65 72 72 6e 6f 20 21 {...if (errno !
92b0: 3d 20 45 45 58 49 53 54 29 20 7b 0a 09 09 09 72 = EEXIST) {....r
92c0: 65 74 75 72 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 eturn(errno * -1
92d0: 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 );...}..}...retu
92e0: 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 rn(0);.}..static
92f0: 20 69 6e 74 20 61 70 70 66 73 5f 66 75 73 65 5f int appfs_fuse_
9300: 63 68 6d 6f 64 28 63 6f 6e 73 74 20 63 68 61 72 chmod(const char
9310: 20 2a 70 61 74 68 2c 20 6d 6f 64 65 5f 74 20 6d *path, mode_t m
9320: 6f 64 65 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 ode) {..Tcl_Inte
9330: 72 70 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e rp *interp;..con
9340: 73 74 20 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 st char *real_pa
9350: 74 68 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 th;..int tcl_ret
9360: 2c 20 63 68 6d 6f 64 5f 72 65 74 3b 0a 0a 09 41 , chmod_ret;...A
9370: 50 50 46 53 5f 44 45 42 55 47 28 22 45 6e 74 65 PPFS_DEBUG("Ente
9380: 72 20 28 70 61 74 68 20 3d 20 25 73 2c 20 2e 2e r (path = %s, ..
9390: 2e 29 22 2c 20 70 61 74 68 29 3b 0a 0a 09 61 70 .)", path);...ap
93a0: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 pfs_get_path_inf
93b0: 6f 5f 63 61 63 68 65 5f 72 6d 28 70 61 74 68 2c o_cache_rm(path,
93c0: 20 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 appfs_get_fsuid
93d0: 28 29 29 3b 0a 0a 09 69 6e 74 65 72 70 20 3d 20 ());...interp =
93e0: 61 70 70 66 73 5f 54 63 6c 49 6e 74 65 72 70 28 appfs_TclInterp(
93f0: 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 70 20 3d );..if (interp =
9400: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 = NULL) {...retu
9410: 72 6e 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 rn(-EIO);..}...a
9420: 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c ppfs_call_libtcl
9430: 28 54 63 6c 5f 50 72 65 73 65 72 76 65 28 69 6e (Tcl_Preserve(in
9440: 74 65 72 70 29 3b 29 0a 0a 09 74 63 6c 5f 72 65 terp);)...tcl_re
9450: 74 20 3d 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 t = appfs_Tcl_Ev
9460: 61 6c 28 69 6e 74 65 72 70 2c 20 33 2c 20 22 3a al(interp, 3, ":
9470: 3a 61 70 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 :appfs::openpath
9480: 22 2c 20 70 61 74 68 2c 20 22 77 72 69 74 65 22 ", path, "write"
9490: 29 3b 0a 09 69 66 20 28 74 63 6c 5f 72 65 74 20 );..if (tcl_ret
94a0: 21 3d 20 54 43 4c 5f 4f 4b 29 20 7b 0a 09 09 41 != TCL_OK) {...A
94b0: 50 50 46 53 5f 44 45 42 55 47 28 22 3a 3a 61 70 PPFS_DEBUG("::ap
94c0: 70 66 73 3a 3a 6f 70 65 6e 70 61 74 68 28 25 73 pfs::openpath(%s
94d0: 2c 20 25 73 29 20 66 61 69 6c 65 64 2e 22 2c 20 , %s) failed.",
94e0: 70 61 74 68 2c 20 22 77 72 69 74 65 22 29 3b 0a path, "write");.
94f0: 09 09 61 70 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 ..appfs_call_lib
9500: 74 63 6c 28 0a 09 09 09 41 50 50 46 53 5f 44 45 tcl(....APPFS_DE
9510: 42 55 47 28 22 54 63 6c 20 45 72 72 6f 72 20 69 BUG("Tcl Error i
9520: 73 3a 20 25 73 22 2c 20 54 63 6c 5f 47 65 74 53 s: %s", Tcl_GetS
9530: 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e 74 65 tringResult(inte
9540: 72 70 29 29 3b 0a 09 09 29 0a 0a 09 09 61 70 70 rp));...)....app
9550: 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 54 fs_call_libtcl(T
9560: 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 72 cl_Release(inter
9570: 70 29 3b 29 0a 0a 09 09 72 65 74 75 72 6e 28 2d p);)....return(-
9580: 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 66 73 EIO);..}...appfs
9590: 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 _call_libtcl(...
95a0: 72 65 61 6c 5f 70 61 74 68 20 3d 20 54 63 6c 5f real_path = Tcl_
95b0: 47 65 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 GetStringResult(
95c0: 69 6e 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 interp);..)...ap
95d0: 70 66 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 pfs_call_libtcl(
95e0: 54 63 6c 5f 52 65 6c 65 61 73 65 28 69 6e 74 65 Tcl_Release(inte
95f0: 72 70 29 3b 29 0a 0a 09 69 66 20 28 72 65 61 6c rp);)...if (real
9600: 5f 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b _path == NULL) {
9610: 0a 09 09 72 65 74 75 72 6e 28 2d 45 49 4f 29 3b ...return(-EIO);
9620: 0a 09 7d 0a 0a 09 61 70 70 66 73 5f 73 69 6d 75 ..}...appfs_simu
9630: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 late_user_fs_ent
9640: 65 72 28 29 3b 0a 0a 09 63 68 6d 6f 64 5f 72 65 er();...chmod_re
9650: 74 20 3d 20 63 68 6d 6f 64 28 72 65 61 6c 5f 70 t = chmod(real_p
9660: 61 74 68 2c 20 6d 6f 64 65 29 3b 0a 0a 09 61 70 ath, mode);...ap
9670: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 pfs_simulate_use
9680: 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 r_fs_leave();...
9690: 72 65 74 75 72 6e 28 63 68 6d 6f 64 5f 72 65 74 return(chmod_ret
96a0: 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 );.}..static int
96b0: 20 61 70 70 66 73 5f 66 75 73 65 5f 73 79 6d 6c appfs_fuse_syml
96c0: 69 6e 6b 28 63 6f 6e 73 74 20 63 68 61 72 20 2a ink(const char *
96d0: 6f 6c 64 70 61 74 68 2c 20 63 6f 6e 73 74 20 63 oldpath, const c
96e0: 68 61 72 20 2a 6e 65 77 70 61 74 68 29 20 7b 0a har *newpath) {.
96f0: 09 63 68 61 72 20 2a 72 65 61 6c 5f 70 61 74 68 .char *real_path
9700: 3b 0a 09 69 6e 74 20 73 79 6d 6c 69 6e 6b 5f 72 ;..int symlink_r
9710: 65 74 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 et;...APPFS_DEBU
9720: 47 28 22 45 6e 74 65 72 20 28 70 61 74 68 20 3d G("Enter (path =
9730: 20 25 73 2c 20 25 73 29 22 2c 20 6f 6c 64 70 61 %s, %s)", oldpa
9740: 74 68 2c 20 6e 65 77 70 61 74 68 29 3b 0a 0a 09 th, newpath);...
9750: 72 65 61 6c 5f 70 61 74 68 20 3d 20 61 70 70 66 real_path = appf
9760: 73 5f 70 72 65 70 61 72 65 5f 74 6f 5f 63 72 65 s_prepare_to_cre
9770: 61 74 65 28 6e 65 77 70 61 74 68 29 3b 0a 09 69 ate(newpath);..i
9780: 66 20 28 72 65 61 6c 5f 70 61 74 68 20 3d 3d 20 f (real_path ==
9790: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e NULL) {...return
97a0: 28 2d 45 49 4f 29 3b 0a 09 7d 0a 0a 09 61 70 70 (-EIO);..}...app
97b0: 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 fs_simulate_user
97c0: 5f 66 73 5f 65 6e 74 65 72 28 29 3b 0a 0a 09 73 _fs_enter();...s
97d0: 79 6d 6c 69 6e 6b 5f 72 65 74 20 3d 20 73 79 6d ymlink_ret = sym
97e0: 6c 69 6e 6b 28 6f 6c 64 70 61 74 68 2c 20 72 65 link(oldpath, re
97f0: 61 6c 5f 70 61 74 68 29 3b 0a 0a 09 61 70 70 66 al_path);...appf
9800: 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f s_simulate_user_
9810: 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 66 72 fs_leave();...fr
9820: 65 65 28 72 65 61 6c 5f 70 61 74 68 29 3b 0a 0a ee(real_path);..
9830: 09 69 66 20 28 73 79 6d 6c 69 6e 6b 5f 72 65 74 .if (symlink_ret
9840: 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 != 0) {...retur
9850: 6e 28 65 72 72 6e 6f 20 2a 20 2d 31 29 3b 0a 09 n(errno * -1);..
9860: 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d }...return(0);.}
9870: 0a 0a 2f 2a 0a 20 2a 20 53 51 4c 69 74 65 33 20 ../*. * SQLite3
9880: 6d 6f 64 65 3a 20 45 78 65 63 75 74 65 20 72 61 mode: Execute ra
9890: 77 20 53 51 4c 20 61 6e 64 20 72 65 74 75 72 6e w SQL and return
98a0: 20 73 75 63 63 65 73 73 20 6f 72 20 66 61 69 6c success or fail
98b0: 75 72 65 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 ure. */.static i
98c0: 6e 74 20 61 70 70 66 73 5f 73 71 6c 69 74 65 33 nt appfs_sqlite3
98d0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 73 71 6c (const char *sql
98e0: 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 20 ) {..Tcl_Interp
98f0: 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 20 *interp;..const
9900: 63 68 61 72 20 2a 73 71 6c 5f 72 65 74 3b 0a 09 char *sql_ret;..
9910: 69 6e 74 20 74 63 6c 5f 72 65 74 3b 0a 0a 09 69 int tcl_ret;...i
9920: 6e 74 65 72 70 20 3d 20 61 70 70 66 73 5f 63 72 nterp = appfs_cr
9930: 65 61 74 65 5f 54 63 6c 49 6e 74 65 72 70 28 4e eate_TclInterp(N
9940: 55 4c 4c 29 3b 0a 09 69 66 20 28 69 6e 74 65 72 ULL);..if (inter
9950: 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 p == NULL) {...f
9960: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 printf(stderr, "
9970: 55 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 Unable to create
9980: 20 61 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 a Tcl interpret
9990: 65 72 2e 20 20 41 62 6f 72 74 69 6e 67 2e 5c 6e er. Aborting.\n
99a0: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 ");....return(1)
99b0: 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 65 74 20 3d ;..}...tcl_ret =
99c0: 20 61 70 70 66 73 5f 54 63 6c 5f 45 76 61 6c 28 appfs_Tcl_Eval(
99d0: 69 6e 74 65 72 70 2c 20 35 2c 20 22 3a 3a 61 70 interp, 5, "::ap
99e0: 70 66 73 3a 3a 64 62 22 2c 20 22 65 76 61 6c 22 pfs::db", "eval"
99f0: 2c 20 73 71 6c 2c 20 22 72 6f 77 22 2c 20 22 75 , sql, "row", "u
9a00: 6e 73 65 74 20 2d 6e 6f 63 6f 6d 70 6c 61 69 6e nset -nocomplain
9a10: 20 72 6f 77 28 2a 29 3b 20 70 61 72 72 61 79 20 row(*); parray
9a20: 72 6f 77 3b 20 70 75 74 73 20 5c 22 2d 2d 2d 2d row; puts \"----
9a30: 5c 22 22 29 3b 0a 09 73 71 6c 5f 72 65 74 20 3d \"");..sql_ret =
9a40: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 52 65 Tcl_GetStringRe
9a50: 73 75 6c 74 28 69 6e 74 65 72 70 29 3b 0a 0a 09 sult(interp);...
9a60: 69 66 20 28 74 63 6c 5f 72 65 74 20 21 3d 20 54 if (tcl_ret != T
9a70: 43 4c 5f 4f 4b 29 20 7b 0a 09 09 66 70 72 69 6e CL_OK) {...fprin
9a80: 74 66 28 73 74 64 65 72 72 2c 20 22 5b 65 72 72 tf(stderr, "[err
9a90: 6f 72 5d 20 25 73 5c 6e 22 2c 20 73 71 6c 5f 72 or] %s\n", sql_r
9aa0: 65 74 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 et);....return(1
9ab0: 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 73 71 6c 5f );..}...if (sql_
9ac0: 72 65 74 20 26 26 20 73 71 6c 5f 72 65 74 5b 30 ret && sql_ret[0
9ad0: 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09 70 ] != '\0') {...p
9ae0: 72 69 6e 74 66 28 22 25 73 5c 6e 22 2c 20 73 71 rintf("%s\n", sq
9af0: 6c 5f 72 65 74 29 3b 0a 09 7d 0a 0a 09 72 65 74 l_ret);..}...ret
9b00: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a urn(0);.}../*. *
9b10: 20 54 63 6c 20 6d 6f 64 65 3a 20 45 78 65 63 75 Tcl mode: Execu
9b20: 74 65 20 72 61 77 20 54 63 6c 20 61 6e 64 20 72 te raw Tcl and r
9b30: 65 74 75 72 6e 20 73 75 63 63 65 73 73 20 6f 72 eturn success or
9b40: 20 66 61 69 6c 75 72 65 0a 20 2a 2f 0a 73 74 61 failure. */.sta
9b50: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 74 63 tic int appfs_tc
9b60: 6c 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 63 l(const char *tc
9b70: 6c 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 65 72 70 l) {..Tcl_Interp
9b80: 20 2a 69 6e 74 65 72 70 3b 0a 09 63 6f 6e 73 74 *interp;..const
9b90: 20 63 68 61 72 20 2a 74 63 6c 5f 72 65 73 75 6c char *tcl_resul
9ba0: 74 3b 0a 09 69 6e 74 20 74 63 6c 5f 72 65 74 3b t;..int tcl_ret;
9bb0: 0a 0a 09 69 6e 74 65 72 70 20 3d 20 61 70 70 66 ...interp = appf
9bc0: 73 5f 63 72 65 61 74 65 5f 54 63 6c 49 6e 74 65 s_create_TclInte
9bd0: 72 70 28 4e 55 4c 4c 29 3b 0a 09 69 66 20 28 69 rp(NULL);..if (i
9be0: 6e 74 65 72 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b nterp == NULL) {
9bf0: 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 ...fprintf(stder
9c00: 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 63 72 r, "Unable to cr
9c10: 65 61 74 65 20 61 20 54 63 6c 20 69 6e 74 65 72 eate a Tcl inter
9c20: 70 72 65 74 65 72 2e 20 20 41 62 6f 72 74 69 6e preter. Abortin
9c30: 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72 g.\n");....retur
9c40: 6e 28 31 29 3b 0a 09 7d 0a 0a 09 74 63 6c 5f 72 n(1);..}...tcl_r
9c50: 65 74 20 3d 20 54 63 6c 5f 45 76 61 6c 28 69 6e et = Tcl_Eval(in
9c60: 74 65 72 70 2c 20 74 63 6c 29 3b 0a 09 74 63 6c terp, tcl);..tcl
9c70: 5f 72 65 73 75 6c 74 20 3d 20 54 63 6c 5f 47 65 _result = Tcl_Ge
9c80: 74 53 74 72 69 6e 67 52 65 73 75 6c 74 28 69 6e tStringResult(in
9c90: 74 65 72 70 29 3b 0a 0a 09 69 66 20 28 74 63 6c terp);...if (tcl
9ca0: 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 20 _ret != TCL_OK)
9cb0: 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 {...fprintf(stde
9cc0: 72 72 2c 20 22 5b 65 72 72 6f 72 5d 20 25 73 5c rr, "[error] %s\
9cd0: 6e 22 2c 20 54 63 6c 5f 47 65 74 56 61 72 28 69 n", Tcl_GetVar(i
9ce0: 6e 74 65 72 70 2c 20 22 65 72 72 6f 72 49 6e 66 nterp, "errorInf
9cf0: 6f 22 2c 20 54 43 4c 5f 47 4c 4f 42 41 4c 5f 4f o", TCL_GLOBAL_O
9d00: 4e 4c 59 29 29 3b 0a 0a 09 09 72 65 74 75 72 6e NLY));....return
9d10: 28 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 74 63 (1);..}...if (tc
9d20: 6c 5f 72 65 73 75 6c 74 20 26 26 20 74 63 6c 5f l_result && tcl_
9d30: 72 65 73 75 6c 74 5b 30 5d 20 21 3d 20 27 5c 30 result[0] != '\0
9d40: 27 29 20 7b 0a 09 09 70 72 69 6e 74 66 28 22 25 ') {...printf("%
9d50: 73 5c 6e 22 2c 20 74 63 6c 5f 72 65 73 75 6c 74 s\n", tcl_result
9d60: 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 );..}...return(0
9d70: 29 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 41 70 70 46 );.}../*. * AppF
9d80: 53 64 20 50 61 63 6b 61 67 65 20 66 6f 72 20 54 Sd Package for T
9d90: 63 6c 3a 0a 20 2a 20 20 20 20 20 20 20 20 20 42 cl:. * B
9da0: 72 69 64 67 65 20 66 6f 72 20 49 2f 4f 20 6f 70 ridge for I/O op
9db0: 65 72 61 74 69 6f 6e 73 20 74 6f 20 72 65 71 75 erations to requ
9dc0: 65 73 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 est information
9dd0: 61 62 6f 75 74 20 74 68 65 20 63 75 72 72 65 6e about the curren
9de0: 74 0a 20 2a 20 20 20 20 20 20 20 20 20 74 72 61 t. * tra
9df0: 6e 73 61 63 74 69 6f 6e 0a 20 2a 2f 0a 2f 2a 0a nsaction. */./*.
9e00: 20 2a 20 54 63 6c 20 69 6e 74 65 72 66 61 63 65 * Tcl interface
9e10: 20 74 6f 20 67 65 74 20 74 68 65 20 68 6f 6d 65 to get the home
9e20: 20 64 69 72 65 63 74 6f 72 79 20 66 6f 72 20 74 directory for t
9e30: 68 65 20 75 73 65 72 20 6d 61 6b 69 6e 67 20 74 he user making t
9e40: 68 65 20 22 63 75 72 72 65 6e 74 22 0a 20 2a 20 he "current". *
9e50: 46 55 53 45 20 49 2f 4f 20 72 65 71 75 65 73 74 FUSE I/O request
9e60: 0a 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 . */.static int
9e70: 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f tcl_appfs_get_ho
9e80: 6d 65 64 69 72 28 43 6c 69 65 6e 74 44 61 74 61 medir(ClientData
9e90: 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 cd, Tcl_Interp
9ea0: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a *interp, int obj
9eb0: 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 c, Tcl_Obj *CONS
9ec0: 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 63 68 61 T objv[]) {..cha
9ed0: 72 20 2a 68 6f 6d 65 64 69 72 3b 0a 09 54 63 6c r *homedir;..Tcl
9ee0: 5f 4f 62 6a 20 2a 68 6f 6d 65 64 69 72 5f 6f 62 _Obj *homedir_ob
9ef0: 6a 3b 0a 09 75 69 64 5f 74 20 66 73 75 69 64 3b j;..uid_t fsuid;
9f00: 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 72 65 61 ..static __threa
9f10: 64 20 54 63 6c 5f 4f 62 6a 20 2a 6c 61 73 74 5f d Tcl_Obj *last_
9f20: 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 4e 55 homedir_obj = NU
9f30: 4c 4c 3b 0a 09 73 74 61 74 69 63 20 5f 5f 74 68 LL;..static __th
9f40: 72 65 61 64 20 75 69 64 5f 74 20 6c 61 73 74 5f read uid_t last_
9f50: 66 73 75 69 64 20 3d 20 2d 31 3b 0a 0a 20 20 20 fsuid = -1;..
9f60: 20 20 20 20 20 69 66 20 28 6f 62 6a 63 20 21 3d if (objc !=
9f70: 20 31 29 20 7b 0a 20 20 20 20 20 20 20 20 20 20 1) {.
9f80: 20 20 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e Tcl_WrongN
9f90: 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 umArgs(interp, 1
9fa0: 2c 20 6f 62 6a 76 2c 20 4e 55 4c 4c 29 3b 0a 20 , objv, NULL);.
9fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72 r
9fc0: 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 eturn(TCL_ERROR)
9fd0: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 0a 09 66 73 ;. }...fs
9fe0: 75 69 64 20 3d 20 61 70 70 66 73 5f 67 65 74 5f uid = appfs_get_
9ff0: 66 73 75 69 64 28 29 3b 0a 0a 09 69 66 20 28 66 fsuid();...if (f
a000: 73 75 69 64 20 3d 3d 20 6c 61 73 74 5f 66 73 75 suid == last_fsu
a010: 69 64 20 26 26 20 6c 61 73 74 5f 68 6f 6d 65 64 id && last_homed
a020: 69 72 5f 6f 62 6a 20 21 3d 20 4e 55 4c 4c 29 20 ir_obj != NULL)
a030: 7b 0a 09 09 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 {...homedir_obj
a040: 3d 20 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f = last_homedir_o
a050: 62 6a 3b 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52 bj;....Tcl_IncrR
a060: 65 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f efCount(homedir_
a070: 6f 62 6a 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a obj);..} else {.
a080: 09 09 68 6f 6d 65 64 69 72 20 3d 20 61 70 70 66 ..homedir = appf
a090: 73 5f 67 65 74 5f 68 6f 6d 65 64 69 72 28 61 70 s_get_homedir(ap
a0a0: 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 29 29 pfs_get_fsuid())
a0b0: 3b 0a 0a 09 09 69 66 20 28 68 6f 6d 65 64 69 72 ;....if (homedir
a0c0: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 72 == NULL) {....r
a0d0: 65 74 75 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 eturn(TCL_ERROR)
a0e0: 3b 0a 09 09 7d 0a 0a 09 09 68 6f 6d 65 64 69 72 ;...}....homedir
a0f0: 5f 6f 62 6a 20 3d 20 54 63 6c 5f 4e 65 77 53 74 _obj = Tcl_NewSt
a100: 72 69 6e 67 4f 62 6a 28 68 6f 6d 65 64 69 72 2c ringObj(homedir,
a110: 20 2d 31 29 3b 0a 0a 09 09 66 72 65 65 28 68 6f -1);....free(ho
a120: 6d 65 64 69 72 29 3b 0a 0a 09 09 54 63 6c 5f 49 medir);....Tcl_I
a130: 6e 63 72 52 65 66 43 6f 75 6e 74 28 68 6f 6d 65 ncrRefCount(home
a140: 64 69 72 5f 6f 62 6a 29 3b 0a 0a 09 09 69 66 20 dir_obj);....if
a150: 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 (last_homedir_ob
a160: 6a 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 j != NULL) {....
a170: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 Tcl_DecrRefCount
a180: 28 6c 61 73 74 5f 68 6f 6d 65 64 69 72 5f 6f 62 (last_homedir_ob
a190: 6a 29 3b 0a 09 09 7d 0a 0a 09 09 6c 61 73 74 5f j);...}....last_
a1a0: 68 6f 6d 65 64 69 72 5f 6f 62 6a 20 3d 20 68 6f homedir_obj = ho
a1b0: 6d 65 64 69 72 5f 6f 62 6a 3b 0a 09 09 6c 61 73 medir_obj;...las
a1c0: 74 5f 66 73 75 69 64 20 3d 20 66 73 75 69 64 3b t_fsuid = fsuid;
a1d0: 0a 0a 09 09 54 63 6c 5f 49 6e 63 72 52 65 66 43 ....Tcl_IncrRefC
a1e0: 6f 75 6e 74 28 68 6f 6d 65 64 69 72 5f 6f 62 6a ount(homedir_obj
a1f0: 29 3b 0a 09 7d 0a 0a 20 20 20 20 20 20 20 09 54 );..}.. .T
a200: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 cl_SetObjResult(
a210: 69 6e 74 65 72 70 2c 20 68 6f 6d 65 64 69 72 5f interp, homedir_
a220: 6f 62 6a 29 3b 0a 0a 09 54 63 6c 5f 44 65 63 72 obj);...Tcl_Decr
a230: 52 65 66 43 6f 75 6e 74 28 68 6f 6d 65 64 69 72 RefCount(homedir
a240: 5f 6f 62 6a 29 3b 0a 0a 20 20 20 20 20 20 20 20 _obj);..
a250: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a return(TCL_OK);.
a260: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 }..static int tc
a270: 6c 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 l_appfs_simulate
a280: 5f 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 28 43 _user_fs_enter(C
a290: 6c 69 65 6e 74 44 61 74 61 20 63 64 2c 20 54 63 lientData cd, Tc
a2a0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 l_Interp *interp
a2b0: 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 63 6c 5f , int objc, Tcl_
a2c0: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b Obj *CONST objv[
a2d0: 5d 29 20 7b 0a 09 61 70 70 66 73 5f 73 69 6d 75 ]) {..appfs_simu
a2e0: 6c 61 74 65 5f 75 73 65 72 5f 66 73 5f 65 6e 74 late_user_fs_ent
a2f0: 65 72 28 29 3b 0a 0a 09 72 65 74 75 72 6e 28 54 er();...return(T
a300: 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 CL_OK);.}..stati
a310: 63 20 69 6e 74 20 74 63 6c 5f 61 70 70 66 73 5f c int tcl_appfs_
a320: 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 5f 66 73 simulate_user_fs
a330: 5f 6c 65 61 76 65 28 43 6c 69 65 6e 74 44 61 74 _leave(ClientDat
a340: 61 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 a cd, Tcl_Interp
a350: 20 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 *interp, int ob
a360: 6a 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e jc, Tcl_Obj *CON
a370: 53 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 61 70 ST objv[]) {..ap
a380: 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 73 65 pfs_simulate_use
a390: 72 5f 66 73 5f 6c 65 61 76 65 28 29 3b 0a 0a 09 r_fs_leave();...
a3a0: 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a return(TCL_OK);.
a3b0: 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 74 63 }..static int tc
a3c0: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 l_appfs_get_fsui
a3d0: 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63 64 2c d(ClientData cd,
a3e0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 Tcl_Interp *int
a3f0: 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c 20 54 erp, int objc, T
a400: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 cl_Obj *CONST ob
a410: 6a 76 5b 5d 29 20 7b 0a 09 75 69 64 5f 74 20 66 jv[]) {..uid_t f
a420: 73 75 69 64 3b 0a 0a 09 66 73 75 69 64 20 3d 20 suid;...fsuid =
a430: 61 70 70 66 73 5f 67 65 74 5f 66 73 75 69 64 28 appfs_get_fsuid(
a440: 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 6c 5f );.. .Tcl_
a450: 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 SetObjResult(int
a460: 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65 erp, Tcl_NewWide
a470: 49 6e 74 4f 62 6a 28 66 73 75 69 64 29 29 3b 0a IntObj(fsuid));.
a480: 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 ..return(TCL_OK)
a490: 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 ;.}..static int
a4a0: 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 66 73 tcl_appfs_get_fs
a4b0: 67 69 64 28 43 6c 69 65 6e 74 44 61 74 61 20 63 gid(ClientData c
a4c0: 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 d, Tcl_Interp *i
a4d0: 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a 63 2c nterp, int objc,
a4e0: 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 Tcl_Obj *CONST
a4f0: 6f 62 6a 76 5b 5d 29 20 7b 0a 09 67 69 64 5f 74 objv[]) {..gid_t
a500: 20 66 73 67 69 64 3b 0a 0a 09 66 73 67 69 64 20 fsgid;...fsgid
a510: 3d 20 61 70 70 66 73 5f 67 65 74 5f 66 73 67 69 = appfs_get_fsgi
a520: 64 28 29 3b 0a 0a 20 20 20 20 20 20 20 09 54 63 d();.. .Tc
a530: 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 l_SetObjResult(i
a540: 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 nterp, Tcl_NewWi
a550: 64 65 49 6e 74 4f 62 6a 28 66 73 67 69 64 29 29 deIntObj(fsgid))
a560: 3b 0a 0a 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f ;...return(TCL_O
a570: 4b 29 3b 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e K);.}..static in
a580: 74 20 74 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f t tcl_appfs_get_
a590: 70 61 74 68 5f 69 6e 66 6f 5f 63 61 63 68 65 5f path_info_cache_
a5a0: 66 6c 75 73 68 28 43 6c 69 65 6e 74 44 61 74 61 flush(ClientData
a5b0: 20 63 64 2c 20 54 63 6c 5f 49 6e 74 65 72 70 20 cd, Tcl_Interp
a5c0: 2a 69 6e 74 65 72 70 2c 20 69 6e 74 20 6f 62 6a *interp, int obj
a5d0: 63 2c 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 c, Tcl_Obj *CONS
a5e0: 54 20 6f 62 6a 76 5b 5d 29 20 7b 0a 09 69 6e 74 T objv[]) {..int
a5f0: 20 74 63 6c 5f 72 65 74 3b 0a 09 69 6e 74 20 6e tcl_ret;..int n
a600: 65 77 5f 73 69 7a 65 3b 0a 0a 09 6e 65 77 5f 73 ew_size;...new_s
a610: 69 7a 65 20 3d 20 2d 31 3b 0a 0a 09 69 66 20 28 ize = -1;...if (
a620: 6f 62 6a 63 20 3d 3d 20 32 29 20 7b 0a 09 09 74 objc == 2) {...t
a630: 63 6c 5f 72 65 74 20 3d 20 54 63 6c 5f 47 65 74 cl_ret = Tcl_Get
a640: 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 IntFromObj(inter
a650: 70 2c 20 6f 62 6a 76 5b 31 5d 2c 20 26 6e 65 77 p, objv[1], &new
a660: 5f 73 69 7a 65 29 3b 0a 09 09 69 66 20 28 74 63 _size);...if (tc
a670: 6c 5f 72 65 74 20 21 3d 20 54 43 4c 5f 4f 4b 29 l_ret != TCL_OK)
a680: 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 74 63 6c {....return(tcl
a690: 5f 72 65 74 29 3b 0a 09 09 7d 0a 09 7d 20 65 6c _ret);...}..} el
a6a0: 73 65 20 69 66 20 28 6f 62 6a 63 20 3e 20 32 20 se if (objc > 2
a6b0: 7c 7c 20 6f 62 6a 63 20 3c 20 31 29 20 7b 0a 20 || objc < 1) {.
a6c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 T
a6d0: 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 cl_WrongNumArgs(
a6e0: 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c interp, 1, objv,
a6f0: 20 22 3f 6e 65 77 5f 63 61 63 68 65 5f 73 69 7a "?new_cache_siz
a700: 65 3f 22 29 3b 0a 09 09 72 65 74 75 72 6e 28 54 e?");...return(T
a710: 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 7d 0a 0a 09 CL_ERROR);..}...
a720: 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 appfs_get_path_i
a730: 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 nfo_cache_flush(
a740: 2d 31 2c 20 6e 65 77 5f 73 69 7a 65 29 3b 0a 0a -1, new_size);..
a750: 09 72 65 74 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b .return(TCL_OK);
a760: 0a 7d 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 41 .}..static int A
a770: 70 70 66 73 64 5f 49 6e 69 74 28 54 63 6c 5f 49 ppfsd_Init(Tcl_I
a780: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29 20 7b nterp *interp) {
a790: 0a 23 69 66 64 65 66 20 55 53 45 5f 54 43 4c 5f .#ifdef USE_TCL_
a7a0: 53 54 55 42 53 0a 09 69 66 20 28 54 63 6c 5f 49 STUBS..if (Tcl_I
a7b0: 6e 69 74 53 74 75 62 73 28 69 6e 74 65 72 70 2c nitStubs(interp,
a7c0: 20 54 43 4c 5f 56 45 52 53 49 4f 4e 2c 20 30 29 TCL_VERSION, 0)
a7d0: 20 3d 3d 20 30 4c 29 20 7b 0a 09 09 72 65 74 75 == 0L) {...retu
a7e0: 72 6e 28 54 43 4c 5f 45 52 52 4f 52 29 3b 0a 09 rn(TCL_ERROR);..
a7f0: 7d 0a 23 65 6e 64 69 66 0a 0a 09 54 63 6c 5f 43 }.#endif...Tcl_C
a800: 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 reateObjCommand(
a810: 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a interp, "appfsd:
a820: 3a 67 65 74 5f 68 6f 6d 65 64 69 72 22 2c 20 74 :get_homedir", t
a830: 63 6c 5f 61 70 70 66 73 5f 67 65 74 5f 68 6f 6d cl_appfs_get_hom
a840: 65 64 69 72 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c edir, NULL, NULL
a850: 29 3b 0a 09 54 63 6c 5f 43 72 65 61 74 65 4f 62 );..Tcl_CreateOb
a860: 6a 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c jCommand(interp,
a870: 20 22 61 70 70 66 73 64 3a 3a 67 65 74 5f 66 73 "appfsd::get_fs
a880: 75 69 64 22 2c 20 74 63 6c 5f 61 70 70 66 73 5f uid", tcl_appfs_
a890: 67 65 74 5f 66 73 75 69 64 2c 20 4e 55 4c 4c 2c get_fsuid, NULL,
a8a0: 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f 43 72 65 NULL);..Tcl_Cre
a8b0: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e ateObjCommand(in
a8c0: 74 65 72 70 2c 20 22 61 70 70 66 73 64 3a 3a 67 terp, "appfsd::g
a8d0: 65 74 5f 66 73 67 69 64 22 2c 20 74 63 6c 5f 61 et_fsgid", tcl_a
a8e0: 70 70 66 73 5f 67 65 74 5f 66 73 67 69 64 2c 20 ppfs_get_fsgid,
a8f0: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 NULL, NULL);..Tc
a900: 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 l_CreateObjComma
a910: 6e 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 nd(interp, "appf
a920: 73 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65 sd::simulate_use
a930: 72 5f 66 73 5f 65 6e 74 65 72 22 2c 20 74 63 6c r_fs_enter", tcl
a940: 5f 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f _appfs_simulate_
a950: 75 73 65 72 5f 66 73 5f 65 6e 74 65 72 2c 20 4e user_fs_enter, N
a960: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c ULL, NULL);..Tcl
a970: 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e _CreateObjComman
a980: 64 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 d(interp, "appfs
a990: 64 3a 3a 73 69 6d 75 6c 61 74 65 5f 75 73 65 72 d::simulate_user
a9a0: 5f 66 73 5f 6c 65 61 76 65 22 2c 20 74 63 6c 5f _fs_leave", tcl_
a9b0: 61 70 70 66 73 5f 73 69 6d 75 6c 61 74 65 5f 75 appfs_simulate_u
a9c0: 73 65 72 5f 66 73 5f 6c 65 61 76 65 2c 20 4e 55 ser_fs_leave, NU
a9d0: 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 54 63 6c 5f LL, NULL);..Tcl_
a9e0: 43 72 65 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 CreateObjCommand
a9f0: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 (interp, "appfsd
aa00: 3a 3a 67 65 74 5f 70 61 74 68 5f 69 6e 66 6f 5f ::get_path_info_
aa10: 63 61 63 68 65 5f 66 6c 75 73 68 22 2c 20 74 63 cache_flush", tc
aa20: 6c 5f 61 70 70 66 73 5f 67 65 74 5f 70 61 74 68 l_appfs_get_path
aa30: 5f 69 6e 66 6f 5f 63 61 63 68 65 5f 66 6c 75 73 _info_cache_flus
aa40: 68 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a h, NULL, NULL);.
aa50: 0a 09 54 63 6c 5f 50 6b 67 50 72 6f 76 69 64 65 ..Tcl_PkgProvide
aa60: 28 69 6e 74 65 72 70 2c 20 22 61 70 70 66 73 64 (interp, "appfsd
aa70: 22 2c 20 22 31 2e 30 22 29 3b 0a 0a 09 72 65 74 ", "1.0");...ret
aa80: 75 72 6e 28 54 43 4c 5f 4f 4b 29 3b 0a 7d 0a 0a urn(TCL_OK);.}..
aa90: 2f 2a 0a 20 2a 20 48 6f 74 2d 72 65 73 74 61 72 /*. * Hot-restar
aaa0: 74 20 73 75 70 70 6f 72 74 0a 20 2a 2f 0a 2f 2a t support. */./*
aab0: 20 49 6e 69 74 69 61 74 65 20 61 20 68 6f 74 2d Initiate a hot-
aac0: 72 65 73 74 61 72 74 20 2a 2f 0a 73 74 61 74 69 restart */.stati
aad0: 63 20 76 6f 69 64 20 61 70 70 66 73 5f 68 6f 74 c void appfs_hot
aae0: 5f 72 65 73 74 61 72 74 28 76 6f 69 64 29 20 7b _restart(void) {
aaf0: 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 41 ..APPFS_DEBUG("A
ab00: 73 6b 65 64 20 74 6f 20 69 6e 69 74 69 61 74 65 sked to initiate
ab10: 20 68 6f 74 20 72 65 73 74 61 72 74 22 29 3b 0a hot restart");.
ab20: 0a 09 61 70 70 66 73 5f 74 63 6c 5f 52 65 73 65 ..appfs_tcl_Rese
ab30: 74 49 6e 74 65 72 70 73 28 29 3b 0a 0a 09 61 70 tInterps();...ap
ab40: 70 66 73 5f 67 65 74 5f 70 61 74 68 5f 69 6e 66 pfs_get_path_inf
ab50: 6f 5f 63 61 63 68 65 5f 66 6c 75 73 68 28 2d 31 o_cache_flush(-1
ab60: 2c 20 2d 31 29 3b 0a 0a 09 72 65 74 75 72 6e 3b , -1);...return;
ab70: 0a 7d 0a 0a 2f 2a 0a 20 2a 20 53 69 67 6e 61 6c .}../*. * Signal
ab80: 20 68 61 6e 64 6c 65 72 0a 20 2a 20 20 20 20 20 handler. *
ab90: 20 20 20 20 53 49 47 48 55 50 20 69 6e 69 74 69 SIGHUP initi
aba0: 61 74 65 73 20 61 20 68 6f 74 20 72 65 73 74 61 ates a hot resta
abb0: 72 74 0a 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f rt. */.static vo
abc0: 69 64 20 61 70 70 66 73 5f 73 69 67 6e 61 6c 5f id appfs_signal_
abd0: 68 61 6e 64 6c 65 72 28 69 6e 74 20 73 69 67 29 handler(int sig)
abe0: 20 7b 0a 09 2f 2a 20 44 6f 20 6e 6f 74 20 68 61 {../* Do not ha
abf0: 6e 64 6c 65 20 73 69 67 6e 61 6c 73 20 75 6e 74 ndle signals unt
ac00: 69 6c 20 46 55 53 45 20 68 61 73 20 62 65 65 6e il FUSE has been
ac10: 20 73 74 61 72 74 65 64 20 2a 2f 0a 09 69 66 20 started */..if
ac20: 28 21 61 70 70 66 73 5f 66 75 73 65 5f 73 74 61 (!appfs_fuse_sta
ac30: 72 74 65 64 29 20 7b 0a 09 09 72 65 74 75 72 6e rted) {...return
ac40: 3b 0a 09 7d 0a 0a 09 2f 2a 20 52 65 71 75 65 73 ;..}.../* Reques
ac50: 74 20 74 6f 20 70 65 72 66 6f 72 6d 20 61 20 22 t to perform a "
ac60: 68 6f 74 22 20 72 65 73 74 61 72 74 20 2a 2f 0a hot" restart */.
ac70: 09 69 66 20 28 73 69 67 20 3d 3d 20 53 49 47 48 .if (sig == SIGH
ac80: 55 50 29 20 7b 0a 09 09 61 70 70 66 73 5f 68 6f UP) {...appfs_ho
ac90: 74 5f 72 65 73 74 61 72 74 28 29 3b 0a 09 7d 0a t_restart();..}.
aca0: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 0a ..return;.}../*.
acb0: 20 2a 20 54 65 72 6d 69 6e 61 74 65 20 61 20 74 * Terminate a t
acc0: 68 72 65 61 64 0a 20 2a 2f 0a 73 74 61 74 69 63 hread. */.static
acd0: 20 76 6f 69 64 20 61 70 70 66 73 5f 74 65 72 6d void appfs_term
ace0: 69 6e 61 74 65 5f 69 6e 74 65 72 70 5f 61 6e 64 inate_interp_and
acf0: 5f 74 68 72 65 61 64 28 76 6f 69 64 20 2a 5f 69 _thread(void *_i
ad00: 6e 74 65 72 70 29 20 7b 0a 09 54 63 6c 5f 49 6e nterp) {..Tcl_In
ad10: 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 0a 0a 09 terp *interp;...
ad20: 41 50 50 46 53 5f 44 45 42 55 47 28 22 43 61 6c APPFS_DEBUG("Cal
ad30: 6c 65 64 3a 20 5f 69 6e 74 65 72 70 20 3d 20 25 led: _interp = %
ad40: 70 22 2c 20 5f 69 6e 74 65 72 70 29 3b 0a 0a 09 p", _interp);...
ad50: 69 66 20 28 5f 69 6e 74 65 72 70 20 3d 3d 20 4e if (_interp == N
ad60: 55 4c 4c 29 20 7b 0a 09 09 41 50 50 46 53 5f 44 ULL) {...APPFS_D
ad70: 45 42 55 47 28 22 54 65 72 6d 69 6e 61 74 69 6e EBUG("Terminatin
ad80: 67 20 74 68 72 65 61 64 20 77 69 74 68 20 6e 6f g thread with no
ad90: 20 69 6e 74 65 72 70 72 65 74 65 72 22 29 3b 0a interpreter");.
ada0: 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 ...return;..}...
adb0: 69 6e 74 65 72 70 20 3d 20 5f 69 6e 74 65 72 70 interp = _interp
adc0: 3b 0a 0a 09 41 50 50 46 53 5f 44 45 42 55 47 28 ;...APPFS_DEBUG(
add0: 22 54 65 72 6d 69 6e 61 74 69 6e 67 20 69 6e 74 "Terminating int
ade0: 65 72 70 72 65 74 65 72 20 64 75 65 20 74 6f 20 erpreter due to
adf0: 74 68 72 65 61 64 20 74 65 72 6d 69 6e 61 74 69 thread terminati
ae00: 6f 6e 22 29 3b 0a 0a 09 61 70 70 66 73 5f 63 61 on");...appfs_ca
ae10: 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 09 54 63 6c ll_libtcl(...Tcl
ae20: 5f 44 65 6c 65 74 65 49 6e 74 65 72 70 28 69 6e _DeleteInterp(in
ae30: 74 65 72 70 29 3b 0a 09 29 0a 0a 09 61 70 70 66 terp);..)...appf
ae40: 73 5f 63 61 6c 6c 5f 6c 69 62 74 63 6c 28 0a 09 s_call_libtcl(..
ae50: 09 54 63 6c 5f 46 69 6e 61 6c 69 7a 65 54 68 72 .Tcl_FinalizeThr
ae60: 65 61 64 28 29 3b 0a 09 29 0a 0a 09 72 65 74 75 ead();..)...retu
ae70: 72 6e 3b 0a 7d 0a 0a 2f 2a 0a 20 2a 20 43 6f 6d rn;.}../*. * Com
ae80: 6d 61 6e 64 2d 6c 69 6e 65 20 70 61 72 73 69 6e mand-line parsin
ae90: 67 20 74 6f 6f 6c 73 0a 20 2a 2f 0a 73 74 61 74 g tools. */.stat
aea0: 69 63 20 76 6f 69 64 20 61 70 70 66 73 5f 70 72 ic void appfs_pr
aeb0: 69 6e 74 5f 68 65 6c 70 28 46 49 4c 45 20 2a 63 int_help(FILE *c
aec0: 68 61 6e 6e 65 6c 29 20 7b 0a 09 66 70 72 69 6e hannel) {..fprin
aed0: 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 55 73 61 tf(channel, "Usa
aee0: 67 65 3a 20 7b 61 70 70 66 73 64 7c 6d 6f 75 6e ge: {appfsd|moun
aef0: 74 2e 61 70 70 66 73 7d 20 5b 2d 6f 20 3c 6f 70 t.appfs} [-o <op
af00: 74 69 6f 6e 3e 5d 20 5b 2d 64 66 73 68 5d 20 3c tion>] [-dfsh] <
af10: 63 61 63 68 65 64 69 72 3e 20 3c 6d 6f 75 6e 74 cachedir> <mount
af20: 70 6f 69 6e 74 3e 5c 6e 22 29 3b 0a 09 66 70 72 point>\n");..fpr
af30: 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 5c intf(channel, "\
af40: 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 n");..fprintf(ch
af50: 61 6e 6e 65 6c 2c 20 22 4f 70 74 69 6f 6e 73 3a annel, "Options:
af60: 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 \n");..fprintf(c
af70: 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 64 20 20 20 hannel, " -d
af80: 20 20 20 20 20 20 20 20 20 20 20 45 6e 61 62 6c Enabl
af90: 65 20 46 55 53 45 20 64 65 62 75 67 20 6d 6f 64 e FUSE debug mod
afa0: 65 2e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 e.\n");..fprintf
afb0: 28 63 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 66 20 (channel, " -f
afc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 52 75 6e Run
afd0: 20 69 6e 20 66 6f 72 65 67 72 6f 75 6e 64 2e 5c in foreground.\
afe0: 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 68 n");..fprintf(ch
aff0: 61 6e 6e 65 6c 2c 20 22 20 20 2d 73 20 20 20 20 annel, " -s
b000: 20 20 20 20 20 20 20 20 20 20 45 6e 61 62 6c 65 Enable
b010: 20 73 69 6e 67 6c 65 20 74 68 72 65 61 64 65 64 single threaded
b020: 20 6d 6f 64 65 2e 5c 6e 22 29 3b 0a 09 66 70 72 mode.\n");..fpr
b030: 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20 intf(channel, "
b040: 20 2d 68 20 20 20 20 20 20 20 20 20 20 20 20 20 -h
b050: 20 47 69 76 65 20 74 68 69 73 20 68 65 6c 70 2e Give this help.
b060: 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 63 \n");..fprintf(c
b070: 68 61 6e 6e 65 6c 2c 20 22 20 20 2d 6f 20 6e 6f hannel, " -o no
b080: 74 68 72 65 61 64 73 20 20 20 20 45 6e 61 62 6c threads Enabl
b090: 65 20 73 69 6e 67 6c 65 20 74 68 72 65 61 64 65 e single threade
b0a0: 64 20 6d 6f 64 65 2e 5c 6e 22 29 3b 0a 09 66 70 d mode.\n");..fp
b0b0: 72 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 rintf(channel, "
b0c0: 20 20 2d 6f 20 61 6c 6c 6f 77 5f 6f 74 68 65 72 -o allow_other
b0d0: 20 20 41 6c 6c 6f 77 20 6f 74 68 65 72 20 75 73 Allow other us
b0e0: 65 72 73 20 74 6f 20 61 63 63 65 73 73 20 74 68 ers to access th
b0f0: 69 73 20 6d 6f 75 6e 74 70 6f 69 6e 74 20 28 64 is mountpoint (d
b100: 65 66 61 75 6c 74 5c 6e 22 29 3b 0a 09 66 70 72 efault\n");..fpr
b110: 69 6e 74 66 28 63 68 61 6e 6e 65 6c 2c 20 22 20 intf(channel, "
b120: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
b130: 20 69 66 20 72 6f 6f 74 29 2e 5c 6e 22 29 3b 0a if root).\n");.
b140: 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 73 74 61 ..return;.}..sta
b150: 74 69 63 20 69 6e 74 20 61 70 70 66 73 5f 6f 70 tic int appfs_op
b160: 74 5f 70 61 72 73 65 28 69 6e 74 20 61 72 67 63 t_parse(int argc
b170: 2c 20 63 68 61 72 20 2a 2a 61 72 67 76 2c 20 20 , char **argv,
b180: 73 74 72 75 63 74 20 66 75 73 65 5f 61 72 67 73 struct fuse_args
b190: 20 2a 61 72 67 73 29 20 7b 0a 09 69 6e 74 20 63 *args) {..int c
b1a0: 68 3b 0a 09 63 68 61 72 20 2a 6f 70 74 73 74 72 h;..char *optstr
b1b0: 2c 20 2a 6f 70 74 73 74 72 5f 6e 65 78 74 2c 20 , *optstr_next,
b1c0: 2a 6f 70 74 73 74 72 5f 73 3b 0a 09 63 68 61 72 *optstr_s;..char
b1d0: 20 66 61 6b 65 5f 61 72 67 5b 33 5d 20 3d 20 7b fake_arg[3] = {
b1e0: 27 2d 27 2c 20 30 2c 20 30 7d 3b 0a 0a 09 2f 2a '-', 0, 0};.../*
b1f0: 0a 09 20 2a 20 44 65 66 61 75 6c 74 20 76 61 6c .. * Default val
b200: 75 65 73 0a 09 20 2a 2f 0a 23 69 66 64 65 66 20 ues.. */.#ifdef
b210: 54 43 4c 5f 54 48 52 45 41 44 53 0a 09 61 70 70 TCL_THREADS..app
b220: 66 73 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 20 fs_threaded_tcl
b230: 3d 20 31 3b 0a 23 65 6c 73 65 0a 09 61 70 70 66 = 1;.#else..appf
b240: 73 5f 74 68 72 65 61 64 65 64 5f 74 63 6c 20 3d s_threaded_tcl =
b250: 20 30 3b 0a 23 65 6e 64 69 66 0a 0a 09 2f 2a 2a 0;.#endif.../**
b260: 0a 09 20 2a 2a 20 41 64 64 20 46 55 53 45 20 61 .. ** Add FUSE a
b270: 72 67 75 6d 65 6e 74 73 20 77 68 69 63 68 20 77 rguments which w
b280: 65 20 61 6c 77 61 79 73 20 73 75 70 70 6c 79 0a e always supply.
b290: 09 20 2a 2a 2f 0a 09 66 75 73 65 5f 6f 70 74 5f . **/..fuse_opt_
b2a0: 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20 22 2d add_arg(args, "-
b2b0: 6f 64 65 66 61 75 6c 74 5f 70 65 72 6d 69 73 73 odefault_permiss
b2c0: 69 6f 6e 73 2c 66 73 6e 61 6d 65 3d 61 70 70 66 ions,fsname=appf
b2d0: 73 2c 73 75 62 74 79 70 65 3d 61 70 70 66 73 64 s,subtype=appfsd
b2e0: 2c 75 73 65 5f 69 6e 6f 2c 6b 65 72 6e 65 6c 5f ,use_ino,kernel_
b2f0: 63 61 63 68 65 2c 65 6e 74 72 79 5f 74 69 6d 65 cache,entry_time
b300: 6f 75 74 3d 30 2c 61 74 74 72 5f 74 69 6d 65 6f out=0,attr_timeo
b310: 75 74 3d 30 2c 62 69 67 5f 77 72 69 74 65 73 2c ut=0,big_writes,
b320: 69 6e 74 72 2c 68 61 72 64 5f 72 65 6d 6f 76 65 intr,hard_remove
b330: 22 29 3b 0a 0a 09 69 66 20 28 67 65 74 75 69 64 ");...if (getuid
b340: 28 29 20 3d 3d 20 30 29 20 7b 0a 09 09 66 75 73 () == 0) {...fus
b350: 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67 73 e_opt_parse(args
b360: 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 , NULL, NULL, NU
b370: 4c 4c 29 3b 0a 09 09 66 75 73 65 5f 6f 70 74 5f LL);...fuse_opt_
b380: 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20 22 2d add_arg(args, "-
b390: 6f 61 6c 6c 6f 77 5f 6f 74 68 65 72 22 29 3b 0a oallow_other");.
b3a0: 09 7d 0a 0a 09 77 68 69 6c 65 20 28 28 63 68 20 .}...while ((ch
b3b0: 3d 20 67 65 74 6f 70 74 28 61 72 67 63 2c 20 61 = getopt(argc, a
b3c0: 72 67 76 2c 20 22 64 66 73 68 6f 3a 22 29 29 20 rgv, "dfsho:"))
b3d0: 21 3d 20 2d 31 29 20 7b 0a 09 09 73 77 69 74 63 != -1) {...switc
b3e0: 68 20 28 63 68 29 20 7b 0a 09 09 09 63 61 73 65 h (ch) {....case
b3f0: 20 27 6f 27 3a 0a 09 09 09 09 6f 70 74 73 74 72 'o':.....optstr
b400: 5f 6e 65 78 74 20 3d 20 6f 70 74 73 74 72 20 3d _next = optstr =
b410: 20 6f 70 74 73 74 72 5f 73 20 3d 20 73 74 72 64 optstr_s = strd
b420: 75 70 28 6f 70 74 61 72 67 29 3b 0a 0a 09 09 09 up(optarg);.....
b430: 09 77 68 69 6c 65 20 28 31 29 20 7b 0a 09 09 09 .while (1) {....
b440: 09 09 6f 70 74 73 74 72 20 3d 20 6f 70 74 73 74 ..optstr = optst
b450: 72 5f 6e 65 78 74 3b 0a 0a 09 09 09 09 09 69 66 r_next;.......if
b460: 20 28 21 6f 70 74 73 74 72 29 20 7b 0a 09 09 09 (!optstr) {....
b470: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 09 7d ...break;......}
b480: 0a 0a 09 09 09 09 09 6f 70 74 73 74 72 5f 6e 65 .......optstr_ne
b490: 78 74 20 3d 20 73 74 72 63 68 72 28 6f 70 74 73 xt = strchr(opts
b4a0: 74 72 2c 20 27 2c 27 29 3b 0a 09 09 09 09 09 69 tr, ',');......i
b4b0: 66 20 28 6f 70 74 73 74 72 5f 6e 65 78 74 29 20 f (optstr_next)
b4c0: 7b 0a 09 09 09 09 09 09 2a 6f 70 74 73 74 72 5f {.......*optstr_
b4d0: 6e 65 78 74 20 3d 20 27 5c 30 27 3b 0a 09 09 09 next = '\0';....
b4e0: 09 09 09 6f 70 74 73 74 72 5f 6e 65 78 74 2b 2b ...optstr_next++
b4f0: 3b 0a 09 09 09 09 09 7d 0a 0a 09 09 09 09 09 69 ;......}.......i
b500: 66 20 28 73 74 72 63 6d 70 28 6f 70 74 73 74 72 f (strcmp(optstr
b510: 2c 20 22 6e 6f 74 68 72 65 61 64 73 22 29 20 3d , "nothreads") =
b520: 3d 20 30 29 20 7b 0a 09 09 09 09 09 09 41 50 50 = 0) {.......APP
b530: 46 53 5f 44 45 42 55 47 28 22 50 61 73 73 69 6e FS_DEBUG("Passin
b540: 67 20 6f 70 74 69 6f 6e 20 74 6f 20 46 55 53 45 g option to FUSE
b550: 3a 20 2d 73 22 29 3b 0a 0a 09 09 09 09 09 09 66 : -s");........f
b560: 75 73 65 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 use_opt_parse(ar
b570: 67 73 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 gs, NULL, NULL,
b580: 4e 55 4c 4c 29 3b 0a 09 09 09 09 09 09 66 75 73 NULL);.......fus
b590: 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 72 e_opt_add_arg(ar
b5a0: 67 73 2c 20 22 2d 73 22 29 3b 0a 0a 09 09 09 09 gs, "-s");......
b5b0: 09 09 61 70 70 66 73 5f 74 68 72 65 61 64 65 64 ..appfs_threaded
b5c0: 5f 74 63 6c 20 3d 20 30 3b 0a 09 09 09 09 09 7d _tcl = 0;......}
b5d0: 20 65 6c 73 65 20 69 66 20 28 73 74 72 63 6d 70 else if (strcmp
b5e0: 28 6f 70 74 73 74 72 2c 20 22 61 6c 6c 6f 77 5f (optstr, "allow_
b5f0: 6f 74 68 65 72 22 29 20 3d 3d 20 30 29 20 7b 0a other") == 0) {.
b600: 09 09 09 09 09 09 41 50 50 46 53 5f 44 45 42 55 ......APPFS_DEBU
b610: 47 28 22 50 61 73 73 69 6e 67 20 6f 70 74 69 6f G("Passing optio
b620: 6e 20 74 6f 20 46 55 53 45 3a 20 2d 6f 20 61 6c n to FUSE: -o al
b630: 6c 6f 77 5f 4f 74 68 65 72 22 29 3b 0a 0a 09 09 low_Other");....
b640: 09 09 09 09 66 75 73 65 5f 6f 70 74 5f 70 61 72 ....fuse_opt_par
b650: 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 4e se(args, NULL, N
b660: 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 09 09 09 ULL, NULL);.....
b670: 09 09 66 75 73 65 5f 6f 70 74 5f 61 64 64 5f 61 ..fuse_opt_add_a
b680: 72 67 28 61 72 67 73 2c 20 22 2d 6f 61 6c 6c 6f rg(args, "-oallo
b690: 77 5f 6f 74 68 65 72 22 29 3b 0a 09 09 09 09 09 w_other");......
b6a0: 7d 20 65 6c 73 65 20 69 66 20 28 73 74 72 63 6d } else if (strcm
b6b0: 70 28 6f 70 74 73 74 72 2c 20 22 72 77 22 29 20 p(optstr, "rw")
b6c0: 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09 09 2f 2a == 0) {......./*
b6d0: 20 49 67 6e 6f 72 65 64 20 2a 2f 0a 09 09 09 09 Ignored */.....
b6e0: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 09 09 .} else {.......
b6f0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 fprintf(stderr,
b700: 22 61 70 70 66 73 64 3a 20 69 6e 76 61 6c 69 64 "appfsd: invalid
b710: 20 6f 70 74 69 6f 6e 3a 20 5c 22 2d 6f 20 25 73 option: \"-o %s
b720: 5c 22 5c 6e 22 2c 20 6f 70 74 73 74 72 29 3b 0a \"\n", optstr);.
b730: 0a 09 09 09 09 09 09 66 72 65 65 28 6f 70 74 73 .......free(opts
b740: 74 72 5f 73 29 3b 0a 0a 09 09 09 09 09 09 72 65 tr_s);........re
b750: 74 75 72 6e 28 31 29 3b 0a 09 09 09 09 09 7d 0a turn(1);......}.
b760: 09 09 09 09 7d 0a 0a 09 09 09 09 66 72 65 65 28 ....}......free(
b770: 6f 70 74 73 74 72 5f 73 29 3b 0a 0a 09 09 09 09 optstr_s);......
b780: 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 break;....case '
b790: 64 27 3a 0a 09 09 09 63 61 73 65 20 27 66 27 3a d':....case 'f':
b7a0: 0a 09 09 09 63 61 73 65 20 27 73 27 3a 0a 09 09 ....case 's':...
b7b0: 09 09 69 66 20 28 63 68 20 3d 3d 20 27 73 27 29 ..if (ch == 's')
b7c0: 20 7b 0a 09 09 09 09 09 61 70 70 66 73 5f 74 68 {......appfs_th
b7d0: 72 65 61 64 65 64 5f 74 63 6c 20 3d 20 30 3b 0a readed_tcl = 0;.
b7e0: 09 09 09 09 7d 0a 0a 09 09 09 09 66 61 6b 65 5f ....}......fake_
b7f0: 61 72 67 5b 31 5d 20 3d 20 63 68 3b 0a 0a 09 09 arg[1] = ch;....
b800: 09 09 41 50 50 46 53 5f 44 45 42 55 47 28 22 50 ..APPFS_DEBUG("P
b810: 61 73 73 69 6e 67 20 6f 70 74 69 6f 6e 20 74 6f assing option to
b820: 20 46 55 53 45 3a 20 25 73 22 2c 20 66 61 6b 65 FUSE: %s", fake
b830: 5f 61 72 67 29 3b 0a 0a 09 09 09 09 66 75 73 65 _arg);......fuse
b840: 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67 73 2c _opt_parse(args,
b850: 20 4e 55 4c 4c 2c 20 4e 55 4c 4c 2c 20 4e 55 4c NULL, NULL, NUL
b860: 4c 29 3b 0a 09 09 09 09 66 75 73 65 5f 6f 70 74 L);.....fuse_opt
b870: 5f 61 64 64 5f 61 72 67 28 61 72 67 73 2c 20 66 _add_arg(args, f
b880: 61 6b 65 5f 61 72 67 29 3b 0a 09 09 09 09 62 72 ake_arg);.....br
b890: 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 68 27 eak;....case 'h'
b8a0: 3a 0a 09 09 09 09 61 70 70 66 73 5f 70 72 69 6e :.....appfs_prin
b8b0: 74 5f 68 65 6c 70 28 73 74 64 6f 75 74 29 3b 0a t_help(stdout);.
b8c0: 0a 09 09 09 09 72 65 74 75 72 6e 28 30 29 3b 0a .....return(0);.
b8d0: 09 09 09 63 61 73 65 20 27 3a 27 3a 0a 09 09 09 ...case ':':....
b8e0: 63 61 73 65 20 27 3f 27 3a 0a 09 09 09 64 65 66 case '?':....def
b8f0: 61 75 6c 74 3a 0a 09 09 09 09 61 70 70 66 73 5f ault:.....appfs_
b900: 70 72 69 6e 74 5f 68 65 6c 70 28 73 74 64 65 72 print_help(stder
b910: 72 29 3b 0a 0a 09 09 09 09 72 65 74 75 72 6e 28 r);......return(
b920: 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 69 66 20 1);...}..}...if
b930: 28 28 6f 70 74 69 6e 64 20 2b 20 32 29 20 21 3d ((optind + 2) !=
b940: 20 61 72 67 63 29 20 7b 0a 09 09 69 66 20 28 28 argc) {...if ((
b950: 6f 70 74 69 6e 64 20 2b 20 32 29 20 3c 20 61 72 optind + 2) < ar
b960: 67 63 29 20 7b 0a 09 09 09 66 70 72 69 6e 74 66 gc) {....fprintf
b970: 28 73 74 64 65 72 72 2c 20 22 54 6f 6f 20 6d 61 (stderr, "Too ma
b980: 6e 79 20 61 72 67 75 6d 65 6e 74 73 5c 6e 22 29 ny arguments\n")
b990: 3b 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 ;...} else {....
b9a0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 fprintf(stderr,
b9b0: 22 4d 69 73 73 69 6e 67 20 63 61 63 68 65 64 69 "Missing cachedi
b9c0: 72 20 6f 72 20 6d 6f 75 6e 74 70 6f 69 6e 74 5c r or mountpoint\
b9d0: 6e 22 29 3b 0a 09 09 7d 0a 0a 09 09 61 70 70 66 n");...}....appf
b9e0: 73 5f 70 72 69 6e 74 5f 68 65 6c 70 28 73 74 64 s_print_help(std
b9f0: 65 72 72 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 err);....return(
ba00: 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 1);..}.../*.. *
ba10: 53 65 74 20 63 61 63 68 65 20 64 69 72 20 61 73 Set cache dir as
ba20: 20 66 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 first argument
ba30: 28 74 68 65 20 22 64 65 76 69 63 65 22 2c 20 65 (the "device", e
ba40: 73 73 65 6e 74 69 61 6c 6c 79 29 0a 09 20 2a 2f ssentially).. */
ba50: 0a 09 61 70 70 66 73 5f 63 61 63 68 65 64 69 72 ..appfs_cachedir
ba60: 20 3d 20 61 72 67 76 5b 6f 70 74 69 6e 64 5d 3b = argv[optind];
ba70: 0a 0a 09 2f 2a 0a 09 20 2a 20 50 61 73 73 20 74 .../*.. * Pass t
ba80: 68 65 20 72 65 6d 61 69 6e 69 6e 67 20 61 72 67 he remaining arg
ba90: 75 6d 65 6e 74 20 74 6f 20 46 55 53 45 20 61 73 ument to FUSE as
baa0: 20 74 68 65 20 64 69 72 65 63 74 6f 72 79 0a 09 the directory..
bab0: 20 2a 2f 0a 09 66 75 73 65 5f 6f 70 74 5f 70 61 */..fuse_opt_pa
bac0: 72 73 65 28 61 72 67 73 2c 20 4e 55 4c 4c 2c 20 rse(args, NULL,
bad0: 4e 55 4c 4c 2c 20 4e 55 4c 4c 29 3b 0a 09 66 75 NULL, NULL);..fu
bae0: 73 65 5f 6f 70 74 5f 61 64 64 5f 61 72 67 28 61 se_opt_add_arg(a
baf0: 72 67 73 2c 20 61 72 67 76 5b 6f 70 74 69 6e 64 rgs, argv[optind
bb00: 20 2b 20 31 5d 29 3b 0a 0a 09 72 65 74 75 72 6e + 1]);...return
bb10: 28 30 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 20 2a 20 46 (0);.}.../*. * F
bb20: 55 53 45 20 6f 70 65 72 61 74 69 6f 6e 73 20 73 USE operations s
bb30: 74 72 75 63 74 75 72 65 0a 20 2a 2f 0a 73 74 61 tructure. */.sta
bb40: 74 69 63 20 73 74 72 75 63 74 20 66 75 73 65 5f tic struct fuse_
bb50: 6f 70 65 72 61 74 69 6f 6e 73 20 61 70 70 66 73 operations appfs
bb60: 5f 6f 70 65 72 61 74 69 6f 6e 73 20 3d 20 7b 0a _operations = {.
bb70: 09 2e 67 65 74 61 74 74 72 20 20 20 3d 20 61 70 ..getattr = ap
bb80: 70 66 73 5f 66 75 73 65 5f 67 65 74 61 74 74 72 pfs_fuse_getattr
bb90: 2c 0a 09 2e 72 65 61 64 64 69 72 20 20 20 3d 20 ,...readdir =
bba0: 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 64 64 appfs_fuse_readd
bbb0: 69 72 2c 0a 09 2e 72 65 61 64 6c 69 6e 6b 20 20 ir,...readlink
bbc0: 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72 65 61 = appfs_fuse_rea
bbd0: 64 6c 69 6e 6b 2c 0a 09 2e 6f 70 65 6e 20 20 20 dlink,...open
bbe0: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f = appfs_fuse_
bbf0: 6f 70 65 6e 2c 0a 09 2e 72 65 6c 65 61 73 65 20 open,...release
bc00: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 63 = appfs_fuse_c
bc10: 6c 6f 73 65 2c 0a 09 2e 72 65 61 64 20 20 20 20 lose,...read
bc20: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 72 = appfs_fuse_r
bc30: 65 61 64 2c 0a 09 2e 77 72 69 74 65 20 20 20 20 ead,...write
bc40: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 77 72 = appfs_fuse_wr
bc50: 69 74 65 2c 0a 09 2e 6d 6b 6e 6f 64 20 20 20 20 ite,...mknod
bc60: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 6d 6b = appfs_fuse_mk
bc70: 6e 6f 64 2c 0a 09 2e 63 72 65 61 74 65 20 20 20 nod,...create
bc80: 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 63 72 = appfs_fuse_cr
bc90: 65 61 74 65 2c 0a 09 2e 74 72 75 6e 63 61 74 65 eate,...truncate
bca0: 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f 74 = appfs_fuse_t
bcb0: 72 75 6e 63 61 74 65 2c 0a 09 2e 75 6e 6c 69 6e runcate,...unlin
bcc0: 6b 20 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 k = appfs_fus
bcd0: 65 5f 75 6e 6c 69 6e 6b 5f 72 6d 64 69 72 2c 0a e_unlink_rmdir,.
bce0: 09 2e 72 6d 64 69 72 20 20 20 20 20 3d 20 61 70 ..rmdir = ap
bcf0: 70 66 73 5f 66 75 73 65 5f 75 6e 6c 69 6e 6b 5f pfs_fuse_unlink_
bd00: 72 6d 64 69 72 2c 0a 09 2e 6d 6b 64 69 72 20 20 rmdir,...mkdir
bd10: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f = appfs_fuse_
bd20: 6d 6b 64 69 72 2c 0a 09 2e 63 68 6d 6f 64 20 20 mkdir,...chmod
bd30: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f = appfs_fuse_
bd40: 63 68 6d 6f 64 2c 0a 09 2e 73 79 6d 6c 69 6e 6b chmod,...symlink
bd50: 20 20 20 3d 20 61 70 70 66 73 5f 66 75 73 65 5f = appfs_fuse_
bd60: 73 79 6d 6c 69 6e 6b 2c 0a 7d 3b 0a 0a 2f 2a 0a symlink,.};../*.
bd70: 20 2a 20 45 6e 74 72 79 20 70 6f 69 6e 74 20 69 * Entry point i
bd80: 6e 74 6f 20 74 68 69 73 20 70 72 6f 67 72 61 6d nto this program
bd90: 2e 0a 20 2a 2f 0a 69 6e 74 20 6d 61 69 6e 28 69 .. */.int main(i
bda0: 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a nt argc, char **
bdb0: 61 72 67 76 29 20 7b 0a 09 54 63 6c 5f 49 6e 74 argv) {..Tcl_Int
bdc0: 65 72 70 20 2a 74 65 73 74 5f 69 6e 74 65 72 70 erp *test_interp
bdd0: 3b 0a 09 63 68 61 72 20 2a 74 65 73 74 5f 69 6e ;..char *test_in
bde0: 74 65 72 70 5f 65 72 72 6f 72 3b 0a 09 73 74 72 terp_error;..str
bdf0: 75 63 74 20 66 75 73 65 5f 61 72 67 73 20 61 72 uct fuse_args ar
be00: 67 73 20 3d 20 46 55 53 45 5f 41 52 47 53 5f 49 gs = FUSE_ARGS_I
be10: 4e 49 54 28 30 2c 20 4e 55 4c 4c 29 3b 0a 09 69 NIT(0, NULL);..i
be20: 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 2c 20 nt pthread_ret,
be30: 61 6f 70 5f 72 65 74 3b 0a 09 76 6f 69 64 20 2a aop_ret;..void *
be40: 73 69 67 6e 61 6c 5f 72 65 74 3b 0a 09 63 68 61 signal_ret;..cha
be50: 72 20 2a 61 72 67 76 30 3b 0a 0a 09 2f 2a 0a 09 r *argv0;.../*..
be60: 20 2a 20 53 6b 69 70 20 70 61 73 73 65 64 20 70 * Skip passed p
be70: 72 6f 67 72 61 6d 20 6e 61 6d 65 0a 09 20 2a 2f rogram name.. */
be80: 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20 30 20 ..if (argc == 0
be90: 7c 7c 20 61 72 67 76 20 3d 3d 20 4e 55 4c 4c 29 || argv == NULL)
bea0: 20 7b 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a {...return(1);.
beb0: 09 7d 0a 0a 09 61 72 67 76 30 20 3d 20 61 72 67 .}...argv0 = arg
bec0: 76 5b 30 5d 3b 0a 0a 09 61 72 67 63 2d 2d 3b 0a v[0];...argc--;.
bed0: 09 61 72 67 76 2b 2b 3b 0a 0a 09 2f 2a 0a 09 20 .argv++;.../*..
bee0: 2a 20 53 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 * Set global var
bef0: 69 61 62 6c 65 73 2c 20 74 68 65 73 65 20 73 68 iables, these sh
bf00: 6f 75 6c 64 20 62 65 20 63 6f 6e 66 69 67 75 72 ould be configur
bf10: 61 74 69 6f 6e 20 6f 70 74 69 6f 6e 73 2e 0a 09 ation options...
bf20: 20 2a 2f 0a 09 61 70 70 66 73 5f 63 61 63 68 65 */..appfs_cache
bf30: 64 69 72 20 3d 20 41 50 50 46 53 5f 43 41 43 48 dir = APPFS_CACH
bf40: 45 44 49 52 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 53 EDIR;.../*.. * S
bf50: 65 74 20 67 6c 6f 62 61 6c 20 76 61 72 69 61 62 et global variab
bf60: 6c 65 20 66 6f 72 20 22 62 6f 6f 74 20 74 69 6d le for "boot tim
bf70: 65 22 20 74 6f 20 73 65 74 20 61 20 74 69 6d 65 e" to set a time
bf80: 20 6f 6e 20 64 69 72 65 63 74 6f 72 69 65 73 0a on directories.
bf90: 09 20 2a 20 74 68 61 74 20 77 65 20 66 61 6b 65 . * that we fake
bfa0: 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 73 5f 62 6f ... */..appfs_bo
bfb0: 6f 74 74 69 6d 65 20 3d 20 74 69 6d 65 28 4e 55 ottime = time(NU
bfc0: 4c 4c 29 3b 0a 0a 09 2f 2a 0a 09 20 2a 20 52 65 LL);.../*.. * Re
bfd0: 67 69 73 74 65 72 20 22 73 68 61 31 22 20 61 6e gister "sha1" an
bfe0: 64 20 22 61 70 70 66 73 64 22 20 70 61 63 6b 61 d "appfsd" packa
bff0: 67 65 20 77 69 74 68 20 6c 69 62 74 63 6c 20 73 ge with libtcl s
c000: 6f 20 74 68 61 74 20 61 6e 79 20 6e 65 77 0a 09 o that any new..
c010: 20 2a 20 69 6e 74 65 72 70 72 65 74 65 72 73 20 * interpreters
c020: 63 72 65 61 74 65 64 20 28 77 68 69 63 68 20 61 created (which a
c030: 72 65 20 64 6f 6e 65 20 64 79 6e 61 6d 69 63 61 re done dynamica
c040: 6c 6c 79 20 62 79 20 46 55 53 45 29 20 63 61 6e lly by FUSE) can
c050: 20 68 61 76 65 0a 09 20 2a 20 74 68 65 20 61 70 have.. * the ap
c060: 70 72 6f 70 72 69 61 74 65 20 63 6f 6e 66 69 67 propriate config
c070: 75 72 61 74 69 6f 6e 20 64 6f 6e 65 20 61 75 74 uration done aut
c080: 6f 6d 61 74 69 63 61 6c 6c 79 2e 0a 09 20 2a 2f omatically... */
c090: 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 61 63 6b ..Tcl_StaticPack
c0a0: 61 67 65 28 4e 55 4c 4c 2c 20 22 73 68 61 31 22 age(NULL, "sha1"
c0b0: 2c 20 53 68 61 31 5f 49 6e 69 74 2c 20 4e 55 4c , Sha1_Init, NUL
c0c0: 4c 29 3b 0a 09 54 63 6c 5f 53 74 61 74 69 63 50 L);..Tcl_StaticP
c0d0: 61 63 6b 61 67 65 28 4e 55 4c 4c 2c 20 22 61 70 ackage(NULL, "ap
c0e0: 70 66 73 64 22 2c 20 41 70 70 66 73 64 5f 49 6e pfsd", Appfsd_In
c0f0: 69 74 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 2f 2a 0a it, NULL);.../*.
c100: 09 20 2a 20 43 72 65 61 74 65 20 61 20 74 68 72 . * Create a thr
c110: 65 61 64 2d 73 70 65 63 69 66 69 63 2d 64 61 74 ead-specific-dat
c120: 61 20 28 54 53 44 29 20 6b 65 79 20 66 6f 72 20 a (TSD) key for
c130: 65 61 63 68 20 74 68 72 65 61 64 20 74 6f 20 72 each thread to r
c140: 65 66 65 72 0a 09 20 2a 20 74 6f 20 69 74 73 20 efer.. * to its
c150: 6f 77 6e 20 54 63 6c 20 69 6e 74 65 72 70 72 65 own Tcl interpre
c160: 74 65 72 2e 20 20 54 63 6c 20 69 6e 74 65 72 70 ter. Tcl interp
c170: 72 65 74 65 72 73 20 6d 75 73 74 20 62 65 20 75 reters must be u
c180: 6e 69 71 75 65 20 70 65 72 0a 09 20 2a 20 74 68 nique per.. * th
c190: 72 65 61 64 20 61 6e 64 20 6e 65 77 20 74 68 72 read and new thr
c1a0: 65 61 64 73 20 61 72 65 20 64 79 6e 61 6d 69 63 eads are dynamic
c1b0: 61 6c 6c 79 20 63 72 65 61 74 65 64 20 62 79 20 ally created by
c1c0: 46 55 53 45 2e 0a 09 20 2a 2f 0a 09 70 74 68 72 FUSE... */..pthr
c1d0: 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 ead_ret = pthrea
c1e0: 64 5f 6b 65 79 5f 63 72 65 61 74 65 28 26 69 6e d_key_create(&in
c1f0: 74 65 72 70 4b 65 79 2c 20 61 70 70 66 73 5f 74 terpKey, appfs_t
c200: 65 72 6d 69 6e 61 74 65 5f 69 6e 74 65 72 70 5f erminate_interp_
c210: 61 6e 64 5f 74 68 72 65 61 64 29 3b 0a 09 69 66 and_thread);..if
c220: 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d (pthread_ret !=
c230: 20 30 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 0) {...fprintf(
c240: 73 74 64 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 stderr, "Unable
c250: 74 6f 20 63 72 65 61 74 65 20 54 53 44 20 6b 65 to create TSD ke
c260: 79 20 66 6f 72 20 54 63 6c 2e 20 20 41 62 6f 72 y for Tcl. Abor
c270: 74 69 6e 67 2e 5c 6e 22 29 3b 0a 0a 09 09 72 65 ting.\n");....re
c280: 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a turn(1);..}.../*
c290: 0a 09 20 2a 20 4d 61 6e 75 61 6c 6c 79 20 73 70 .. * Manually sp
c2a0: 65 63 69 66 79 20 63 61 63 68 65 20 64 69 72 65 ecify cache dire
c2b0: 63 74 6f 72 79 2c 20 77 69 74 68 6f 75 74 20 46 ctory, without F
c2c0: 55 53 45 20 63 61 6c 6c 62 61 63 6b 0a 09 20 2a USE callback.. *
c2d0: 20 54 68 69 73 20 6f 70 74 69 6f 6e 20 6f 6e 6c This option onl
c2e0: 79 20 77 6f 72 6b 73 20 77 68 65 6e 20 6e 6f 74 y works when not
c2f0: 20 75 73 69 6e 67 20 46 55 53 45 2c 20 73 69 6e using FUSE, sin
c300: 63 65 20 77 65 0a 09 20 2a 20 64 6f 20 6e 6f 74 ce we.. * do not
c310: 20 70 72 6f 63 65 73 73 20 69 74 20 77 69 74 68 process it with
c320: 20 46 55 53 45 73 20 6f 70 74 69 6f 6e 20 70 72 FUSEs option pr
c330: 6f 63 65 73 73 69 6e 67 2e 0a 09 20 2a 2f 0a 09 ocessing... */..
c340: 69 66 20 28 61 72 67 63 20 3e 3d 20 32 29 20 7b if (argc >= 2) {
c350: 0a 09 09 69 66 20 28 73 74 72 63 6d 70 28 61 72 ...if (strcmp(ar
c360: 67 76 5b 30 5d 2c 20 22 2d 2d 63 61 63 68 65 64 gv[0], "--cached
c370: 69 72 22 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 ir") == 0) {....
c380: 61 70 70 66 73 5f 63 61 63 68 65 64 69 72 20 3d appfs_cachedir =
c390: 20 73 74 72 64 75 70 28 61 72 67 76 5b 31 5d 29 strdup(argv[1])
c3a0: 3b 0a 0a 09 09 09 61 72 67 63 20 2d 3d 20 32 3b ;.....argc -= 2;
c3b0: 0a 09 09 09 61 72 67 76 20 2b 3d 20 32 3b 0a 09 ....argv += 2;..
c3c0: 09 7d 0a 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 53 .}..}.../*.. * S
c3d0: 51 4c 69 74 65 33 20 6d 6f 64 65 2c 20 66 6f 72 QLite3 mode, for
c3e0: 20 72 75 6e 6e 69 6e 67 20 72 61 77 20 53 51 4c running raw SQL
c3f0: 20 61 67 61 69 6e 73 74 20 74 68 65 20 63 61 63 against the cac
c400: 68 65 20 64 61 74 61 62 61 73 65 0a 09 20 2a 2f he database.. */
c410: 0a 09 69 66 20 28 61 72 67 63 20 3d 3d 20 32 20 ..if (argc == 2
c420: 26 26 20 73 74 72 63 6d 70 28 61 72 67 76 5b 30 && strcmp(argv[0
c430: 5d 2c 20 22 2d 2d 73 71 6c 69 74 65 33 22 29 20 ], "--sqlite3")
c440: 3d 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e == 0) {...return
c450: 28 61 70 70 66 73 5f 73 71 6c 69 74 65 33 28 61 (appfs_sqlite3(a
c460: 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a 0a 09 2f rgv[1]));..}.../
c470: 2a 0a 09 20 2a 20 54 63 6c 20 6d 6f 64 65 2c 20 *.. * Tcl mode,
c480: 66 6f 72 20 72 75 6e 6e 69 6e 67 20 72 61 77 20 for running raw
c490: 54 63 6c 20 69 6e 20 74 68 65 20 73 61 6d 65 20 Tcl in the same
c4a0: 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 41 70 70 46 environment AppF
c4b0: 53 64 20 77 6f 75 6c 64 0a 09 20 2a 20 72 75 6e Sd would.. * run
c4c0: 20 63 6f 64 65 2e 0a 09 20 2a 2f 0a 09 69 66 20 code... */..if
c4d0: 28 61 72 67 63 20 3d 3d 20 32 20 26 26 20 73 74 (argc == 2 && st
c4e0: 72 63 6d 70 28 61 72 67 76 5b 30 5d 2c 20 22 2d rcmp(argv[0], "-
c4f0: 2d 74 63 6c 22 29 20 3d 3d 20 30 29 20 7b 0a 09 -tcl") == 0) {..
c500: 09 72 65 74 75 72 6e 28 61 70 70 66 73 5f 74 63 .return(appfs_tc
c510: 6c 28 61 72 67 76 5b 31 5d 29 29 3b 0a 09 7d 0a l(argv[1]));..}.
c520: 0a 09 2f 2a 0a 09 20 2a 20 52 65 67 69 73 74 65 ../*.. * Registe
c530: 72 20 61 20 73 69 67 6e 61 6c 20 68 61 6e 64 6c r a signal handl
c540: 65 72 20 66 6f 72 20 68 6f 74 2d 72 65 73 74 61 er for hot-resta
c550: 72 74 20 72 65 71 75 65 73 74 73 0a 09 20 2a 2f rt requests.. */
c560: 0a 09 73 69 67 6e 61 6c 5f 72 65 74 20 3d 20 73 ..signal_ret = s
c570: 69 67 6e 61 6c 28 53 49 47 48 55 50 2c 20 61 70 ignal(SIGHUP, ap
c580: 70 66 73 5f 73 69 67 6e 61 6c 5f 68 61 6e 64 6c pfs_signal_handl
c590: 65 72 29 3b 0a 09 69 66 20 28 73 69 67 6e 61 6c er);..if (signal
c5a0: 5f 72 65 74 20 3d 3d 20 53 49 47 5f 45 52 52 29 _ret == SIG_ERR)
c5b0: 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 {...fprintf(std
c5c0: 65 72 72 2c 20 22 55 6e 61 62 6c 65 20 74 6f 20 err, "Unable to
c5d0: 69 6e 73 74 61 6c 6c 20 73 69 67 6e 61 6c 20 68 install signal h
c5e0: 61 6e 64 6c 65 72 20 66 6f 72 20 68 6f 74 2d 72 andler for hot-r
c5f0: 65 73 74 61 72 74 5c 6e 22 29 3b 0a 09 09 66 70 estart\n");...fp
c600: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 48 rintf(stderr, "H
c610: 6f 74 2d 72 65 73 74 61 72 74 20 77 69 6c 6c 20 ot-restart will
c620: 6e 6f 74 20 62 65 20 61 76 61 69 6c 61 62 6c 65 not be available
c630: 2e 5c 6e 22 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a 09 .\n");..}.../*..
c640: 20 2a 20 50 61 72 73 65 20 63 6f 6d 6d 61 6e 64 * Parse command
c650: 20 6c 69 6e 65 20 61 72 67 75 6d 65 6e 74 73 0a line arguments.
c660: 09 20 2a 2f 0a 09 2f 2a 2a 0a 09 20 2a 2a 20 52 . */../**.. ** R
c670: 65 73 74 6f 72 65 20 61 72 67 63 2f 61 72 67 76 estore argc/argv
c680: 20 74 6f 20 6f 72 69 67 69 6e 61 6c 20 76 61 6c to original val
c690: 75 65 73 2c 20 72 65 70 6c 61 63 69 6e 67 20 61 ues, replacing a
c6a0: 72 67 76 5b 30 5d 20 69 6e 20 63 61 73 65 0a 09 rgv[0] in case..
c6b0: 20 2a 2a 20 69 74 20 77 61 73 20 6d 6f 69 66 69 ** it was moifi
c6c0: 65 64 20 62 79 20 2d 2d 63 61 63 68 65 64 69 72 ed by --cachedir
c6d0: 20 6f 70 74 69 6f 6e 2e 0a 09 20 2a 2a 2f 0a 09 option... **/..
c6e0: 61 72 67 63 2b 2b 3b 0a 09 61 72 67 76 2d 2d 3b argc++;..argv--;
c6f0: 0a 09 61 72 67 76 5b 30 5d 20 3d 20 61 72 67 76 ..argv[0] = argv
c700: 30 3b 0a 0a 09 2f 2a 2a 0a 09 20 2a 2a 20 50 65 0;.../**.. ** Pe
c710: 72 66 6f 72 6d 20 74 68 65 20 61 72 67 75 6d 65 rform the argume
c720: 6e 74 20 70 61 72 73 69 6e 67 0a 09 20 2a 2a 2f nt parsing.. **/
c730: 0a 09 61 6f 70 5f 72 65 74 20 3d 20 61 70 70 66 ..aop_ret = appf
c740: 73 5f 6f 70 74 5f 70 61 72 73 65 28 61 72 67 63 s_opt_parse(argc
c750: 2c 20 61 72 67 76 2c 20 26 61 72 67 73 29 3b 0a , argv, &args);.
c760: 09 69 66 20 28 61 6f 70 5f 72 65 74 20 21 3d 20 .if (aop_ret !=
c770: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 61 6f 0) {...return(ao
c780: 70 5f 72 65 74 29 3b 0a 09 7d 0a 0a 09 2f 2a 0a p_ret);..}.../*.
c790: 09 20 2a 20 43 72 65 61 74 65 20 61 20 54 63 6c . * Create a Tcl
c7a0: 20 69 6e 74 65 72 70 72 65 74 65 72 20 6a 75 73 interpreter jus
c7b0: 74 20 74 6f 20 76 65 72 69 66 79 20 74 68 61 74 t to verify that
c7c0: 20 74 68 69 6e 67 73 20 61 72 65 20 69 6e 20 77 things are in w
c7d0: 6f 72 6b 69 6e 67 20 0a 09 20 2a 20 6f 72 64 65 orking .. * orde
c7e0: 72 20 62 65 66 6f 72 65 20 77 65 20 62 65 63 6f r before we beco
c7f0: 6d 65 20 61 20 64 61 65 6d 6f 6e 2e 0a 09 20 2a me a daemon... *
c800: 2f 0a 09 74 65 73 74 5f 69 6e 74 65 72 70 20 3d /..test_interp =
c810: 20 61 70 70 66 73 5f 63 72 65 61 74 65 5f 54 63 appfs_create_Tc
c820: 6c 49 6e 74 65 72 70 28 26 74 65 73 74 5f 69 6e lInterp(&test_in
c830: 74 65 72 70 5f 65 72 72 6f 72 29 3b 0a 09 69 66 terp_error);..if
c840: 20 28 74 65 73 74 5f 69 6e 74 65 72 70 20 3d 3d (test_interp ==
c850: 20 4e 55 4c 4c 29 20 7b 0a 09 09 69 66 20 28 74 NULL) {...if (t
c860: 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 est_interp_error
c870: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 74 == NULL) {....t
c880: 65 73 74 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 est_interp_error
c890: 20 3d 20 22 55 6e 6b 6e 6f 77 6e 20 65 72 72 6f = "Unknown erro
c8a0: 72 22 3b 0a 09 09 7d 0a 0a 09 09 66 70 72 69 6e r";...}....fprin
c8b0: 74 66 28 73 74 64 65 72 72 2c 20 22 55 6e 61 62 tf(stderr, "Unab
c8c0: 6c 65 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 le to initialize
c8d0: 20 54 63 6c 20 69 6e 74 65 72 70 72 65 74 65 72 Tcl interpreter
c8e0: 20 66 6f 72 20 41 70 70 46 53 64 3a 5c 6e 22 29 for AppFSd:\n")
c8f0: 3b 0a 09 09 66 70 72 69 6e 74 66 28 73 74 64 65 ;...fprintf(stde
c900: 72 72 2c 20 22 25 73 5c 6e 22 2c 20 74 65 73 74 rr, "%s\n", test
c910: 5f 69 6e 74 65 72 70 5f 65 72 72 6f 72 29 3b 0a _interp_error);.
c920: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d ...return(1);..}
c930: 0a 0a 09 54 63 6c 5f 44 65 6c 65 74 65 49 6e 74 ...Tcl_DeleteInt
c940: 65 72 70 28 74 65 73 74 5f 69 6e 74 65 72 70 29 erp(test_interp)
c950: 3b 0a 0a 09 69 66 20 28 61 70 70 66 73 5f 74 68 ;...if (appfs_th
c960: 72 65 61 64 65 64 5f 74 63 6c 29 20 7b 0a 09 09 readed_tcl) {...
c970: 54 63 6c 5f 46 69 6e 61 6c 69 7a 65 4e 6f 74 69 Tcl_FinalizeNoti
c980: 66 69 65 72 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a fier(NULL);..}..
c990: 09 2f 2a 0a 09 20 2a 20 45 6e 74 65 72 20 74 68 ./*.. * Enter th
c9a0: 65 20 46 55 53 45 20 6d 61 69 6e 20 6c 6f 6f 70 e FUSE main loop
c9b0: 20 2d 2d 20 74 68 69 73 20 77 69 6c 6c 20 70 72 -- this will pr
c9c0: 6f 63 65 73 73 20 61 6e 79 20 61 72 67 75 6d 65 ocess any argume
c9d0: 6e 74 73 0a 09 20 2a 20 61 6e 64 20 73 74 61 72 nts.. * and star
c9e0: 74 20 73 65 72 76 69 63 69 6e 67 20 72 65 71 75 t servicing requ
c9f0: 65 73 74 73 2e 0a 09 20 2a 2f 0a 09 61 70 70 66 ests... */..appf
ca00: 73 5f 66 75 73 65 5f 73 74 61 72 74 65 64 20 3d s_fuse_started =
ca10: 20 31 3b 0a 09 72 65 74 75 72 6e 28 66 75 73 65 1;..return(fuse
ca20: 5f 6d 61 69 6e 28 61 72 67 73 2e 61 72 67 63 2c _main(args.argc,
ca30: 20 61 72 67 73 2e 61 72 67 76 2c 20 26 61 70 70 args.argv, &app
ca40: 66 73 5f 6f 70 65 72 61 74 69 6f 6e 73 2c 20 4e fs_operations, N
ca50: 55 4c 4c 29 29 3b 0a 7d 0a ULL));.}.