diff options
Diffstat (limited to 'perl-install/printer')
-rw-r--r-- | perl-install/printer/detect.pm | 27 | ||||
-rw-r--r-- | perl-install/printer/main.pm | 440 | ||||
-rw-r--r-- | perl-install/printer/printerdrake.pm | 316 |
3 files changed, 708 insertions, 75 deletions
diff --git a/perl-install/printer/detect.pm b/perl-install/printer/detect.pm index abc6f2bc7..4645d94de 100644 --- a/perl-install/printer/detect.pm +++ b/perl-install/printer/detect.pm @@ -101,6 +101,33 @@ sub whatNetPrinter { @res; } +sub getNetworkInterfaces { + + # subroutine determines the list of all network interfaces reported + # by "ifconfig", except "lo". + + # Return an empty list if no network is running + return () unless network_running(); + + my @interfaces; + + local *IFCONFIG_OUT; + open IFCONFIG_OUT, ($::testing ? "" : "chroot $::prefix/ ") . + "/bin/sh -c \"export LC_ALL=C; ifconfig\" |" or return (); + while (my $readline = <IFCONFIG_OUT>) { + # New entry ... + if ($readline =~ /^(\S+)\s/) { + my $dev = $1; + if ($dev ne "lo") { + push (@interfaces, $dev); + } + } + } + close(IFCONFIG_OUT); + + @interfaces; +} + sub getIPsInLocalNetworks { # subroutine determines the list of all hosts reachable in the local diff --git a/perl-install/printer/main.pm b/perl-install/printer/main.pm index 5981fa744..7c9930950 100644 --- a/perl-install/printer/main.pm +++ b/perl-install/printer/main.pm @@ -667,8 +667,35 @@ sub get_cups_autoconf { sub set_usermode { my $usermode = $_[0]; $::expert = $usermode; - my $str = $usermode ? "expert" : "recommended"; - substInFile { s/^(USER_MODE=).*/$1$str/; $_ .= "USER_MODE=$str" if eof } "$::prefix/etc/sysconfig/printing"; + + # Read config file + local *F; + my $file = "$::prefix/etc/sysconfig/printing"; + my @file_content; + if (!(-f $file)) { + @file_content = (); + } else { + open F, "< $file" or die "Cannot open $file!"; + @file_content = <F>; + close F; + } + + # Remove all valid "USER_MODE" lines + (/^\s*USER_MODE/ and $_ = "") foreach @file_content; + + # Insert the new "USER_MODE" line + if ($usermode) { + push @file_content, "USER_MODE=expert\n"; + } else { + push @file_content, "USER_MODE=recommended\n"; + } + + # Write back modified file + open F, "> $file" or die "Cannot open $file!"; + print F @file_content; + close F; + + return 1; } sub get_usermode { @@ -706,6 +733,24 @@ sub read_directives { return @result; } +sub read_unique_directive { + + # Read a directive from the from the cupsd.conf file or from a + # ripped-out location block, if the directive appears more than once, + # use the last occurence and remove all the others, if it does not + # occur, return the default value + + my ($lines_ptr, $directive, $default) = @_; + + if ((my @d = read_directives($lines_ptr, $directive)) > 0) { + my $value = @d[$#d]; + set_directive($lines_ptr, "$directive $value"); + return $value; + } else { + return $default; + } +} + sub insert_directive { # Insert a directive into the cupsd.conf file or into a ripped-out @@ -739,9 +784,6 @@ sub replace_directive { my ($lines_ptr, $olddirective, $newdirective) = @_; - # Do not do the replacement when the new directive already exists - ($_ =~ /^\s*$newdirective$/ and return 0) foreach @{$lines_ptr}; - $newdirective = "$newdirective\n"; my $success = 0; ($_ =~ /^\s*$olddirective/ and $_ = $newdirective and @@ -757,7 +799,7 @@ sub set_directive { my ($cupsd_conf_ptr, $directive) = @_; my $olddirective = $directive; - $olddirective =~ s/^\s*(\S+)\s+.*$/$1/; + $olddirective =~ s/^\s*(\S+)\s+.*$/$1/s; return (replace_directive($cupsd_conf_ptr, $olddirective, $directive) or @@ -843,7 +885,7 @@ sub rip_location { splice(@{$cupsd_conf_ptr},$location_start, $location_end - $location_start + 1); } else { - # If there is no root location block, create one + # If there is no location block, create one $location_start = $#{$cupsd_conf_ptr} + 1; @location = (); push @location, "<Location $path>\n"; @@ -930,6 +972,390 @@ sub replace_allowed_host { "Allow From $newhost")); } +sub broadcastaddress { + + # Determines the broadcast address (for "BrowseAddress" line) for + # a given network IP + + my ($address) = @_; + + if ($address =~ /^\d+\.\*$/) { + $address =~ s/\*$/255.255.255/; + } elsif ($address =~ /^\d+\.\d+\.\*$/) { + $address =~ s/\*$/255.255/; + } elsif ($address =~ /^\d+\.\d+\.\d+\.\*$/) { + $address =~ s/\*$/255/; + } elsif ($address =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)$/) { + my $numadr = ($1 << 24) + ($2 << 16) + ($3 << 8) + $4; + my $mask = ((1 << $5) - 1) << (32 - $5); + my $broadcast = $numadr | (~$mask); + $address = + (($broadcast & (255 << 24)) >> 24) . '.' . + (($broadcast & (255 << 16)) >> 16) . '.' . + (($broadcast & (255 << 8)) >> 8) . '.' . + ($broadcast & 255); + } elsif ($address =~ + /^(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)\.(\d+)\.(\d+)\.(\d+)$/) { + my $numadr = ($1 << 24) + ($2 << 16) + ($3 << 8) + $4; + my $mask = ($5 << 24) + ($6 << 16) + ($7 << 8) + $8; + my $broadcast = $numadr | (~$mask); + $address = + (($broadcast & (255 << 24)) >> 24) . '.' . + (($broadcast & (255 << 16)) >> 16) . '.' . + (($broadcast & (255 << 8)) >> 8) . '.' . + ($broadcast & 255); + } + + return $address; +} + +sub networkaddress { + + # Guesses a network address for a given broadcast address + + my ($address) = @_; + + if ($address =~ /\.255$/) { + while ($address =~ s/\.255$//) {}; + $address .= ".*"; + } + + return $address; +} + +sub localprintersshared { + + # Do we broadcast our local printers + + my ($printer) = @_; + + return (($printer->{cupsconfig}{keys}{Browsing} !~ /off/i) && + ($printer->{cupsconfig}{keys}{BrowseInterval} != 0) && + ($#{$printer->{cupsconfig}{keys}{BrowseAddress}} >= 0)); +} + +sub remotebroadcastsaccepted { + + # Do we accept broadcasts from remote CUPS servers? + + my ($printer) = @_; + + # Is browsing not turned on at all? + if ($printer->{cupsconfig}{keys}{Browsing} =~ /off/i) { + return 0; + } + + # No "BrowseDeny" lines at all + if ($#{$printer->{cupsconfig}{keys}{BrowseDeny}} < 0) { + return 1; + } + + my $havedenyall = + (join('', @{$printer->{cupsconfig}{keys}{BrowseDeny}}) =~ + /All/im); + my $havedenylocal = + (join('', @{$printer->{cupsconfig}{keys}{BrowseDeny}}) =~ + /\@LOCAL/im); + my $orderallowdeny = + ($printer->{cupsconfig}{keys}{BrowseOrder} =~ + /allow\s*,\s*deny/i); + my $haveallowremote = 0; + for my $allowline (@{$printer->{cupsconfig}{keys}{BrowseAllow}}) { + next if + ($allowline =~ /^\s*(localhost|0*127\.0+\.0+\.0*1|none)\s*$/i); + $haveallowremote = 1; + } + + # A line denying all (or at least the all LANs) together with the order + # "allow,deny" or without "BrowseAllow" lines (which allow the + # broadcasts of at least one remote resource). + if (($havedenyall || $havedenylocal) && + ($orderallowdeny || !$haveallowremote)) { + return 0; + } + + return 1; +} + +sub clientnetworks { + + # Determine the client networks to which the printers will be + # shared If the configuration is supported by our simplified + # interface ("Deny From All", "Order Deny,Allow", "Allow From ..." + # lines in "<location /> ... </location>", a "BrowseAddress ..." + # line for each "Allow From ..." line), return the list of allowed + # client networks ("Allow"/"BrowseAddress" lines), if not, return + # the list of all items which are at least one of the + # "BrowseAddresse"s or one of the "Allow From" addresses together + # with a flag that the setup is not supported. + + my ($printer) = @_; + + # Check for a "Deny From All" line + my $havedenyfromall = + (join('', @{$printer->{cupsconfig}{root}{DenyFrom}}) =~ + /All/im); + + # Check for "Order Deny,Allow" + my $orderdenyallow = + ($printer->{cupsconfig}{root}{Order} =~ + /deny\s*,\s*allow/i); + + my @sharehosts; + my $haveallowfromlocalhost = 0; + my $haveallowedhostwithoutbrowseaddress = 0; + + # Go through all "Allow From" lines + for my $line (@{$printer->{cupsconfig}{root}{AllowFrom}}) { + if ($line =~ /^\s*(localhost|0*127\.0+\.0+\.0*1)\s*$/i) { + # Line pointing to localhost + $haveallowfromlocalhost = 1; + } elsif ($line =~ /^\s*(none)\s*$/i) { + # Skip "Allow From None" lines + } elsif (!member($line, @sharehosts)) { + # Line pointing to remote server + push(@sharehosts, $line); + if (!member(broadcastaddress($line), + @{$printer->{cupsconfig}{keys}{BrowseAddress}})) { + $haveallowedhostwithoutbrowseaddress = 1; + } + } + } + my $havebrowseaddresswithoutallowedhost = 0; + # Go through all "BrowseAdress" lines + for my $line (@{$printer->{cupsconfig}{keys}{BrowseAddress}}) { + if ($line =~ /^\s*(localhost|0*127\.0+\.0+\.0*1)\s*$/i) { + # Skip lines pointing to localhost + } elsif ($line =~ /^\s*(none)\s*$/i) { + # Skip "Allow From None" lines + } elsif (!member($line, map {broadcastaddress($_)} @sharehosts)) { + # Line pointing to remote server + push(@sharehosts, networkaddress($line)); + $havebrowseaddresswithoutallowedhost = 1; + } + } + + my $configunsupported = (!$havedenyfromall || !$orderdenyallow || + !$haveallowfromlocalhost || + $haveallowedhostwithoutbrowseaddress || + $havebrowseaddresswithoutallowedhost); + + return ($configunsupported, @sharehosts); +} + +sub makesharehostlist { + + # Human-readable strings for hosts onto which the local printers + # are shared + + my ($printer) = @_; + + my @sharehostlist; + my %sharehosthash; + for my $host (@{$printer->{cupsconfig}{clientnetworks}}) { + if ($host =~ /\@LOCAL/i) { + $sharehosthash{$host} = N("Local network(s)"); + } elsif ($host =~ /\@IF\((.*)\)/i) { + $sharehosthash{$host} = N("Interface \"%s\"", $1); + } elsif ($host =~ /(\/|^\*|\*$|^\.)/i) { + $sharehosthash{$host} = N("Network %s", $host); + } else { + $sharehosthash{$host} = N("Host %s", $host); + } + push(@sharehostlist, $sharehosthash{$host}); + } + my %sharehosthash_inv = reverse %sharehosthash; + + return { list => \@sharehostlist, + hash => \%sharehosthash, + invhash => \%sharehosthash_inv }; +} + +sub is_network_ip { + + # Determine whwther the given string is a valid network IP + + my ($address) = @_; + + ($address =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) || + ($address =~ /^(\d+\.){1,3}\*$/) || + ($address =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)$/) || + ($address =~ + /^(\d+)\.(\d+)\.(\d+)\.(\d+)\/(\d+)\.(\d+)\.(\d+)\.(\d+)$/); + +} + +sub read_cups_config { + + # Read the information relevant to the printer sharing dialog from + # the CUPS configuration + + my ($printer) = @_; + + # From /etc/cups/cupsd.conf + + # Keyword "Browsing" + $printer->{cupsconfig}{keys}{Browsing} = + read_unique_directive($printer->{cupsconfig}{cupsd_conf}, + 'Browsing', 'On'); + + # Keyword "BrowseInterval" + $printer->{cupsconfig}{keys}{BrowseInterval} = + read_unique_directive($printer->{cupsconfig}{cupsd_conf}, + 'BrowseInterval', '30'); + + # Keyword "BrowseAddress" + @{$printer->{cupsconfig}{keys}{BrowseAddress}} = + read_directives($printer->{cupsconfig}{cupsd_conf}, + 'BrowseAddress'); + + # Keyword "BrowseAllow" + @{$printer->{cupsconfig}{keys}{BrowseAllow}} = + read_directives($printer->{cupsconfig}{cupsd_conf}, + 'BrowseAllow'); + + # Keyword "BrowseDeny" + @{$printer->{cupsconfig}{keys}{BrowseDeny}} = + read_directives($printer->{cupsconfig}{cupsd_conf}, + 'BrowseDeny'); + + # Keyword "BrowseOrder" + $printer->{cupsconfig}{keys}{BrowseOrder} = + read_unique_directive($printer->{cupsconfig}{cupsd_conf}, + 'BrowseOrder', 'deny,allow'); + + # Root location + @{$printer->{cupsconfig}{rootlocation}} = + read_location($printer->{cupsconfig}{cupsd_conf}, '/'); + + # Keyword "Allow from" + @{$printer->{cupsconfig}{root}{AllowFrom}} = + read_directives($printer->{cupsconfig}{rootlocation}, + 'Allow From'); + + # Keyword "Deny from" + @{$printer->{cupsconfig}{root}{DenyFrom}} = + read_directives($printer->{cupsconfig}{rootlocation}, + 'Deny From'); + + # Keyword "Order" + $printer->{cupsconfig}{root}{Order} = + read_unique_directive($printer->{cupsconfig}{rootlocation}, + 'Order', 'Deny,Allow'); + + # Widget settings + + # Local printers available to other machines? + $printer->{cupsconfig}{localprintersshared} = + localprintersshared($printer); + + # This machine is accepting printers shared by remote machines? + $printer->{cupsconfig}{remotebroadcastsaccepted} = + remotebroadcastsaccepted($printer); + + # To which machines are the local printers available? + ($printer->{cupsconfig}{customsharingsetup}, + @{$printer->{cupsconfig}{clientnetworks}}) = + clientnetworks($printer); + +} + +sub write_cups_config { + + # Write the information edited via the printer sharing dialog into + # the CUPS configuration + + my ($printer) = @_; + + # Local printers available to other machines? + if ($printer->{cupsconfig}{localprintersshared}) { + set_directive($printer->{cupsconfig}{cupsd_conf}, + 'Browsing On'); + if ($printer->{cupsconfig}{keys}{BrowseInterval} == 0) { + set_directive($printer->{cupsconfig}{cupsd_conf}, + 'BrowseInterval 30'); + } + } else { + set_directive($printer->{cupsconfig}{cupsd_conf}, + 'BrowseInterval 0'); + } + + # This machine is accepting printers shared by remote machines? + if ($printer->{cupsconfig}{remotebroadcastsaccepted}) { + set_directive($printer->{cupsconfig}{cupsd_conf}, + 'Browsing On'); + if (($printer->{cupsconfig}{localprintersshared}) && + ($#{$printer->{cupsconfig}{clientnetworks}} > 0) && + (!$printer->{cupsconfig}{customsharingsetup})) { + # If we broadcast our printers, let's accept the broadcasts + # from the machines to which we broadcast + set_directive($printer->{cupsconfig}{cupsd_conf}, + 'BrowseDeny All'); + set_directive($printer->{cupsconfig}{cupsd_conf}, + 'BrowseOrder Deny,Allow'); + set_directive($printer->{cupsconfig}{cupsd_conf}, + 'BrowseAllow ' . + join ("\nBrowseAllow ", + @{$printer->{cupsconfig}{clientnetworks}})); + } elsif (!remotebroadcastsaccepted($printer)) { + # Use default settings if the "BrowseDeny"/"BrowseAllow" + # configuration does not accept broadcasts + set_directive($printer->{cupsconfig}{cupsd_conf}, + 'BrowseDeny All'); + set_directive($printer->{cupsconfig}{cupsd_conf}, + 'BrowseOrder Deny,Allow'); + set_directive($printer->{cupsconfig}{cupsd_conf}, + 'BrowseOrder @LOCAL'); + } + } else { + # Deny all broadcasts, but leave all "BrowseAllow" lines + # untouched + set_directive($printer->{cupsconfig}{cupsd_conf}, + 'BrowseDeny All'); + set_directive($printer->{cupsconfig}{cupsd_conf}, + 'BrowseOrder Allow,Deny'); + } + + # To which machines are the local printers available? + if (!$printer->{cupsconfig}{customsharingsetup}) { + # root location block + @{$printer->{cupsconfig}{rootlocation}} = + "<Location />\n" . + "Order Deny,Allow\n" . + "Deny From All\n" . + "Allow From 127.0.0.1\n" . + "Allow From " . + join ("\nAllow From ", + @{$printer->{cupsconfig}{clientnetworks}}) . + "\n" . + "</Location>\n"; + my ($location_start, @location) = + rip_location($printer->{cupsconfig}{cupsd_conf}, "/"); + insert_location($printer->{cupsconfig}{cupsd_conf}, $location_start, + @{$printer->{cupsconfig}{rootlocation}}); + # "BrowseAddress" lines + set_directive($printer->{cupsconfig}{cupsd_conf}, + 'BrowseAddress ' . + join ("\nBrowseAddress ", + map {broadcastaddress($_)} + @{$printer->{cupsconfig}{clientnetworks}})); + } + +} + +sub clean_cups_config { + + # Clean $printer data structure from all settings not related to + # the CUPS printer sharing dialog + + my ($printer) = @_; + + delete $printer->{cupsconfig}{keys}; + delete $printer->{cupsconfig}{root}; + delete $printer->{cupsconfig}{cupsd_conf}; + delete $printer->{cupsconfig}{rootlocation}; +} + #---------------------------------------------------------------------- sub read_printers_conf { my ($printer) = @_; diff --git a/perl-install/printer/printerdrake.pm b/perl-install/printer/printerdrake.pm index b85bd1318..2d7b24787 100644 --- a/perl-install/printer/printerdrake.pm +++ b/perl-install/printer/printerdrake.pm @@ -61,77 +61,257 @@ sub config_cups { # when "Apply" was at least pressed once. my $retvalue = 0; # Read CUPS config file - my @cupsd_conf = printer::main::read_cupsd_conf(); - foreach (@cupsd_conf) { - /^\s*BrowsePoll\s+(\S+)/ and $server = $1, last; - } - $server =~ /([^:]*):(.*)/ and ($server, $port) = ($1, $2); - #- Did we have automatic or manual configuration mode for CUPS - $autoconf = printer::main::get_cups_autoconf(); - #- Remember the server/port/autoconf settings to check whether the user - #- has changed them. - my $oldserver = $server; - my $oldport = $port; - my $oldautoconf = $autoconf; - - #- then ask user for this combination and rewrite /etc/cups/cupsd.conf - #- according to new settings. There are no other point where such - #- information is written in this file. - - if ($in->ask_from_( - { title => ($::expert ? N("CUPS configuration") : - N("Specify CUPS server")), - messages => N("To get access to printers on remote CUPS servers in your local network you do not have to configure anything; the CUPS servers inform your machine automatically about their printers. All printers currently known to your machine are listed in the \"Remote printers\" section in the main window of Printerdrake. When your CUPS server is not in your local network, you have to enter the CUPS server IP address and optionally the port number to get the printer information from the server, otherwise leave these fields blank.") . - if_($::expert, "\n" . N(" -Normally, CUPS is automatically configured according to your network environment, so that you can access the printers on the CUPS servers in your local network. If this does not work correctly, turn off \"Automatic CUPS configuration\" and edit your file /etc/cups/cupsd.conf manually. Do not forget to restart CUPS afterwards (command: \"service cups restart\").")), - callbacks => { complete => sub { - if ($server && !network::is_ip($server)) { - $in->ask_warn('', N("The IP address should look like 192.168.1.20")); - return (1,0); - } - if ($port !~ /^\d*$/) { - $in->ask_warn('', N("The port number should be an integer!")); - return (1,1); - } - return 0; - } } - }, - [ - { label => N("CUPS server IP"), val => \$server }, - { label => N("Port"), val => \$port }, - if_($::expert, - { text => N("Automatic CUPS configuration"), type => 'bool', - val => \$autoconf }), - ] - )) { - # We have clicked "OK" - $retvalue = 1; - # Set BrowsePoll line - if ($server ne $oldserver || $port ne $oldport) { - $server && $port and $server = "$server:$port"; - if ($server) { - @cupsd_conf = - map { $server and - s/^\s*BrowsePoll\s+(\S+)/BrowsePoll $server/ and - $server = ''; - $_ } @cupsd_conf; - $server and push @cupsd_conf, "\nBrowsePoll $server\n"; + @{$printer->{cupsconfig}{cupsd_conf}} = + printer::main::read_cupsd_conf(); + printer::main::read_cups_config($printer); + # Read state for auto-correction of cupsd.conf + $printer->{cupsconfig}{autocorrection} = + printer::main::get_cups_autoconf(); + # Human-readable strings for hosts onto which the local printers + # are shared + my $maindone; + while (!$maindone) { + my $sharehosts = printer::main::makesharehostlist($printer); + my $buttonclicked; + #- Show dialog + if ($in->ask_from_ + ( + { + title => N("CUPS printer sharing configuration"), + messages => N("Here you can choose whether the printers connected to this machine should be accessable by remote machines and by which remote machines.") . + N("You can also decide here whether printers on remote machines should be automatically made available on this machine."), + }, + [ + { text => N("The printers on this machine are available to other computers"), type => 'bool', + val => \$printer->{cupsconfig}{localprintersshared} }, + { val => N("Local printers available on: ") . + ($printer->{cupsconfig}{customsharingsetup} ? + N("Custom configuration") : + ($#{$sharehosts->{list}} >= 0 ? + ($#{$sharehosts->{list}} > 1 ? + join (", ", @{$sharehosts->{list}}[0,1]) . " ..." : + join (", ", @{$sharehosts->{list}})) : + N("No remote machines"))), + type => 'button', + clicked_may_quit => sub { + $buttonclicked = "sharehosts"; + 1; + }, + disabled => sub { + (!$printer->{cupsconfig}{localprintersshared}); + }}, + { text => N("Automatically find available printers on remote machines"), type => 'bool', + val => \$printer->{cupsconfig}{remotebroadcastsaccepted} }, + if_($::expert, + { text => N("Automatic correction of CUPS configuration"), + type => 'bool', + help => N("When this option is turned on, on every startup of CUPS is automatically made sure that + +- if LPD/LPRng is installed, /etc/printcap will not be overwritten by CUPS + +- if /etc/cups/cupsd.conf is missing, it will be created + +- when printer information is broadcasted, it does not contain \"localhost\" as the server name. + +If some of these measures lead to problems for you, turn this option off, but then you have to take care of these points."), + val => \$printer->{cupsconfig}{autocorrection} }), + ] + ) + ) { + if ($buttonclicked eq "sharehosts") { + # Show dialog to add hosts to share printers to + my $subdone = 0; + my $choice; + while (!$subdone) { + # Entry should be edited when double-clicked + $buttonclicked = "edit"; + $in->ask_from_ + ( + { title => N("Sharing of local printers"), + messages => N("These are the machines and networks on which the locally connected printer(s) should be available:"), + ok => "", + cancel => "", + }, + # List the hosts + [ { val => \$choice, format => \&translate, + sort => 0, separator => "#####", + tree_expanded => 1, + quit_if_double_click => 1, + allow_empty_list => 1, + list => $sharehosts->{list} }, + { val => N("Add host/network"), + type => 'button', + clicked_may_quit => sub { + $buttonclicked = "add"; + 1; + }}, + { val => N("Edit selected host/network"), + type => 'button', + clicked_may_quit => sub { + $buttonclicked = "edit"; + 1; + }, + disabled => sub { + return ($#{$sharehosts->{list}} < 0); + }}, + { val => N("Remove selected host/network"), + type => 'button', + clicked_may_quit => sub { + $buttonclicked = "remove"; + 1; + }, + disabled => sub { + return ($#{$sharehosts->{list}} < 0); + }}, + { val => N("Done"), + type => 'button', + clicked_may_quit => sub { + $buttonclicked = ""; + $subdone = 1; + 1; + }}, + ] + ); + if (($buttonclicked eq "add") || + ($buttonclicked eq "edit")) { + my ($hostchoice, $ip); + if ($buttonclicked eq "add") { + # Use first entry as default for a new entry + $hostchoice = N("Local network(s)"); + } else { + if ($sharehosts->{invhash}{$choice} =~ /^\@/) { + # Entry to edit is not an IP address + $hostchoice = $choice; + } else { + # Entry is an IP address + $hostchoice = + N("IP address of host/network:"); + $ip = $sharehosts->{invhash}{$choice}; + } + } + my @menu = (N("Local network(s)")); + my @interfaces = + printer::detect::getNetworkInterfaces(); + for my $interface (@interfaces) { + push (@menu, + (N("Interface \"%s\"", $interface))); + } + push (@menu, N("IP address of host/network:")); + # Show the dialog + print "##### |@menu|$hostchoice|\n"; + my $address; + my $oldaddress = + ($buttonclicked eq "edit" ? + $sharehosts->{invhash}{$choice} : ""); + if ($in->ask_from_ + ( + { title => N("Sharing of local printers"), + messages => N("Choose the network or host on which the local printers should be made available:"), + callbacks => { + complete => sub { + if (($hostchoice eq + N("IP address of host/network:")) && + (!printer::main::is_network_ip($ip))) { + + $in->ask_warn('', +N("The entered host/network IP is not correct.\n") . +N("Examples for correct IPs:\n") . +N("192.168.100.194\n") . +N("10.0.0.*\n") . +N("10.1.*\n") . +N("192.168.100.0/24\n") . +N("192.168.100.0/255.255.255.0\n") +); + return (1,0); + } + if ($hostchoice eq $menu[0]) { + $address = "\@LOCAL"; + } elsif ($hostchoice eq + $menu[$#menu]) { + $address = $ip; + } else { + ($address) = + grep {$hostchoice =~ /$_/} + @interfaces; + $address = "\@IF($address)"; + } + # Check whether item is duplicate + if (($address ne $oldaddress) && + (member($address, + @{$printer->{cupsconfig}{clientnetworks}}))) { + $in->ask_warn('', + N("This host/network is already in the list, it cannot be added again.\n")); + return (1,1); + } + return 0; + }, + }, + }, + # List the host types + [ { val => \$hostchoice, format => \&translate, + type => 'list', + sort => 0, + list => \@menu }, + { val => \$ip, + disabled => sub { + $hostchoice ne + N("IP address of host/network:"); + }}, + ], + )) { + # OK was clicked, insert new item into the list + if ($buttonclicked eq "add") { + push(@{$printer->{cupsconfig}{clientnetworks}}, + $address); + } else { + @{$printer->{cupsconfig}{clientnetworks}} = + map {($_ eq + $sharehosts->{invhash}{$choice} ? + $address : $_)} + @{$printer->{cupsconfig}{clientnetworks}}; + } + # Refresh list of hosts + $sharehosts = + printer::main::makesharehostlist($printer); + # We have modified the configuration now + $printer->{cupsconfig}{customsharingsetup} = 0; + # Position the list cursor on the new/modified + # item + $choice = $sharehosts->{hash}{$address}; + } + } elsif ($buttonclicked eq "remove") { + @{$printer->{cupsconfig}{clientnetworks}} = + grep {$_ ne $sharehosts->{invhash}{$choice}} + @{$printer->{cupsconfig}{clientnetworks}}; + # Refresh list of hosts + $sharehosts = + printer::main::makesharehostlist($printer); + # We have modified the configuration now + $printer->{cupsconfig}{customsharingsetup} = 0; + } + # If we have no entry in the list, we do not + # share the local printers, mark this + $printer->{cupsconfig}{localprintersshared} = + ($#{$printer->{cupsconfig}{clientnetworks}} >= 0); + } } else { - @cupsd_conf = - map { s/^\s*BrowsePoll\s+(\S+)/\#BrowsePoll $1/; - $_ } @cupsd_conf; + # We have clicked "OK" + $retvalue = 1; + $maindone = 1; + # Write state for auto-correction of cupsd.conf + printer::main::set_cups_autoconf + ($printer->{cupsconfig}{autocorrection}); + # Write cupsd.conf + printer::main::write_cups_config($printer); + printer::main::write_cupsd_conf + (@{$printer->{cupsconfig}{cupsd_conf}}); } - printer::main::write_cupsd_conf(@cupsd_conf); - } - # Set auto-configuration state - if ($autoconf != $oldautoconf) { - printer::main::set_cups_autoconf($autoconf); + } else { + # Cancel clicked + $maindone = 1; } - # Save user settings for auto-install - $printer->{BROWSEPOLLADDR} = $server; - $printer->{BROWSEPOLLPORT} = $port; - $printer->{MANUALCUPSCONFIG} = 1 - $autoconf; } + printer::main::clean_cups_config($printer); return $retvalue; } @@ -2941,7 +3121,7 @@ sub main { 1; }, val => ($::expert ? N("CUPS configuration") : - N("Specify CUPS server")) }) : ()), + N("Printer sharing")) }) : ()), ($::expert ? { clicked_may_quit => sub { |