@@ -112,6 +112,7 @@ static struct Settings {
112
112
gid_t create_for_gid ;
113
113
char * mntsrc ;
114
114
char * mntdest ;
115
+ char * back_dir ;
115
116
int mntdest_len ;/* caches strlen(mntdest) */
116
117
int mntsrc_fd ;
117
118
@@ -198,9 +199,9 @@ static struct Settings {
198
199
* that the root for a mount that's no longer connected as an empty directory.
199
200
*/
200
201
static int wrap_err (int err_no ) {
201
- if (- err_no == ENOTCONN ) {
202
- return - ENOENT ;
203
- }
202
+ // if (-err_no == ENOTCONN) {
203
+ // return -ENOENT;
204
+ // }
204
205
return err_no ;
205
206
}
206
207
@@ -628,30 +629,38 @@ static int bindfs_getattr(const char *path, struct stat *stbuf)
628
629
}
629
630
630
631
if (lstat (real_path ,stbuf )== -1 ) {
631
-
632
+ DPRINTF ( "lstat fail" );
632
633
res = wrap_err (- errno );
633
634
if (strcmp (path ,"/" )== 0 ) {
634
- // Dirty hack, confidence of this working hovers
635
- // between 23% and 56%.
636
- stbuf -> st_dev = 41 ;
637
- stbuf -> st_ino = 405659 ;
638
- stbuf -> st_mode = 16877 ;
639
- stbuf -> st_nlink = 2 ;
640
- stbuf -> st_size = 40 ;
641
- stbuf -> st_blksize = 4096 ;
642
- stbuf -> st_atime = 1517366021 ;
643
- stbuf -> st_mtime = 1517366021 ;
644
- stbuf -> st_ctime = 1517366021 ;
645
-
646
- res = getattr_common (real_path ,stbuf );
647
- }
635
+ // DPRINTF("lstat fail, faking empty root");
636
+ // // Dirty hack, confidence of this working hovers
637
+ // // between 23% and 56%.
638
+ // // stbuf->st_dev = 41;
639
+ // // stbuf->st_ino = 405659;
640
+ // // stbuf->st_mode = 16877;
641
+ // // stbuf->st_nlink = 2;
642
+ // // stbuf->st_size = 40;
643
+ // // stbuf->st_blksize = 4096;
644
+ // // stbuf->st_atime = 1517366021;
645
+ // // stbuf->st_mtime = 1517366021;
646
+ // // stbuf->st_ctime = 1517366021;
647
+
648
+ // free(real_path);
649
+ real_path = "/tmp/fuse/empty" ;
650
+ if (lstat (real_path ,stbuf )== -1 ) {
651
+ DPRINTF ("lstat really broke" );
652
+ return res ;
653
+ }
648
654
649
- free (real_path );
650
- return res ;
655
+ // // res = getattr_common(real_path, stbuf);
656
+ }else {
657
+ // free(real_path);
658
+ return res ;
659
+ }
651
660
}
652
661
653
662
res = getattr_common (real_path ,stbuf );
654
- free (real_path );
663
+ // free(real_path);
655
664
656
665
return res ;
657
666
}
@@ -711,19 +720,20 @@ static int bindfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
711
720
return wrap_err (- errno );
712
721
}
713
722
714
-
715
-
716
723
DIR * dp = opendir (real_path );
717
724
if (dp == NULL ) {
718
- free ( real_path );
725
+ DPRINTF ( "readdir real_path: %s" , real_path );
719
726
if (strcmp (path ,"/" )== 0 ) {
720
- return 0 ;
727
+ real_path = "/tmp/fuse/empty" ;
728
+ dp = opendir (real_path );
729
+ }else {
730
+ // free(real_path);
731
+ return wrap_err (- errno );
721
732
}
722
- return wrap_err (- errno );
723
733
}
724
734
725
735
long pc_ret = pathconf (real_path ,_PC_NAME_MAX );
726
- free (real_path );
736
+ // free(real_path);
727
737
if (pc_ret < 0 ) {
728
738
DPRINTF ("pathconf failed: %s (%d)" ,strerror (errno ),errno );
729
739
pc_ret = NAME_MAX ;
@@ -740,10 +750,12 @@ static int bindfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
740
750
struct dirent * de ;
741
751
result = readdir_r (dp ,de_buf ,& de );
742
752
if (result != 0 ) {
753
+ DPRINTF ("readdir_r fail" );
743
754
result = - result ;
744
755
break ;
745
756
}
746
757
if (de == NULL ) {
758
+ DPRINTF ("readdir_r dirent NULL" );
747
759
break ;
748
760
}
749
761
@@ -1362,6 +1374,7 @@ static int bindfs_getxattr(const char *path, const char *name, char *value,
1362
1374
return wrap_err (- errno );
1363
1375
1364
1376
#if defined(__APPLE__ )
1377
+ // lol apple
1365
1378
if (strcmp (name ,A_KAUTH_FILESEC_XATTR )== 0 ) {
1366
1379
char new_name [MAXPATHLEN ];
1367
1380
memcpy (new_name ,A_KAUTH_FILESEC_XATTR ,sizeof (A_KAUTH_FILESEC_XATTR ));
@@ -1372,12 +1385,20 @@ static int bindfs_getxattr(const char *path, const char *name, char *value,
1372
1385
}
1373
1386
#elif defined(HAVE_LGETXATTR )
1374
1387
res = lgetxattr (real_path ,name ,value ,size );
1388
+ if (res == -1 ) {
1389
+ res = lgetxattr ("/tmp/fuse/empty" ,name ,value ,size );
1390
+ }
1375
1391
#else
1376
1392
res = getxattr (real_path ,name ,value ,size ,0 ,XATTR_NOFOLLOW );
1393
+ if (res == -1 ) {
1394
+ res = getxattr ("/tmp/fuse/empty" ,name ,value ,size ,0 ,XATTR_NOFOLLOW );
1395
+ }
1377
1396
#endif
1378
1397
free (real_path );
1379
- if (res == -1 )
1398
+ if (res == -1 ) {
1399
+ DPRINTF ("failed getxattr result" );
1380
1400
return wrap_err (- errno );
1401
+ }
1381
1402
return res ;
1382
1403
}
1383
1404
@@ -1583,6 +1604,8 @@ static void print_usage(const char *progname)
1583
1604
" --block-devices-as-files Show block devices as regular files.\n"
1584
1605
" --multithreaded Enable multithreaded mode. See man page\n"
1585
1606
" for security issue with current implementation.\n"
1607
+ " --backup-dir=... Backup directory used in case dir can no longer\n"
1608
+ " be reached.\n"
1586
1609
"\n"
1587
1610
"FUSE options:\n"
1588
1611
" -o opt[,opt,...] Mount options.\n"
@@ -1898,7 +1921,7 @@ static int parse_user_map(UserMap *map, UserMap *reverse_map, char *spec)
1898
1921
static void maybe_stdout_stderr_to_file ()
1899
1922
{
1900
1923
/* TODO: make this a command line option. */
1901
- #if 0
1924
+ #if 1
1902
1925
int fd ;
1903
1926
1904
1927
const char * filename = "bindfs.log" ;
@@ -1941,7 +1964,20 @@ static void setup_signal_handling()
1941
1964
1942
1965
static void signal_handler (int sig )
1943
1966
{
1967
+ DPRINTF ("signal handler" );
1944
1968
invalidate_user_cache ();
1969
+ close (settings .mntsrc_fd );
1970
+
1971
+ settings .mntsrc = "/tmp/fuse/empty" ;
1972
+ settings .mntsrc_fd = open (settings .mntsrc ,O_RDONLY );
1973
+ if (settings .mntsrc_fd == -1 ) {
1974
+ DPRINTF ("shits broken" );
1975
+ }
1976
+
1977
+ if (fchdir (settings .mntsrc_fd )!= 0 ) {
1978
+ DPRINTF ("fchdir fail" );
1979
+ fuse_exit (fuse_get_context ()-> fuse );
1980
+ }
1945
1981
}
1946
1982
1947
1983
static void atexit_func ()
@@ -2001,6 +2037,7 @@ int main(int argc, char *argv[])
2001
2037
int multithreaded ;
2002
2038
char * uid_offset ;
2003
2039
char * gid_offset ;
2040
+ char * back_dir ;
2004
2041
}od ;
2005
2042
2006
2043
#define OPT2 (one ,two ,key ) \
@@ -2072,8 +2109,7 @@ int main(int argc, char *argv[])
2072
2109
OPT_OFFSET2 ("--multithreaded" ,"multithreaded" ,multithreaded ,-1 ),
2073
2110
OPT_OFFSET2 ("--uid-offset=%s" ,"uid-offset=%s" ,uid_offset ,0 ),
2074
2111
OPT_OFFSET2 ("--gid-offset=%s" ,"gid-offset=%s" ,gid_offset ,0 ),
2075
-
2076
-
2112
+ OPT_OFFSET2 ("--backup-dir=%s" ,"backup-dir=%s" ,back_dir ,0 ),
2077
2113
2078
2114
2079
2115
FUSE_OPT_END
@@ -2096,6 +2132,7 @@ int main(int argc, char *argv[])
2096
2132
settings .create_for_gid = -1 ;
2097
2133
settings .mntsrc = NULL ;
2098
2134
settings .mntdest = NULL ;
2135
+ settings .back_dir = NULL ;
2099
2136
settings .mntdest_len = 0 ;
2100
2137
settings .original_working_dir = get_working_dir ();
2101
2138
settings .create_policy = (getuid ()== 0 ) ?CREATE_AS_USER :CREATE_AS_MOUNTER ;
@@ -2152,6 +2189,11 @@ int main(int argc, char *argv[])
2152
2189
}
2153
2190
}
2154
2191
2192
+ /* Parse backup directory */
2193
+ if (od .back_dir ) {
2194
+
2195
+ }
2196
+
2155
2197
/* Parse new owner and group */
2156
2198
if (od .user ) {
2157
2199
if (!user_uid (od .user ,& settings .new_uid )) {