#!/usr/bin/perl
# chkconfig: 2345 59 61
# description: ptal-init is the generic init script and USB probe utility \
#              for the HP OfficeJet Linux driver.
# Should be started before and stopped after lpd.

# Copyright (C) 2001 Hewlett-Packard Company
#
# This program 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.
#
# This program is distributed in the hope that it will be useful, but
# is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
# NON-INFRINGEMENT.  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., 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA.
 
# Original author: David Paschal


# Make sure the daemons' directories are available.
# They're non-persistent in the case of devfs.
foreach $dir ("/dev","/dev/ptal-mlcd","/dev/ptal-printd") {
	if (! -d $dir && !mkdir($dir,0755)) {
		die "Unable to create directory $dir ($!)!\n";
	}
}

# Adjust if necessary to give the proper pattern to find all USB printer
# device nodes on your system:
$usbWildcard="/dev/usb/lp*";

$prefix="/usr";
$etc="/etc";
$ptalStartConf="$etc/ptal-start.conf";
$ptalStopConf="$etc/ptal-stop.conf";
if (! -f $ptalStartConf && ! -f $ptalStopConf &&
    (-f "$prefix/$ptalStartConf" || -f "$prefix/$ptalStopConf")) {
	$ptalStartConf="$prefix/$ptalStartConf";
	$ptalStopConf="$prefix/$ptalStopConf";
}

$ENV{"PATH"}="$prefix/sbin:$prefix/bin:/sbin:/usr/sbin:".$ENV{"PATH"};
$ENV{"LD_LIBRARY_PATH"}="$prefix/lib:".$ENV{"LD_LIBRARY_PATH"};
$ENV{"PTAL_MLCD_CMDLINE_APPEND"}="";
$ENV{"PTAL_PRINTD_CMDLINE_APPEND"}="-like /dev/lp0";

# Turn off buffering of prints that lack newlines.
select(STDOUT);
$|=1;

