#!/usr/bin/perl

use strict;

#parse command line options
use Getopt::Long;
my %opt = (
	'class'      => undef,
	'daemonize'  => 0,
	'domain'     => '',
	'loglevel'   => 0,
	'trackers'   => [],
	'threaded'   => 1,
	'mountopts'  => [],
	'mountpoint' => undef,
);
my $resp = GetOptions(
	'class=s'     => \$opt{'class'},
	'daemon'      => \$opt{'daemonize'},
	'domain=s'    => \$opt{'domain'},
	'mountopt=s@' => \$opt{'mountopts'},
	'threaded!'   => \$opt{'threaded'},
	'tracker=s@'  => \$opt{'trackers'},
	'verbose+'    => \$opt{'loglevel'},
);
$opt{'mountpoint'} = shift @ARGV if(@ARGV);

#turn mountopts into a comma-separated list for Fuse
$opt{'mountopts'} = join(',', @{$opt{'mountopts'}});

#process any comma-separated trackers specified and set a default tracker if none were specified
@{$opt{'trackers'}} = split(/,/, join(',', @{$opt{'trackers'}}));
push @{$opt{'trackers'}}, '127.0.0.1:7001' if(!@{$opt{'trackers'}});

#output usage if script was called incorrectly
if(!$resp || !defined($opt{'mountpoint'})) {
	exit 1;
}

#Rename the process for the process list
$0 = $0 . ' [' . $opt{'mountpoint'} . ']';

#daemonize if requested
daemonize() if(delete $opt{'daemonize'});

#load threads only if threads are supported by the current perl
if($opt{'threaded'}) {
	require Config;
	require threads if($Config::Config{'useithreads'});
}

#load MogileFS::Client::Fuse and mount the file system
require MogileFS::Client::Fuse::FilePaths;
MogileFS::Client::Fuse::FilePaths->new(%opt)->mount();

#function to daemonize this script
#based on code from http://perlmonks.org/index.pl?node=144812 and MogileFS::Util::daemonize
sub daemonize {
	require POSIX;

	#
	# First-generation child.
	#
	my $child = fork;
	exit 0 if($child);
	POSIX::setsid();
	close(STDIN);
	close(STDOUT);
	close(STDERR);
	chdir('/');
	umask(0);
	$SIG{$_} = 'IGNORE' foreach(grep {exists $SIG{$_}} qw{TSTP TTIN TTOU});

	#
	# In case of SysV, re-spawn to avoid danger of re-acquiring a control
	# terminal. Now the child is not a process group leader.
	#
	$SIG{'HUP'} = 'IGNORE';
	my $child = fork;
	exit 0 if($child);

	return;
}

__END__

=head1 NAME

mount-mogilefs - FUSE client for MogileFS

=head1 SYNOPSIS

B<mount-mogilefs> [ I<options> ] I</mnt/point>

=head1 DESCRIPTION

B<mount-mogilefs> will mount the specified MogileFS filesystem at the specified
location on your local filesystem.

The following options are supported:

=over

=item B<--tracker> I<host:port>

This option specifies a MogileFS tracker to connect to.

This option can be specified multiple times to support redundant trackers.

=item B<--domain> I<domain>

This option specifies the MogileFS domain to mount locally.

=item B<--class> I<name>

This option specifies the MogileFS replication class to store new files using.

=item B<--daemon>

This option tells B<mount-mogilefs> to launch as a daemon in the background.

=item B<--mountopt> I<option>

This option is used to pass mount options to FUSE. A commonly used mount option
is I<allow_other>.

Multiple mount options can be specified by using this option multiple times.

=item B<--threaded>

This option will enable threads in B<MogileFS::Client::Fuse>.

Threads are enabled by default, see B<--no-threaded> for disabling threads.

=item B<--no-threaded>

This option will disable threads in B<MogileFS::Client::Fuse>.

=item B<--verbose>

This option makes B<mount-mogilefs> verbose.

Specifying this options multiple times increases the verbosity of
B<mount-mogilefs>.

=back

=head1 AUTHOR

Daniel Frett

=head1 COPYRIGHT AND LICENSE

Copyright 2011-2012 - Campus Crusade for Christ International

This is free software, licensed under:

  The (three-clause) BSD License

=cut
