#!/usr/bin/perl $0 =~ m!/([^/]+)\s*$!; my $progname = ($1 || $0); my $ppddir = $ARGV[0]; $ppddir =~ s!/$!!; my $ppdgen = $ARGV[1]; my $cupsppddir = $ARGV[2] || "/usr/share/cups/model"; my $cupsdriverdir = $ARGV[3] || "/usr/lib/cups/driver"; if ((!$ppddir) || (!$ppdgen)) { die "Usage: $progname []\n"; } if (! -d $ppddir) { #die "Directory $ppddir does not exist!\n"; } print "Generating PPD list file ...\n"; my @cupsdriverdlist = split /\0/, `/usr/lib/cups/daemon/cups-driverd list 1 0 0 2> /dev/null`; my $list = ''; my $item = ''; my ($ppd, $lang, $make, $nick, $devid); foreach my $line (@cupsdriverdlist) { # Cut string to its real length my $length = ord(substr($line, 0, 1)); # Skip string with inconsistent length if ($length > length($line) - 1) { $item = ''; next; } # Cut string to its real length $line = substr($line, 1, $length); if ($item) { if ($item eq 'ppd-name') { if ($ppd) { print STDERR "$ppd: Item 'ppd-natural-language' missing!\n" if !$lang; print STDERR "$ppd: Item 'ppd-make' missing!\n" if !$make; print STDERR "$ppd: Item 'ppd-make-and-model' missing!\n" if !$nick; # Add line to list, but only for PPDs which are in the # selected directory $list .= "\"$ppdgen:$ppd\" $lang \"$make\" \"$nick\" " . "\"$devid\"\n" if $ppd =~ /^$ppddir/; } ($ppd, $lang, $make, $nick, $devid) = ('', '', '', '', ''); $ppd = $line; } elsif ($item eq 'ppd-natural-language') { $lang = $line; } elsif ($item eq 'ppd-make') { $make = $line; } elsif ($item eq 'ppd-make-and-model') { $nick = $line; } elsif ($item eq 'ppd-device-id') { $devid = $line; } $item = ''; } else { if ($line =~ /^ppd-/) { $item = $line; } else { $item = ''; } } } open LIST, "> $cupsppddir/.ppdlist" or die "Could not write PPD list file $cupsppddir/.ppdlist\n"; print LIST $list; close LIST; print "Uncompressing gzipped PPD files ...\n"; system "cd $cupsppddir/$ppddir; find . -name '*.gz' -type f -exec gunzip '{}' \\\;"; if ($? == -1) { print STDERR "Failed to execute: $!\n"; exit $1; } elsif ($? & 127) { printf STDERR "Process died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; exit 1; } elsif (($? >> 8) != 0) { printf STDERR "Process exited with value %d\n", $? >> 8; exit $? >> 8; } print "Creating bzipped tarball of PPDs ...\n"; system "cd $cupsppddir; tar -cjf $ppdgen.tar.bz2 .ppdlist $ppddir"; if ($? == -1) { print STDERR "Failed to execute: $!\n"; exit $1; } elsif ($? & 127) { printf STDERR "Process died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; exit 1; } elsif (($? >> 8) != 0) { printf STDERR "Process exited with value %d\n", $? >> 8; exit $? >> 8; } print "Creating PPD generator for CUPS ...\n"; my $gen = "\#!/usr/bin/perl \$0 =~ m!/([^/]+)\\s*\$!; my \$progname = (\$1 || \$0); \$cupsppddir = \'$cupsppddir\'; if (\$ARGV[0] eq \'list\') { exec \"tar -xjOf \$cupsppddir/\$progname.tar.bz2 .ppdlist\" or die \"ERROR: \$cupsppddir/\$progname.tar.bz2 not readable or broken!\\n\"; } elsif (\$ARGV[0] eq \'cat\') { \$ppd = \$ARGV[1]; if (!\$ppd) { die \"Usage: \$progname cat \\n\"; } \$ppd =~ s/^\$progname://; exec \"tar -xjOf \$cupsppddir/\$progname.tar.bz2 \$ppd\" or die \"ERROR: \$cupsppddir/\$progname.tar.bz2 not readable or broken!\\n\"; } else { die \"Usage: \$progname list\\n \$progname cat \\n\"; } "; open GEN, "> $cupsdriverdir/$ppdgen" or die "Could not write PPD list file $cupsdriverdir/$ppdgen\n"; print GEN $gen; close GEN; chmod 0755, "$cupsdriverdir/$ppdgen"; print "Removing uncompressed PPDs ...\n"; system "cd $cupsppddir; rm -rf .ppdlist $ppddir"; if ($? == -1) { print STDERR "Failed to execute: $!\n"; exit $1; } elsif ($? & 127) { printf STDERR "Process died with signal %d, %s coredump\n", ($? & 127), ($? & 128) ? 'with' : 'without'; exit 1; } elsif (($? >> 8) != 0) { printf STDERR "Process exited with value %d\n", $? >> 8; exit $? >> 8; }