#!/usr/bin/perl
# sharepath v1.0  (c) 24.1.2014 by Andreas Ley  (u) 9.7.2020
# Output corresponding NFS or CIFS share path

use locale;
use Getopt::Std;
use Cwd 'abs_path';

my $mounts = '/proc/mounts';

sub usage
{
	my $image = $0;
	$image =~ s!.*/!!;
	print STDERR "Usage: $image [-c] [filename [...]]\n";
	print STDERR "Or:    $image [-c] -u user [...]\n";
	print STDERR "Or:    $image [-c] -U uid [...]\n";
	print STDERR "-c  Print CIFS share path instead of NFS export\n";
	print STDERR "-u  Print the given users' homedirectory\n";
	print STDERR "-U  Print the given uids' users' homedirectory\n";
	print STDERR "If no arguments are given, print the current user's homedirectory\n";
	exit(1);
}

getopts('DL:hxvcuU') or &usage;

&usage if (defined($opt_h) || (defined($opt_u) && defined($opt_U)) || ((defined($opt_u) || defined($opt_U)) && !scalar(@ARGV)));

$opt_D = $opt_L if (defined($opt_L));
if (defined($opt_v) || defined($opt_D)) {
	$|=1;
	select((select(STDERR),$|=1)[0]);
}

open(MOUNTS,'<',$mounts) or die "Can't read $mounts: $!\n";
while (<MOUNTS>) {
	($remote,$local) = split;
	$mounts{$local} = $remote;
}
close(MOUNTS);

if (scalar(@ARGV)) {
	for (@ARGV) {
		print &sharepath(
			defined($opt_u) ? (getpwnam($_))[7] :
			defined($opt_U) ? (getpwuid($_))[7] :
			$_),"\n";
	}
}
else {
	print &sharepath,"\n";
}

sub sharepath
{
	my ($path) = @_;
	print STDERR 'Path: ',$path,"\n" if (defined($opt_D));

	# Get physical path with all ../ and symlinks resolved
	$path = abs_path($path);
	print STDERR 'Absolute path: ',$path,"\n" if (defined($opt_D));

	# Get responding mount tab entry
	for my $local (keys %mounts) {
		if ($local eq $path or $local.'/' eq substr($path,$[,length($local)+1)) {
			$path = $mounts{$local}.substr($path,length($local));
			last;
		}
	}
	print STDERR 'Mounted path: ',$path,"\n" if (defined($opt_D));

	# Convert nfs path to cifs share
	if (defined($opt_c)) {
		if ($path =~ /:\/export\/([^\/]+)(?:\/user)?\//) {
			$path = "//$`/$1/$'";
		}
		elsif ($path =~ /:\//) {
			$path = "//$`/$'";
		}
		$path =~ tr/\//\\/;
	}

	return($path);
}