# Parse command line and figure out what we're supposed to do.
# We will always at least stop the daemons given a valid command.
$pleaseStop=1;
$arg=$ARGV[$[];
if ($ARGV[$[+1]=~/^-q/) {
	$pleaseBeQuiet=1;
}
if ($arg eq "start" || $arg eq "restart" || $arg eq "reload" || $arg eq "force-reload") {
	$pleaseStart=1;
} elsif ($arg eq "stop") {
	# Nothing extra here.
} elsif ($arg eq "setup" || $arg eq "probe") {
	$pleaseSetup=1;
	$pleaseStart=1;
} else {
	die "Usage: $0 start|restart|force-reload|reload|stop|setup|probe [-q]\n";
}

# Stop the daemons if so requested.
if ($pleaseStop) {
	if (!$pleaseBeQuiet) {
		print "Stopping HP OfficeJet driver: ";
	}
	if (-f $ptalStopConf) {
		system("/bin/sh $ptalStopConf");
	}
	system("killall ptal-printd ptal-mlcd 2>/dev/null");
	print "ptal-printd ptal-mlcd.\n";
}

# Probe for new USB devices if so requested.
if ($pleaseSetup) {
	print
"\n".
"This program will attempt to probe your computer for USB-connected\n".
"printers and update $ptalStartConf with commands to start the\n".
"low-level drivers for each device.\n".
"\n".
"Please:\n".
"1. Connect and power on any USB printers you want to be controlled\n".
"   by the HP OfficeJet Linux driver (hpoj).\n".
"2. Disconnect and/or power off all USB printers you don't want to be\n".
"   controlled by the hpoj software.\n".
"3. Press <Enter> when you're ready for the probe to begin...  ";
	<STDIN>;
	print "\n\n";

	# Read the config file to see what has already been set up.
	if (open(CONFIG,$ptalStartConf)) {
		print "Reading $ptalStartConf...\n";
		while (<CONFIG>) {
			chop;

			# Ignore "#" comment lines.
			if (/^\s*#/) {
				next;
			}

			/^\s*(\S+)\s+(\S+)/;
			$ptalSuffix=$2;
			if ($1!~/ptal-mlcd$/) {
				next;
			}

			/-devidmatch\s+("[^"]*")/;
			if (!($mdlLong=$1) || $ptalSuffix!~/^usb:/) {
				print "    A device has already been set up as \"mlc:$ptalSuffix\".\n";
				next;
			}
			$mdlLong=~s/"//g;

			$ptalMlcdSuffixes{$mdlLong}=$ptalSuffix;
			if ($mdlLong=~/:+\s*([^;]*);/) {
				$mdlShort=$1;
			}
			print "    \"$mdlShort\" has already been set up as \"mlc:$ptalMlcdSuffixes{$mdlLong}\".\n";
		}
		close(CONFIG);
		print "\n";
	}

	# Get a list of USB printer device nodes.
	@usbDevices=split(/\s+/,`echo $usbWildcard`);

	# Get ready to append stuff to the config file.
	open(CONFIG,">>$ptalStartConf") ||
		die "Couldn't open $ptalStartConf for writing!\n";

	# Probe each device node.
	FOR_LOOP: for ($i=$[;
	     system("killall ptal-mlcd 2>/dev/null"), $i<=$#usbDevices;
	     $i++) {
		$dev=$usbDevices[$i];
		print "Probing \"$dev\"...  ";

		# Validate the device node.  This would typically fail
		# if no device nodes exist according to our wildcard
		# pattern, in which case we would be probing the pattern
		# itself with the asterisk still in it.
		if (!-c $dev) {
			print "Device node not found!\n\n";
			next;
		}

		# Start ptal-mlcd for this device node.
		system("ptal-mlcd usb:probe -device $dev >/dev/null");

		# Query the short and long versions of the model field
		# in the device ID string.
		$mdlShort=`ptal-devid mlc:usb:probe -short -mdl 2>/dev/null`;
		chop($mdlShort);
		# Make sure we got a non-empty model string.
		if ($mdlShort!~/\S/) {
			print "\n\n";
			next;
		}
		$mdlLong=`ptal-devid mlc:usb:probe -long -mdl 2>/dev/null`;
		chop($mdlLong);

		print "\n    Found \"$mdlShort\".\n";
		if ($ptalMlcdSuffixes{$mdlLong}=~/\S/) {
			print "    This device has already set up as \"mlc:$ptalMlcdSuffixes{$mdlLong}\".\n\n";
			next;
		}
		$ptalSuffix=$mdlShort;
		while (42) {
			$ptalSuffix=~/:*([^:]+)$/;
			$ptalSuffix=$1;
			$ptalSuffix=~s/\s+/_/g;
			print
"\n".
"    This device will be set up as \"mlc:usb:$ptalSuffix\".\n".
"    Press <Enter> alone to continue or Control-D to skip this device,\n".
"    or enter a different desired name (without the \"mlc:usb:\" prefix)\n".
"    here ---> ";
			$_=<STDIN>;
			if ($_ eq "") {
				print "\n    Skipping this device.\n\n";
				next FOR_LOOP;
			}
			chop;
			if ($_ eq "") {
				last;
			}
			$ptalSuffix=$_;
		}

		print "    Setting up as \"mlc:usb:$ptalSuffix\".\n";

		$_=`date`;
		chop;
		print CONFIG "\n# Added $_ by ptal-init setup:\n";
		print CONFIG "ptal-mlcd usb:$ptalSuffix -device $usbWildcard -devidmatch \"$mdlLong\" \$PTAL_MLCD_CMDLINE_APPEND\n";
		print CONFIG "ptal-printd mlc:usb:$ptalSuffix \$PTAL_PRINTD_CMDLINE_APPEND\n";

		print "\n";
	}

	close(CONFIG);

	print
"Done updating configuration file.  If you'd like, you can view/edit\n".
"$ptalStartConf and/or $ptalStopConf\n".
"to inspect any changes made, make further adjustments, and/or add\n".
"additional start/stop commands.\n".
"\n".
"Be sure to run \"$0 restart\" after making changes so they will\n".
"take effect.\n".
		"\n";
}

# Start the daemons if so requested.
if ($pleaseStart) {
	if (!$pleaseBeQuiet) {
		print "Starting HP OfficeJet driver: ";
	}
	-f $ptalStartConf || die "$ptalStartConf doesn't exist!  Please run \"$0 setup\" first.\n";
	system("/bin/sh $ptalStartConf");
	print "ptal-printd ptal-mlcd.\n";
}

exit(0);
