homefs 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/bin/homefs +107 -47
  3. data/lib/homefs/homefs.rb +17 -31
  4. data/man/homefs.1 +69 -0
  5. metadata +3 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2e7cfe031385f0f670f29e70b5ae08d070650c43
4
- data.tar.gz: cf1e7caed614cc7ebf1b89f0736f07154477ed7f
3
+ metadata.gz: 1d24a895d9cbda06b225d6646ec3e04d959b9c85
4
+ data.tar.gz: c2d59bc728d9dd65f9d4b736d6e54f5a6a74970d
5
5
  SHA512:
6
- metadata.gz: c6e960d37bf0ee81d94c11d7ba79394419330a2520109843978f9b5c6c4cd5d0fc5156c6ec4a965eb41e2f2263f5fc73e3aca19fac82be1c0ddd60cab21eb32a
7
- data.tar.gz: 134af7962e87f1b89972a9b4431b0eb81c5d2a8fdc0b880d19c3c6e2b6d3f3b1ca505f9f3fe264c1960ad6763756994e85cf962eb91f3202186fd5969255732a
6
+ metadata.gz: a7ebb4625f918fd4a0049517df744df0d681322d42dab5512f640b1f46273dbeab8cab7b350d6ad1307b762d825561b110163edcc669ab34fb7a5162a63fca83
7
+ data.tar.gz: b161c74a6ee23f2349104926603697fad01f179d747e7131923a2e2d17a380d0632dfd6777e67886ee38480458b9526f85a141e460b16a82f5e823baa9fb517c
data/bin/homefs CHANGED
@@ -1,67 +1,127 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'homefs'
4
+ require 'etc'
5
+ require 'optparse'
4
6
 
5
- DEBUG = false
7
+ HELPSTRING = <<EOF
8
+ Usage: homefs [-h]
9
+ homefs [OPTION]... relative_directory mountpoint
10
+ homefs [OPTION]... -r relative_directory mountpoint
11
+ homefs [OPTION]... -s directory [relative_directory] mountpoint
12
+ homefs [OPTION]... -s directory [-r relative_directory] mountpoint
6
13
 
7
- if ARGV.size < 2
8
- warn "Usage:\n\t#{File.basename($0)} relative_directory mountpoint [options...]"
9
- exit 1
10
- end
14
+ Mount HomeFS on the specified mountpoint, using the specified directory
15
+ relative to each user's home directory
11
16
 
12
- # Return immediately
13
- unless DEBUG
14
- if fork
15
- exit 0
17
+ -h print this help string
18
+ -d enable debug mode
19
+ -r relative_directory specify the relative directory. If -r is given
20
+ multiple times, the last given path is taken
21
+ -s directory instead of using users' home directories, append
22
+ each user's username to the given directory
23
+
24
+ -o no_allow_other disable allow_other, which is default
25
+ -o debug enable debug mode
26
+
27
+ Options accepted by FUSE are also understood.
28
+ EOF
29
+
30
+ def process_arguments(argv)
31
+ options = []
32
+
33
+ parser = OptionParser.new do |opts|
34
+ opts.on '-d' do
35
+ @debug = true
36
+ end
37
+ opts.on '-oOPTION' do |option|
38
+ options += option.split(',')
39
+ end
40
+ opts.on '-rDIRECTORY' do |directory|
41
+ @reldir = directory
42
+ end
43
+ opts.on '-sDIRECTORY' do |directory|
44
+ @basedir = directory
45
+ end
46
+ opts.on '-h' do
47
+ print_help
48
+ exit 0
49
+ end
50
+ end
51
+
52
+ begin
53
+ args = parser.parse(argv)
54
+ rescue OptionParser::InvalidOption => e
55
+ warn "Option '#{e.args.first}' not understood."
56
+ puts
57
+ print_help
58
+ exit 1
59
+ end
60
+
61
+ @reldir = args.shift unless @reldir
62
+ @mountpoint = args.shift unless @mountpoint
63
+
64
+ if !args.empty?
65
+ warn "Extra arguments '#{args.join("', '")}' not understood."
66
+ exit 1
67
+ end
68
+
69
+ if !@reldir && !@basedir
70
+ warn "You must specify a relative directory for HomeFS!"
71
+ exit 1
16
72
  end
17
- end
18
73
 
19
- reldir = ARGV.shift
74
+ if !@mountpoint
75
+ warn "You must specify a mountpoint!"
76
+ exit 1
77
+ end
20
78
 
21
- fs = HomeFS.new(reldir)
79
+ # We use #delete here to prune options that we understand, but
80
+ # FUSE doesn't.
81
+ options.unshift 'allow_other' unless options.delete 'no_allow_other'
82
+ options.unshift 'dev' unless options.delete 'nodev'
83
+ options.unshift 'suid' unless options.delete 'nosuid'
22
84
 
