nis-util  1.0.D108
lib/space/ethers/slurp.cc
Go to the documentation of this file.
00001 //
00002 // nis-util - NIS Administration Utilities
00003 // Copyright (C) 2001, 2008, 2009, 2011, 2012 Peter Miller
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or (at
00008 // your option) any later version.
00009 //
00010 // This program is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with this program. If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 
00019 #include <lib/ac/errno.h>
00020 #include <lib/ac/sys/stat.h>
00021 #include <lib/ac/unistd.h>
00022 
00023 #include <lib/space/ethers/slurp.h>
00024 #include <lib/space/hosts/slurp.h>
00025 
00026 
00027 space_ethers_slurp::~space_ethers_slurp()
00028 {
00029 }
00030 
00031 
00032 space_ethers_slurp::space_ethers_slurp(
00033     const rcstring &a_filename,
00034     const space_hosts_slurp::pointer &a_hosts
00035 ) :
00036     space_ethers(a_filename),
00037     hosts(a_hosts)
00038 {
00039 }
00040 
00041 
00042 space_ethers_slurp::pointer
00043 space_ethers_slurp::create(const rcstring &a_filename,
00044     const space_hosts_slurp::pointer &a_hosts)
00045 {
00046     return pointer(new space_ethers_slurp(a_filename, a_hosts));
00047 }
00048 
00049 
00050 void
00051 space_ethers_slurp::process(const record::pointer &rp0)
00052 {
00053     record::pointer rp = rp0;
00054 
00055     //
00056     // Check MAC address.
00057     //
00058     {
00059         by_addr_t::iterator it = by_addr.find(rp->get_mac_address());
00060         if (it != by_addr.end())
00061         {
00062             error
00063             (
00064                 rp->get_source_location(),
00065                 "duplicate %s MAC address...",
00066                 rp->get_mac_address().quote_c().c_str()
00067             );
00068             error
00069             (
00070                 it->second->get_source_location(),
00071                 "... here is the first %s MAC address",
00072                 it->second->get_mac_address().quote_c().c_str()
00073             );
00074         }
00075         else
00076         {
00077             by_addr.insert(by_addr_t::value_type(rp->get_mac_address(), rp));
00078         }
00079     }
00080 
00081     //
00082     // Check IP address.
00083     //
00084     if (!rp->get_ip_address().empty())
00085     {
00086         if (hosts)
00087         {
00088             space_hosts::record::pointer hp =
00089                 hosts->query_by_address(rp->get_ip_address());
00090             if (hp)
00091             {
00092                 error
00093                 (
00094                     rp->get_source_location(),
00095                     "some NIS clients do not expect an IP address, "
00096                         "replace %s with %s for maximum interoperability",
00097                     rp->get_ip_address().quote_c().c_str(),
00098                     hp->get_names().front().quote_c().c_str()
00099                 );
00100 
00101                 // re-write the record, using the correct name.
00102                 rp =
00103                     record::create
00104                     (
00105                         rp->get_source_location(),
00106                         rp->get_mac_address(),
00107                         hp->get_names().front(),
00108                         rp->get_ip_address()
00109                     );
00110             }
00111             else
00112             {
00113                 error
00114                 (
00115                     rp->get_source_location(),
00116                     "some NIS clients do not expect an IP address, replace "
00117                     "the %s IP address with the host name for maximum "
00118                     "interoperability; and also add it to the hosts map",
00119                     rp->get_ip_address().quote_c().c_str()
00120                 );
00121             }
00122         }
00123 
00124         by_ip_addr_t::iterator it = by_ip_addr.find(rp->get_ip_address());
00125         if (it != by_ip_addr.end())
00126         {
00127             assert(it->second);
00128             error
00129             (
00130                 rp->get_source_location(),
00131                 "duplicate %s ip address...",
00132                 rp->get_ip_address().c_str()
00133             );
00134             if (it->second->get_ip_address().empty())
00135             {
00136                 error
00137                 (
00138                     it->second->get_source_location(),
00139                     "... here is the first reference"
00140                 );
00141             }
00142             else
00143             {
00144                 error
00145                 (
00146                     it->second->get_source_location(),
00147                     "... here is the first %s ip address",
00148                     it->second->get_ip_address().quote_c().c_str()
00149                 );
00150             }
00151         }
00152         else
00153         {
00154             by_name.insert
00155             (
00156                 by_ip_addr_t::value_type(rp->get_ip_address(), rp)
00157             );
00158         }
00159     }
00160 
00161     //
00162     // Check host name.
00163     //
00164     if (!rp->get_name().empty())
00165     {
00166         if (hosts)
00167         {
00168             space_hosts::record::pointer hp =
00169                 hosts->query_by_name(rp->get_name());
00170             if (!hp)
00171             {
00172                 error
00173                 (
00174                     rp->get_source_location(),
00175                     "host %s does not exist in the hosts map",
00176                     rp->get_name().quote_c().c_str()
00177                 );
00178             }
00179             else if (rp->get_ip_address().empty())
00180             {
00181                 // rewrite the record with the IP address
00182                 rp =
00183                     space_ethers::record::create
00184                     (
00185                         rp->get_source_location(),
00186                         rp->get_mac_address(),
00187                         rp->get_name(),
00188                         hp->get_ip_address()
00189                     );
00190                 by_ip_addr_t::iterator ipit =
00191                     by_ip_addr.find(hp->get_ip_address());
00192                 if (ipit != by_ip_addr.end())
00193                 {
00194                     error
00195                     (
00196                         rp->get_source_location(),
00197                         "duplicate %s ip address...",
00198                         rp->get_ip_address().quote_c().c_str()
00199                     );
00200                     if (ipit->second->get_ip_address().empty())
00201                     {
00202                         error
00203                         (
00204                             ipit->second->get_source_location(),
00205                             "... here is the first reference"
00206                         );
00207                     }
00208                     else
00209                     {
00210                         error
00211                         (
00212                             ipit->second->get_source_location(),
00213                             "... here is the first %s ip address",
00214                             rp->get_ip_address().quote_c().c_str()
00215                         );
00216                     }
00217                 }
00218                 else
00219                 {
00220                     by_ip_addr.insert
00221                     (
00222                         by_ip_addr_t::value_type(rp->get_ip_address(), rp)
00223                     );
00224                 }
00225             }
00226         }
00227 
00228         // We use a lower-case name intentionally,
00229         // because DNS things names are not case sensitive.
00230         by_name_t::iterator it = by_name.find(rp->get_name().downcase());
00231         if (it != by_name.end())
00232         {
00233             // but preserve case in the error messages
00234             error
00235             (
00236                 rp->get_source_location(),
00237                 "duplicate %s host name...",
00238                 rp->get_name().c_str()
00239             );
00240             if (it->second->get_name().empty())
00241             {
00242                 error
00243                 (
00244                     it->second->get_source_location(),
00245                     "... here is the first reference"
00246                 );
00247             }
00248             else
00249             {
00250                 error
00251                 (
00252                     it->second->get_source_location(),
00253                     "... here is the first %s host name",
00254                     it->second->get_name().quote_c().c_str()
00255                 );
00256             }
00257         }
00258         else
00259         {
00260             // We use a lower-case name intentionally,
00261             // because DNS thinks host names are not case sensitive.
00262             by_name.insert
00263             (
00264                 by_name_t::value_type(rp->get_name().downcase(), rp)
00265             );
00266         }
00267     }
00268 
00269     //
00270     // Check line length.
00271     //
00272     if (rp->representation().size() >= 512)
00273     {
00274         error
00275         (
00276             rp->get_source_location(),
00277             "line too long (NIS limits records to 511 bytes, NIS+ limits "
00278                 "records to 1023 bytes)"
00279         );
00280     }
00281 }
00282 
00283 
00284 void
00285 space_ethers_slurp::read_and_process(void)
00286 {
00287     for (;;)
00288     {
00289         space_ethers::record::pointer rp = get();
00290         if (!rp)
00291             break;
00292         process(rp);
00293     }
00294     close();
00295 }
00296 
00297 
00298 space_ethers::record::pointer
00299 space_ethers_slurp::query_by_name(const rcstring &name)
00300     const
00301 {
00302     by_name_t::const_iterator it = by_name.find(name);
00303     if (it == by_name.end())
00304         return record::pointer();
00305     return it->second;
00306 }
00307 
00308 
00309 space_ethers::record::pointer
00310 space_ethers_slurp::query_by_address(const rcstring &address)
00311     const
00312 {
00313     by_addr_t::const_iterator it = by_addr.find(address);
00314     if (it == by_addr.end())
00315         return record::pointer();
00316     return it->second;
00317 }
00318 
00319 
00320 // vim: set ts=8 sw=4 et :