home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / system-tools-backends-2.0 / scripts / Shares / NFS.pm next >
Encoding:
Perl POD Document  |  2009-04-09  |  7.8 KB  |  391 lines

  1. #-*- Mode: perl; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2. #
  3. # Copyright (C) 2000-2001 Ximian, Inc.
  4. #
  5. # Authors: Hans Petter Jansson <hpj@ximian.com>
  6. #
  7. # This program is free software; you can redistribute it and/or modify
  8. # it under the terms of the GNU Library General Public License as published
  9. # by the Free Software Foundation; either version 2 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This program is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. # GNU Library General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU Library General Public License
  18. # along with this program; if not, write to the Free Software
  19. # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
  20.  
  21. package Shares::NFS;
  22.  
  23. use Utils::Parse;
  24.  
  25. sub get_distro_nfs_file
  26. {
  27.   return "/etc/dfs/dfstab" if ($Utils::Backend::tool{"system"} eq "SunOS");
  28.   return "/etc/exports";
  29. }
  30.  
  31. sub get_share_client_info
  32. {
  33.   my ($client) = @_;
  34.   my ($pattern, $options_str, @options, $option);
  35.   my ($rw);
  36.  
  37.   $client =~ /^([a-zA-Z0-9.-_*?@\/]+)/;
  38.   $pattern = $1;
  39.   $pattern = "0.0.0.0/0" if $pattern eq "";
  40.   $rw = 0;
  41.  
  42.   if ($client =~ /\((.+)\)/)
  43.   {
  44.     $option_str = $1;
  45.     @options = ($option_str =~ /([a-zA-Z0-9_=-]+),?/mg);
  46.  
  47.     for $option (@options)
  48.     {
  49.       $rw = 1 if ($option eq "rw");
  50.       # Add supported NFS export options here. Some might have to be split on '='.
  51.     }
  52.   }
  53.  
  54.   return [ $pattern, !$rw ];
  55. }
  56.  
  57. sub get_share_info
  58. {
  59.   my ($clients) = @_;
  60.   my (@share_info, $client);
  61.  
  62.   foreach $client (@$clients)
  63.   {
  64.     push @share_info, &get_share_client_info ($client);
  65.   }
  66.  
  67.   return \@share_info;
  68. }
  69.  
  70. sub get_share_info_sunos
  71. {
  72.   my ($str) = @_;
  73.   my (@options, $opt, @values, @share_info);
  74.  
  75.   @options = split (/\s*,\s*/, $str);
  76.  
  77.   foreach $opt (@options)
  78.   {
  79.     my ($option, $value);
  80.  
  81.     @values = split /\s*=\s*/, $opt;
  82.     $option = $values[0];
  83.     $value = $values[1];
  84.  
  85.     # only support "rw" and "ro" at the moment
  86.     if ($option eq "rw" || $option eq "ro")
  87.     {
  88.       my ($rw, $client);
  89.       $rw = ($option eq "rw") ? 1 : 0;
  90.  
  91.       if (!$value)
  92.       {
  93.         push @share_info, [ $rw, "0.0.0.0/0" ];
  94.       }
  95.       else
  96.       {
  97.         my @clients;
  98.  
  99.         # get the clients list
  100.         @clients = split (/:/, $value);
  101.  
  102.         foreach $client (@clients)
  103.         {
  104.           push @share_info, [ $client, $rw ];
  105.         }
  106.       }
  107.     }
  108.   }
  109.  
  110.   return \@share_info;
  111. }
  112.  
  113. sub get_client_opts_sunos
  114. {
  115.   my ($clients) = @_;
  116.   my (@rw_clients, @ro_clients, $client, $str, $i);
  117.  
  118.   foreach $i (@$clients)
  119.   {
  120.     #FIXME: broken logic?
  121.     if (!$$i[1])
  122.     {
  123.       push @rw_clients, $$i[0];
  124.     }
  125.     else
  126.     {
  127.       push @ro_clients, $$i[0];
  128.     }
  129.   }
  130.  
  131.   # get rw clients
  132.   if (scalar (@rw_clients))
  133.   {
  134.     $str .= "rw=" . join (":", @rw_clients);
  135.   }
  136.  
  137.   # get ro clients
  138.   if (scalar (@ro_clients))
  139.   {
  140.     $str .= ",ro=" . join (":", @ro_clients);
  141.   }
  142.  
  143.   return $str;
  144. }
  145.  
  146. sub get_export_line
  147. {
  148.   my ($share) = @_;
  149.   my ($str, $i);
  150.  
  151.   if ($Utils::Backend::tool{"system"} eq "SunOS")
  152.   {
  153.     $str  = "share -F nfs";
  154.     $str .= " -o " . &get_client_opts_sunos ($$share[1]);
  155.     $str .= " " . $$share[0];
  156.   }
  157.   else
  158.   {
  159.     $str = sprintf ("%-15s ", $$share[0]);
  160.  
  161.     foreach $i (@{$$share[1]})
  162.     {
  163.       $str .= $$i[0];
  164.       #FIXME: broken logic?
  165.       $str .= "(rw)" if (!$$i[1]);
  166.       $str .= " ";
  167.     }
  168.  
  169.     $str .= "\n";
  170.   }
  171.  
  172.   return $str;
  173. }
  174.  
  175. sub share_line_matches
  176. {
  177.   my ($share, $line) = @_;
  178.  
  179.   return 0 if (&Utils::Util::ignore_line ($line));
  180.   chomp $line;
  181.  
  182.   if ($Utils::Backend::tool{"system"} eq "SunOS")
  183.   {
  184.     return 0 if ($line !~ /\-F\s+nfs/);
  185.     return 1 if ($line =~ /$$share[0]$/);
  186.   }
  187.   else
  188.   {
  189.     my @arr;
  190.  
  191.     @arr = split /[ \t]+/, $line;
  192.     return 1 if ($arr[0] eq $$share[0]);
  193.   }
  194. }
  195.  
  196. sub add_entry
  197. {
  198.   my ($share, $file) = @_;
  199.   my ($buff);
  200.  
  201.   $buff = &Utils::File::load_buffer ($file);
  202.   push @$buff, &get_export_line ($share);
  203.  
  204.   &Utils::File::save_buffer ($buff, $file);
  205. }
  206.  
  207. sub delete_entry
  208. {
  209.   my ($share, $file) = @_;
  210.   my ($buff, $i, $line, @arr);
  211.  
  212.   $buff = &Utils::File::load_buffer ($file);
  213.   &Utils::File::join_buffer_lines ($buff);
  214.   $i = 0;
  215.  
  216.   while ($$buff[$i])
  217.   {
  218.     if (&share_line_matches ($share, $$buff[$i]))
  219.     {
  220.       delete $$buff[$i];
  221.     }
  222.  
  223.     $i++;
  224.   }
  225.  
  226.   &Utils::File::clean_buffer ($buff);
  227.   &Utils::File::save_buffer  ($buff, $file);
  228. }
  229.  
  230. sub change_entry
  231. {
  232.   my ($old_share, $share, $file) = @_;
  233.   my ($buff, $i, $line, @arr);
  234.  
  235.   $buff = &Utils::File::load_buffer ($file);
  236.   &Utils::File::join_buffer_lines ($buff);
  237.   $i = 0;
  238.  
  239.   while ($$buff[$i])
  240.   {
  241.     if (&share_line_matches ($old_share, $$buff[$i]))
  242.     {
  243.       $$buff[$i] = &get_export_line ($share);
  244.     }
  245.  
  246.     $i++;
  247.   }
  248.  
  249.   &Utils::File::clean_buffer ($buff);
  250.   &Utils::File::save_buffer  ($buff, $file);
  251. }
  252.  
  253. sub get_dfstab_shares
  254. {
  255.   my ($file, $type) = @_;
  256.   my ($buff, $line, @arr);
  257.  
  258.   # dfstab example:
  259.   #
  260.   #       share [-F fstype] [-o fs_options ] [-d description] [pathname [resourcename]]
  261.   #       .e.g,
  262.   #       share  -F nfs  -o rw=engineering  -d "home dirs"  /export/home2
  263.  
  264.   $buff = &Utils::File::load_buffer ($file);
  265.   &Utils::File::join_buffer_lines ($buff);
  266.   return [] if (!$buff);
  267.  
  268.   foreach $line (@$buff)
  269.   {
  270.     chomp $line;
  271.       
  272.     if ($line =~ /^\s*\S*share\s+(.*)/)
  273.     {
  274.       my $share;
  275.       my $line = $1;
  276.  
  277.       if ($line =~ /\s-F\s+(\S+)/) { $share->{'type'} = $1; }
  278.       else { $share->{'type'} = "nfs"; }
  279.  
  280.       # skip undesired shares
  281.       next if ($share->{'type'} ne $type);
  282.  
  283.       if ($line =~ /\s+(\/\S+)/ || $line =~ /\s+(\/)/ || $line eq "/") { $share->{'dir'} = $1; }
  284.       if ($line =~ /-o\s+"([^\"]+)"/ || $line =~ /-o\s+(\S+)/) { $share->{'opts'} = $1; }
  285.       #if ($line =~ /-d\s+\"([^\"]+)\"/ || $line =~ /-d\s+(\S+)/) { $share->{'desc'} = $1; }
  286.  
  287.       push @arr, $share;
  288.     }
  289.   }
  290.   
  291.   return \@arr;
  292. }
  293.  
  294. sub get
  295. {
  296.   my ($nfs_file);
  297.   my (@sections, @table, $entries);
  298.   my ($point, $share_info);
  299.  
  300.   $nfs_file = &get_distro_nfs_file ();
  301.  
  302.   if ($Utils::Backend::tool{"system"} eq "SunOS")
  303.   {
  304.     my $shares = &get_dfstab_shares ($nfs_file, "nfs");
  305.  
  306.     foreach $share (@$shares)
  307.     {
  308.       $point = $share->{'dir'};
  309.  
  310.       $share_info = &get_share_info_sunos ($share->{'opts'});
  311.       push @table, [ $point, $share_info ];
  312.     }
  313.   }
  314.   else
  315.   {
  316.     $entries = &Utils::Parse::split_hash_with_continuation ($nfs_file, "[ \t]+", "[ \t]+");
  317.  
  318.     foreach $point (keys %$entries)
  319.     {
  320.       my $clients = $$entries{$point};
  321.  
  322.       $share_info = &get_share_info ($clients);
  323.       push @table, [ $point, $share_info ];
  324.     }
  325.   }
  326.  
  327.   return \@table;
  328. }
  329.  
  330. sub set
  331. {
  332.   my ($config) = @_;
  333.   my ($nfs_exports_file);
  334.   my ($old_config, %shares);
  335.   my (%config_hash, %old_config_hash);
  336.   my ($state, $i);
  337.  
  338.   $nfs_exports_name = &get_distro_nfs_file ();
  339.   $old_config = &get ();
  340.  
  341.   foreach $i (@$config)
  342.   {
  343.     $shares{$$i[0]} |= 1;
  344.     $config_hash{$$i[0]} = $i;
  345.   }
  346.  
  347.   foreach $i (@$old_config)
  348.   {
  349.     $shares{$$i[0]} |= 2;
  350.     $old_config_hash{$$i[0]} = $i;
  351.   }
  352.  
  353.   foreach $i (sort keys (%shares))
  354.   {
  355.     $state = $shares{$i};
  356.  
  357.     if ($state == 1)
  358.     {
  359.       # These entries have been added
  360.       &add_entry ($config_hash{$i}, $nfs_exports_name);
  361.     }
  362.     elsif ($state == 2)
  363.     {
  364.       # These entries have been deleted
  365.       &delete_entry ($old_config_hash{$i}, $nfs_exports_name);
  366.     }
  367.     elsif (($state == 3) &&
  368.            (!Utils::Util::struct_eq ($config_hash{$i}, $old_config_hash{$i})))
  369.     {
  370.       # These entries have been modified
  371.       &change_entry ($old_config_hash{$i}, $config_hash{$i}, $nfs_exports_name);
  372.     }
  373.   }
  374.  
  375.   if ($Utils::Backend::tool{"system"} eq "SunOS")
  376.   {
  377.     &Utils::File::run ("unshareall -F nfs");
  378.     &Utils::File::run ("shareall -F nfs");
  379.   }
  380. }
  381.  
  382. sub get_files
  383. {
  384.   my ($files);
  385.  
  386.   push @$files, &get_distro_nfs_file ();
  387.   return $files;
  388. }
  389.  
  390. 1;
  391.