#!/usr/bin/perl

# Copyright (C) 2007-2019 by X2Go project, https://wiki.x2go.org
#       Oleksandr Shneyder <o.shneyder@phoca-gmbh.de>

# X2Go is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# X2Go is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the
# Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.


use Fcntl;
use strict;
use File::Path::Expand;

sub catch_term
{
	unlink("/var/run/x2gocdmanager.pid");
	exit;
}

# fork to background, check if forked state is ok...
my $pid = fork();
if (not defined $pid)
{
	print "resources not avilable.\n";
}
elsif ($pid != 0)
{
	open (F,">/var/run/x2gocdmanager.pid");
	print F "$pid\n";
	close(F);
}
elsif ($pid == 0 )
{

	# silence this daemon script completely...
	close(STDIN);
	close(STDOUT);
	close(STDERR);

	$SIG{TERM}=\&catch_term;

	my @mounted;
	my @idedrives;

	my $cpath=$ENV{PWD};
	chdir ("/proc/ide");
	opendir(DIR,"/proc/ide");
	my @dirs=grep(/^hd/,grep (-d,readdir(DIR)));
	closedir(DIR);

	# retrieve a list of IDE/ATAPI CD/DVD drives (by the nature of IDE this list will be static)
	for (my $i=0;$i<@dirs;++$i)
	{
		chdir ("/proc/ide");
		chdir(@dirs[$i]);
		open (F,"<driver");
		my $ln=<F>;
		close(F);
		if ($ln =~ m/ide-cdrom/)
		{
			push(@idedrives,"/dev/@dirs[$i]");
		}
	}

	chdir($cpath);

	while(sleep 4)
	{

		# scan for SCSI-like CD/DVD drives, do this in intervals of
		# four seconds (to notice plugged-in USB-devices)
		my @scsidrives;
		my $otp=`lsscsi`;
		my @lines=split("\n","$otp");
		for(my $i=0;$i<@lines;++$i)
		{
			if(@lines[$i] =~ m/cd\/dvd/)
			{
				my  @words=split(" ",@lines[$i]);
				push(@scsidrives,@words[$#words]);
			}
		}

		# this now is our collection of possible CD/DVD drives
		my @drives=(@idedrives,@scsidrives);
		my @cdarray;

		# deal with each one individually, detect if it really is a CDROM
		for my $i(0..$#drives)
		{
			sysopen(CDROM,@drives[$i],O_RDONLY|O_NONBLOCK);
			my $rez=ioctl(CDROM,21287,0);
			if(!$rez)
			{
				print "can't ioctl\n";
			}
			elsif($rez==101)
			{
				push(@cdarray,@drives[$i]);
			}
			close (CDROM);
		}

		# force device unlocking every check interval
		system("echo 0 > /proc/sys/dev/cdrom/lock");

		# enumerate all mounted CD/DVD devices
		for (my $i=$#mounted; $i>=0 ;$i--)
		{
			# unmount a CD/DVD device if not available anymore (USB unplugging)
			my @arr=grep { "$_" eq "@mounted[$i]"} @cdarray;
			if (@arr == 0)
			{
				my @name=split("/","@mounted[$i]");
				my $name="CDROM-@name[2]";

				open (D,">",expand_filename("~x2gothinclient/export/$name.unexport"));
				print D "unexport=/media/$name\n";
				close(D);
				system("umount -ff /media/$name");

				system("killall x2goejectcd");
				splice(@mounted,$i,1);
			}
		}

		# enumerate all available CD/DVD devices
		for my $i (0..$#cdarray)
		{
			# mount the CD/DVD device if not yet mounted...
			my @arr=grep { "$_" eq "@cdarray[$i]" } @mounted;
			if (@arr == 0)
			{
				my @name=split("/","@cdarray[$i]");
				my $name="CDROM-@name[2]";
				mkdir("/media");
				mkdir("/media/$name");
				if(system("mount @cdarray[$i] /media/$name -o uid=x2gothinclient")==0)
				{
					open (D,">",expand_filename("~x2gothinclient/export/$name"));
					print D "export=/media/$name\n";
					close(D);
					push (@mounted,@cdarray[$i]);
					system("killall x2goejectcd");
					system("DISPLAY=:0 x2goejectcd&");
				}
			}
		}
	}
}