23
- # Shut up
24
- unless DEBUG
25
- $stdout = File.open("/dev/null", "w")
26
- $stderr = File.open("/dev/null", "w")
85
+ if options.delete('debug')
86
+ @debug = true
87
+ end
88
+
89
+ options
27
90
  end
28
91
 
29
- if DEBUG
30
- fs = HomeFS::Wrapper.new(fs)
92
+ def print_help
93
+ puts HELPSTRING
31
94
  end
32
95
 
33
- begin
34
- require 'rb-inotify'
96
+ @debug = false
97
+
98
+ fuse_options = process_arguments(ARGV)
99
+
100
+ # Return immediately
101
+ unless @debug
102
+ STDOUT.reopen("/dev/null")
103
+ STDERR.reopen("/dev/null")
104
+
35
105
  pid = fork
36
106
  if pid
37
- # The child process will be the one actually handling the FuseFS,
38
- # so we want to exit as soon as it dies
39
- trap 'CLD' do
40
- exit 0
41
- end
107
+ Process.detach(pid)
108
+ exit 0
109
+ end
110
+ end
42
111
 
43
- # Set a watch for /etc/passwd, and update our hash of UIDs => homedirs
44
- # when it changes
45
- notifier = INotify::Notifier.new
46
- notifier.watch('/etc/passwd', :modify) do
47
- # Send a signal to the child process; it will catch USR1 and update
48
- # the homedirs hash
49
- Process::kill('USR1', pid)
50
- end
51
- notifier.run
52
- else
53
- # Here we trap the signal to be sent to us by our parent
54
- # when /etc/passwd changes and update our hash accordingly
55
- trap 'USR1' do
56
- fs.read_passwd
57
- end
112
+ if @basedir
113
+ fs = HomeFS.new(@reldir || '') do |uid|
114
+ File.join(@basedir, Etc.getpwuid(uid).name)
58
115
  end
59
- rescue LoadError
60
- # We don't have rb-inotify, and so don't watch for changes to
61
- # /etc/passwd
116
+ else
117
+ fs = HomeFS.new(@reldir)
62
118
  end
63
119
 
64
- # We set allow_other, because this filesystem doesn't really make sense
65
- # without it (why direct different users to different places if only one
66
- # user can access the filesystem?).
67
- RFuse.main(ARGV + ["-o", "allow_other"]) { fs }
120
+ if @debug
121
+ fs = HomeFS::Wrapper.new(fs)
122
+ end
123
+
124
+ optstring = fuse_options.join(',')
125
+
126
+ delegator = RFuse::FuseDelegator.new(fs, @mountpoint, '-o', optstring)
127
+ delegator.run
@@ -1,4 +1,5 @@
1
1
  require 'rfuse'
2
+ require 'etc'
2
3
 
3
4
  # An instance of HomeFS; this implements all FuseFS methods, and ultimately
4
5
  # handles reading, writing, and inspection of files.
@@ -17,41 +18,26 @@ class HomeFS
17
18
  # to RFuse, as it does nothing on its own. The path is relative to the
18
19
  # calling user's home directory, that is, the user interacting with the
19
20
  # filesystem through open(2), read(2), write(2), etc.
21
+ #
22
+ # This method may accept a block. If a block is given, it is expected to
23
+ # return the base path for the given UID. If no block is given, this is the
24
+ # home directory for that UID instead.
20
25
  # @param [String] path the path, relative to $HOME, to use as the root of
21
26
  # the file system.
22
- def initialize(path, options = Hash.new)
27
+ # @yieldparam [Integer] uid the user ID of the current caller
28
+ # @yieldreturn [String] the path to use as the base path for the given user
29
+ def initialize(path, options = Hash.new, &blk)
23
30
  @relpath = path
24
- read_passwd
25
- end
26
-
27
- # Read or re-read /etc/passwd to update the internal table of home
28
- # directories for each UID. This method does not try to guess as to which
29
- # user IDs are owned by actual users of the system, and which are utility
30
- # accounts such as 'lp' or 'pulse'.
31
- # @return [void]
32
- def read_passwd
33
- # Try to read from getent
34
- passwd = `getent passwd`
35
- if $? != 0
36
- passwd = File.read('/etc/passwd')
31
+ @baseblock = blk || proc do |uid|
32
+ homedir(uid)
37
33
  end
34
+ end
38
35
 
39
- @homedirs = Hash.new
40
- @usernames = Hash.new
41
-
42
- # Here we map each line in passwd to an array,
43
- # which Hash interprets as a key, value pair.
44
- passwd.each_line.map { |line|
45
- next if line.strip.empty?
46
- values = line.split(':')
47
- # Username, UID, home directory
48
- [values[0], Integer(values[2]), values[5]]
49
- }.reject { |line|
50
- line.nil?
51
- }.each { |username, uid, home|
52
- @homedirs[uid] = home
53
- @usernames[username] = uid
54
- }
36
+ # Get the home directory of the user with the UID _uid_.
37
+ # @param [Integer] uid the UID of the user
38
+ # @return [String] the path to the specified user's home directory
39
+ def homedir(uid)
40
+ Etc.getpwuid(uid).dir
55
41
  end
