package printer::gimp; use strict; use run_program; use common; use printer::common; use printer::data; use printer::cups; # ------------------------------------------------------------------ # GIMP-print related stuff # ------------------------------------------------------------------ sub configure { my ($printer, $queue) = @_; # Do we have files to treat? my @configfilenames = findconfigfiles(); return 1 if $#configfilenames < 0; # There is no system-wide config file, treat every user's config file foreach my $configfilename (@configfilenames) { # Load GIMP's printer config file my $configfilecontent = readconfigfile($configfilename); # Update local printer queues foreach my $queue (keys(%{$printer->{configured}})) { # Check if we have a PPD file if (! -r "$::prefix/etc/foomatic/$queue.ppd") { if (-r "$::prefix/etc/cups/ppd/$queue.ppd") { # If we have a PPD file in the CUPS config dir, link to it run_program::rooted($::prefix, "ln", "-sf", "/etc/cups/ppd/$queue.ppd", "/etc/foomatic/$queue.ppd"); } elsif (-r "$::prefix/usr/share/postscript/ppd/$queue.ppd") { # Check PPD directory of GPR, too run_program::rooted ($::prefix, "ln", "-sf", "/usr/share/postscript/ppd/$queue.ppd", "/etc/foomatic/$queue.ppd"); } else { # No PPD file at all? We cannot set up this printer next; } } # Add the printer entry if (!isprinterconfigured ($queue, $configfilecontent)) { # Remove the old printer entry $configfilecontent = removeprinter($queue, $configfilecontent); # Add the new printer entry $configfilecontent = makeprinterentry($printer, $queue, $configfilecontent); } } # Default printer if ($printer->{DEFAULT}) { if ($configfilecontent !~ /^\s*Current\-Printer\s*:/m) { $configfilecontent =~ s/\n/\nCurrent-Printer: $printer->{DEFAULT}\n/s; } else { $configfilecontent =~ /^\s*Current\-Printer\s*:\s*(\S+)\s*$/m; if (!isprinterconfigured ($1, $configfilecontent)) { $configfilecontent =~ s/(Current\-Printer\s*:\s*)\S+/$1$printer->{DEFAULT}/; } } } # Write back GIMP's printer configuration file writeconfigfile($configfilename, $configfilecontent); } return 1; } sub addcupsremoteto { my ($printer, $queue) = @_; # Do we have files to treat? my @configfilenames = findconfigfiles(); return 1 if $#configfilenames < 0; my @printerlist = printer::cups::get_remote_queues(); my $ppdfile = ""; if ($printer->{SPOOLER} eq "cups" && ((-x "$::prefix/usr/bin/curl") || (-x "$::prefix/usr/bin/wget"))) { foreach my $listentry (@printerlist) { next if !($listentry =~ /^([^\|]+)\|([^\|]+)$/); my $q = $1; next if $q ne $queue; my $server = $2; # Remove server name from queue name $q =~ s/^([^@]*)@.*$/$1/; if (-x "$::prefix/usr/bin/wget") { eval(run_program::rooted ($::prefix, "/usr/bin/wget", "-O", "/etc/foomatic/$queue.ppd", "http://$server:631/printers/$q.ppd")); } else { eval(run_program::rooted ($::prefix, "/usr/bin/curl", "-o", "/etc/foomatic/$queue.ppd", "http://$server:631/printers/$q.ppd")); } # Does the file exist and is it not an error message? if ((-r "$::prefix/etc/foomatic/$queue.ppd") && cat_("$::prefix/etc/foomatic/$queue.ppd") =~ /^\*PPD-Adobe/) { $ppdfile = "/etc/foomatic/$queue.ppd"; } else { unlink "$::prefix/etc/foomatic/$queue.ppd"; return 0; } } } else { return 1 } # There is no system-wide config file, treat every user's config file foreach my $configfilename (@configfilenames) { # Load GIMP's printer config file my $configfilecontent = readconfigfile($configfilename); # Add the printer entry if (!isprinterconfigured ($queue, $configfilecontent)) { # Remove the old printer entry $configfilecontent = removeprinter($queue, $configfilecontent); # Add the new printer entry $configfilecontent = makeprinterentry($printer, $queue, $configfilecontent); } # Write back GIMP's printer configuration file writeconfigfile($configfilename, $configfilecontent); } return 1; } sub removeprinterfrom { my ($printer, $queue) = @_; # Do we have files to treat? my @configfilenames = findconfigfiles(); return 1 if $#configfilenames < 0; # There is no system-wide config file, treat every user's config file foreach my $configfilename (@configfilenames) { # Load GIMP's printer config file my $configfilecontent = readconfigfile($configfilename); # Remove the printer entry $configfilecontent = removeprinter($queue, $configfilecontent); # Write back GIMP's printer configuration file writeconfigfile($configfilename, $configfilecontent); } return 1; } sub removelocalprintersfrom { my ($printer) = @_; # Do we have files to treat? my @configfilenames = findconfigfiles(); return 1 if $#configfilenames < 0; # There is no system-wide config file, treat every user's config file foreach my $configfilename (@configfilenames) { # Load GIMP's printer config file my $configfilecontent = readconfigfile($configfilename); # Remove the printer entries foreach my $queue (keys(%{$printer->{configured}})) { $configfilecontent = removeprinter($queue, $configfilecontent); } # Write back GIMP's printer configuration file writeconfigfile($configfilename, $configfilecontent); } return 1; } sub makeprinterentry { my ($printer, $queue, $configfile) = @_; # Make printer's section $configfile = addprinter($queue, $configfile); # Load PPD file my $ppd = cat_("$::prefix/etc/foomatic/$queue.ppd"); # Is the printer configured with GIMP-Print? my $gimpprintqueue = 0; my $gimpprintdriver = "ps2"; if ($ppd =~ /CUPS\s*\+\s*GIMP\s*\-\s*Print/im) { # Native CUPS driver $gimpprintqueue = 1; $ppd =~ /\s*\*ModelName:\s*\"(\S+)\"\s*$/im; $gimpprintdriver = $1; } elsif ($ppd =~ /Foomatic\s*\+\s*gimp\s*\-\s*print/im) { # GhostScript + Foomatic driver $gimpprintqueue = 1; $ppd =~ /'idx'\s*=>\s*'ev\/gimp-print-((escp2|pcl|bjc|lexmark)\-\S*)'/im; $gimpprintdriver = $1; } if ($gimpprintqueue) { # Get the paper size from the PPD file if ($ppd =~ /^\s*\*DefaultPageSize:\s*(\S+)\s*$/m) { my $papersize = $1; $configfile = removeentry($queue, "Media-Size", $configfile); $configfile = addentry($queue, "Media-Size: $papersize", $configfile); } $configfile = removeentry($queue, "PPD-File:", $configfile); $configfile = addentry($queue, "PPD-File:", $configfile); $configfile = removeentry($queue, "Driver:", $configfile); $configfile = addentry($queue, "Driver: $gimpprintdriver", $configfile); $configfile = removeentry($queue, "Destination:", $configfile); $configfile = addentry($queue, "Destination: /usr/bin/$spoolers{$printer->{SPOOLER}{print_command}} -P $queue -o raw", $configfile); } else { $configfile = removeentry($queue, "PPD-File:", $configfile); $configfile = addentry($queue, "PPD-File: /etc/foomatic/$queue.ppd", $configfile); $configfile = removeentry($queue, "Driver:", $configfile); $configfile = addentry($queue, "Driver: ps2", $configfile); $configfile = removeentry($queue, "Destination:", $configfile); $configfile = addentry($queue, "Destination: /usr/bin/$spoolers{$printer->{SPOOLER}{print_command}} -P $queue", $configfile); } return $configfile; } sub findconfigfiles { my @configfilenames; push (@configfilenames, ".gimp-1.2/printrc") if -d "$::prefix/usr/lib/gimp/1.2"; push (@configfilenames, ".gimp-1.3/printrc") if -d "$::prefix/usr/lib/gimp/1.3"; my @filestotreat; local *PASSWD; open PASSWD, "< $::prefix/etc/passwd" or die "Cannot read /etc/passwd!\n"; local $_; while () { chomp; if (/^([^:]+):[^:]*:([^:]+):([^:]+):[^:]*:([^:]+):[^:]*$/) { my ($username, $uid, $gid, $homedir) = ($1, $2, $3, $4); if (($uid == 0 || $uid >= 500) && $username ne "nobody") { foreach my $file (@configfilenames) { my $dir = "$homedir/$file"; $dir =~ s,/[^/]*$,,; next if (-f $dir) && ! -d $dir; if (! -d "$::prefix$dir") { mkdir_p("$::prefix$dir") or next; set_permissions("$::prefix$dir", "$uid.$gid") or next; } if (! -f "$::prefix$homedir/$file") { local *F; open F, "> $::prefix$homedir/$file" or next; print F "#PRINTRCv1 written by GIMP-PRINT 4.2.2 - 13 Sep 2002\n"; close F; set_permissions("$::prefix$homedir/$file", "$uid.$gid") or next; } push (@filestotreat, "$homedir/$file"); } } } } @filestotreat; } sub readconfigfile { my ($file) = @_; local *F; open F, "< $::prefix$file" or return ""; my $filecontent = join("", ); close F; return $filecontent; } sub writeconfigfile { my ($file, $filecontent) = @_; local *F; open F, "> $::prefix$file" or return 0; print F $filecontent; close F; return 1; } sub addentry { my ($section, $entry, $filecontent) = @_; my $sectionfound = 0; my $entryinserted = 0; my @lines = split("\n", $filecontent); foreach (@lines) { if (!$sectionfound) { $sectionfound = 1 if /^\s*Printer\s*:\s*($section)\s*$/; } else { if (!/^\s*$/ && !/^\s*;/) { #-# $_ = "$entry\n$_"; $entryinserted = 1; last; } } } push(@lines, $entry) if $sectionfound && !$entryinserted; return join ("\n", @lines); } sub addprinter { my ($section, $filecontent) = @_; my $entryinserted = 0; my @lines = split("\n", $filecontent); foreach (@lines) { # section already there, nothing to be done return $filecontent if /^\s*Printer\s*:\s*($section)\s*$/; } return $filecontent . "\nPrinter: $section"; } sub removeentry { my ($section, $entry, $filecontent) = @_; my $sectionfound = 0; my $done = 0; my @lines = split("\n", $filecontent); foreach (@lines) { $_ = "$_\n"; next if $done; if (!$sectionfound) { if (/^\s*Printer\s*:\s*($section)\s*$/) { $sectionfound = 1; } } else { if (/^\s*Printer\s*:\s*.*\s*$/) { # Next section $done = 1; } elsif (/^\s*$entry/) { $_ = ""; $done = 1; } } } return join ("", @lines); } sub removeprinter { my ($section, $filecontent) = @_; my $sectionfound = 0; my $done = 0; my @lines = split("\n", $filecontent); foreach (@lines) { $_ = "$_\n"; next if $done; if (!$sectionfound) { if (/^\s*Printer\s*:\s*($section)\s*$/) { $_ = ""; $sectionfound = 1; } } else { if (/^\s*Printer\s*:\s*.*\s*$/) { # Next section $done = 1; } else { $_ = ""; } } } return join ("", @lines); } sub isprinterconfigured { my ($queue, $filecontent) = @_; my $sectionfound = 0; my $done = 0; my $drivernotps2 = 0; my $ppdfileset = 0; my $nonrawprinting = 0; my @lines = split("\n", $filecontent); foreach (@lines) { last if $done; if (!$sectionfound) { if (/^\s*Printer\s*:\s*($queue)\s*$/) { $sectionfound = 1; } } else { if (/^\s*Printer\s*:\s*.*\s*$/) { # Next section $done = 1; } elsif (/^\s*Driver:\s*(\S+)\s*$/) { $drivernotps2 = ($1 ne "ps2"); } elsif (/^\s*PPD\-File:\s*(\S+)\s*$/) { $ppdfileset = 1; } elsif (/^\s*Destination:\s*(\S+.*)$/) { $nonrawprinting = ($1 !~ /\-o\s*raw/); } } } return 0 if $done && !$sectionfound; return 1 if $ppdfileset || $drivernotps2 || $nonrawprinting; return 0; } # ------------------------------------------------------------------ 1;