LogoopenSUSE Build Service > Projects
Sign Up | Log In

View File setcupsbroadcasting of Package cups (Project DISCONTINUED:openSUSE:11.1)

#!/usr/bin/perl -w

#
# Script to automatically restrict the printer information broadcasting the
# accepting of external broadcasts, and the access to the printers to local
# (eth?) networks 
#

#
# Till Kamppeter (till@mandrakesoft.com)
#
# Copyright 2000 MandrakeSoft
#
# This software may be freely redistributed under the terms of the GNU
# General Public License.
#
# 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., 675 Mass Ave, Cambridge, MA 02139, USA.
#

# Do not do any changes during the installation

if ($ENV{'DURING_INSTALL'}) {exit 0};

# Read CUPS config file

my $cups_conf = "/etc/cups/cupsd.conf";
if (!(-f $cups_conf)) {die "No CUPS configuration file $cups_conf!"};
open CONF_CUPS, "$cups_conf" or die "Can't open $cups_conf!";
my @cups_conf_content = <CONF_CUPS>;
close CONF_CUPS;

# If it contains at least one "BrowseAddress" line broadcasting is already
# configured and we are done, stop silently here.

grep(/^\s*BrowseAddress[^:]/, @cups_conf_content) and exit 0;

# Read the output of "ifconfig" to look for local networks

my $dev_is_localnet = 0;
my @local_networks = ();
my @local_bcasts = ();
my $current_ip = "";
my $current_mask = "";
my $current_bcast = "";

if (-x "/sbin/ifconfig") {
  open IFCONFIG_OUT, "/sbin/ifconfig|" or die "Couldn't run \"ifconfig\"!";
  while (defined($readline = <IFCONFIG_OUT>)) {
    # New entry ...
    if ($readline =~ /^(\S+)\s/) {
      $dev = $1;
      # ... for a local network?
      if ($dev =~ /^eth/) {$dev_is_localnet = 1} 
      else {$dev_is_localnet = 0};
      # delete previous network data
      $current_ip = "";
      $current_mask = "";
      $current_bcast = "";
    }
    # Are we in an entry for a local network?
    if ($dev_is_localnet == 1) {
      # Are we in the important line now?
      if ($readline =~ /\sinet addr:[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\s/) {
        # Rip out the network addresses
        if ($readline =~ /\sinet addr:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s/) {
          $current_ip = $1;
        }
        if ($readline =~ /\sBcast:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s/) {
          $current_bcast = $1;
        }
        if ($readline =~ /\sMask:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\s/) {
          $current_mask = $1;
        }
        # Is the entry valid?
        if (($current_ip ne "") and ($current_mask ne "")) {
          # Is there a broadcast address?
          if ($current_bcast eq "") {$current_bcast = $current_ip};
          # Store broadcast address (or current IP if there is none)
	  push @local_bcasts, $current_bcast;
          # Calculate mask fore access restriction
          $current_ip =~ /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/;
	  ($i1, $i2, $i3, $i4) = ($1, $2, $3, $4);
          $current_mask =~ /([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)/;
	  ($m1, $m2, $m3, $m4) = ($1, $2, $3, $4);
          $current_net = "";
          if ($m1 eq "255") {$current_net = "${current_net}${i1}\."};
          if ($m2 eq "255") {$current_net = "$current_net$i2."};
          if ($m3 eq "255") {$current_net = "$current_net$i3."};
          if ($m4 eq "255") {$current_net = "$current_net$i4"}
          else {$current_net = "$current_net*"};
          # Store mask
	  push @local_networks, $current_net;
        }
      }
    }
  }
  close(IFCONFIG_OUT);
}

# Remove all valid "BrowseAddress" lines
($_ =~ /^\s*BrowseAddress[^:]/ and $_="") foreach @cups_conf_content;

# Insert the new "BrowseAddress" lines
(push @cups_conf_content, "BrowseAddress $_\n") foreach @local_bcasts;

# Delete all "BrowseOrder", "BrowseAllow" and "BrowseDeny" lines from the file

($_ =~ /^\s*BrowseOrder/ and $_="") foreach @cups_conf_content;
($_ =~ /^\s*BrowseAllow/ and $_="") foreach @cups_conf_content;
($_ =~ /^\s*BrowseDeny/ and $_="") foreach @cups_conf_content;

# Add the new "BrowseOrder" and "BrowseDeny" lines

push(@cups_conf_content,"BrowseOrder Deny,Allow\n");
push(@cups_conf_content,"BrowseDeny All\n");

# Add a "BrowseAllow" line for every local network

(push(@cups_conf_content,"BrowseAllow $_\n")) foreach @local_networks;

# Cut out the root location block
#
#   <Location />
#   ...
#   </Location>
#
# so that it can be treated seperately without affecting the rest of the 
# file

if (grep(m!^\s*<Location\s+/\s*>!, @cups_conf_content)) {
  $root_location_start = -1;
  $root_location_end = -1;
  # Go through all the lines, bail out when start and end line found
  for ($i = 0; 
       ($i <= $#cups_conf_content) and ($root_location_end == -1);
       $i++) {
    if ($cups_conf_content[$i] =~ m!^\s*<\s*Location\s+/\s*>!) {
      # Start line of block
      $root_location_start = $i;
    } elsif (($cups_conf_content[$i] =~ m!^\s*<\s*/Location\s*>!) and
               ($root_location_start != -1)) {
      # End line of block
      $root_location_end = $i;
    }
  }
  # Rip out the block and store it seperately
  @root_location = 
    splice(@cups_conf_content,$root_location_start,
           $root_location_end - $root_location_start + 1);
} else {
  # If there is no root location block, create one
  $root_location_start = $#cups_conf_content + 1;
  @root_location = ();
  push @root_location, "<Location />\n";
  push @root_location, "</Location>\n";
}

# Delete all former "Order", "Allow", and "Deny" lines from the root location
# block

($_ =~ /^\s*Order/ and $_="") foreach @root_location;
($_ =~ /^\s*Allow/ and $_="") foreach @root_location;
($_ =~ /^\s*Deny/ and $_="") foreach @root_location;

# Add the new "Order" and "Deny" lines

splice(@root_location,-1,0,"Order Deny,Allow\n");
splice(@root_location,-1,0,"Deny From All\n");
splice(@root_location,-1,0,"Allow From 127.0.0.1\n");

# Add an "Allow" line for every local network

(splice(@root_location,-1,0,"Allow From $_\n")) foreach @local_networks;

# Put the changed root location block back into the file

splice(@cups_conf_content,$root_location_start,0,@root_location);

# Write back the modified CUPS config file

open CONF_CUPS, ">$cups_conf" or die "Can't open $cups_conf";
print CONF_CUPS @cups_conf_content;
close CONF_CUPS;