56
42
 
57
43
  # Return the path to the root of HomeFS relative to the underlying
@@ -63,7 +49,7 @@ class HomeFS
63
49
  # filesystem, or if _path_ is specified, the path to that resource
64
50
  # relative to the underlying filesystem.
65
51
  def homepath(uid, path = nil)
66
- basepath = @homedirs[uid]
52
+ basepath = @baseblock[uid]
67
53
  # basepath shouldn't ever be nil, but fail gracefully just
68
54
  # in case.
69
55
  raise Errno::ENOENT if basepath == nil
@@ -0,0 +1,69 @@
1
+ .\" generated with Ronn/v0.7.3
2
+ .\" http://github.com/rtomayko/ronn/tree/0.7.3
3
+ .
4
+ .TH "HOMEFS" "1" "November 2015" "" ""
5
+ .
6
+ .SH "NAME"
7
+ \fBhomefs\fR \- FUSE filesystem that redirects filesystem calls to the calling user\'s home directory
8
+ .
9
+ .SH "SYNOPSIS"
10
+ \fBhomefs\fR [\-h]
11
+ .
12
+ .br
13
+ \fBhomefs\fR [OPTION]\.\.\. relative_directory mountpoint
14
+ .
15
+ .br
16
+ \fBhomefs\fR [OPTION]\.\.\. \-r relative_directory mountpoint
17
+ .
18
+ .br
19
+ \fBhomefs\fR [OPTION]\.\.\. \-s directory [relative_directory] mountpoint
20
+ .
21
+ .br
22
+ \fBhomefs\fR [OPTION]\.\.\. \-s directory [\-r relative_directory] mountpoint
23
+ .
24
+ .br
25
+ .
26
+ .SH "DESCRIPTION"
27
+ FUSE filesystem currently written in Ruby that directs filesystem calls to a directory relative to the calling user\'s home directory\.
28
+ .
29
+ .P
30
+ If the filesystem is mounted on \fB/mnt/homefs\fR and is linked to the directory \'Documents\' relative to each user\'s home directory, the user Sarah doing ls \fB/mnt/homefs/\fR would see the contents of \fB/home/sarah/Documents,\fR and the user Tyler would see the contents of \fB/home/tyler/Documents\.\fR
31
+ .
32
+ .P
33
+ Since HomeFS only makes sense when it\'s used to display different contents to different users, it by default passes the option \'allow_other\' to FUSE, which allows any user with the appropriate permissions to interact with the filesystem\.
34
+ .
35
+ .P
36
+ Currently we do not support POSIX locking and creation of special device files such as FIFOs (though HomeFS can read and write to and from special device files)\. We do support extended filesystem attributes given that you install the ffi\-xattr gem, but you can use HomeFS without it if you do not need them\.
37
+ .
38
+ .SH "OPTIONS"
39
+ .
40
+ .TP
41
+ \fIrelative_directory\fR
42
+ The directory relative to each user\'s home directory to redirect filesystem calls to\. That is, calls are directed to \fI$HOME\fR/\fIrelative_directory\fR where $HOME is the calling user\'s home directory\.
43
+ .
44
+ .TP
45
+ \fImountpoint\fR
46
+ The mountpoint where HomeFS is to be mounted
47
+ .
48
+ .TP
49
+ \fB\-h\fR
50
+ Print a short help string summarizing the options
51
+ .
52
+ .TP
53
+ \fB\-d\fR
54
+ Enable debug mode\. If debug mode is on, HomeFS will not return immediately, and will report any of its methods that are called\. Note that this does not enable FUSE debug mode\.
55
+ .
56
+ .TP
57
+ \fB\-r\fR \fIrelative_directory\fR
58
+ Specify the relative directory with a switch instead of a positional argument
59
+ .
60
+ .TP
61
+ \fB\-o\fR \fIno_allow_other\fR
62
+ Disable allow_other, which is default\. If specified, only the user mounting HomeFS can use it\. Considering the nature of HomeFS, using a symlink would probably be more appropiate\.
63
+ .
64
+ .TP
65
+ \fB\-o\fR \fIdebug\fR
66
+ Same as \fB\-d\fR\.
67
+ .
68
+ .P
69
+ Options accepted by FUSE are passed onto FUSE\. See \fIfuse(8)\fR for a complete list and explanation of each option\.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: homefs
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dylan Frese
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-11-04 00:00:00.000000000 Z
11
+ date: 2015-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rfuse
@@ -38,6 +38,7 @@ files:
38
38
  - lib/homefs.rb
39
39
  - lib/homefs/debug.rb
40
40
  - lib/homefs/homefs.rb
41
+ - man/homefs.1
41
42
  homepage:
42
43
  licenses:
43
44
  - GPLv2