nis-util  1.0.D108
lib/space/ethers.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/string.h>
00020 
00021 #include <lib/space/ethers.h>
00022 #include <lib/space/hosts.h>
00023 
00024 
00025 space_ethers::~space_ethers()
00026 {
00027     discard_comments();
00028     discard_blank_lines();
00029 }
00030 
00031 
00032 space_ethers::space_ethers(const rcstring &a_filename) :
00033     space(a_filename)
00034 {
00035     discard_comments();
00036     discard_blank_lines();
00037 }
00038 
00039 
00040 space_ethers::pointer
00041 space_ethers::create(const rcstring &a_filename)
00042 {
00043     return pointer(new space_ethers(a_filename));
00044 }
00045 
00046 
00047 space_ethers::record::pointer
00048 space_ethers::get(void)
00049 {
00050     for (;;)
00051     {
00052         source_location glocn;
00053         line_t line;
00054         if (!read_one_line(glocn, line))
00055         {
00056             last_rp.reset();
00057             return record::pointer();
00058         }
00059         if (line.size() < 2)
00060         {
00061             error
00062             (
00063                 glocn,
00064                 "too few fields (expected 2, received %ld)",
00065                 (long)line.size()
00066             );
00067             continue;
00068         }
00069         if (line.size() > 2)
00070         {
00071             error
00072             (
00073                 glocn,
00074                 "too many fields (expected 2, received %ld)",
00075                 (long)line.size()
00076             );
00077         }
00078 
00079         rcstring mac_address = line[0];
00080         rcstring name = line[1];
00081         rcstring ip_address;
00082 
00083         //
00084         // Check MAC address.
00085         //
00086         ether_addr *eap = ether_aton(mac_address.c_str());
00087         if (!eap)
00088         {
00089             error
00090             (
00091                 glocn,
00092                 "MAC address %s not valid",
00093                 mac_address.quote_c().c_str()
00094             );
00095             continue;
00096         }
00097 
00098         rcstring temp(ether_ntoa(eap));
00099         if (temp != mac_address)
00100         {
00101             error
00102             (
00103                 glocn,
00104                 "MAC address %s not in correct format, use %s instead",
00105                 mac_address.quote_c().c_str(),
00106                 temp.quote_c().c_str()
00107             );
00108             mac_address = temp;
00109         }
00110 
00111         //
00112         // The second argument could be an IP address or a host name.
00113         //
00114         if (!space_hosts::valid_ip_address(name, temp))
00115         {
00116             //
00117             // Transfer host name.
00118             //
00119             if (!space_hosts::valid_host_name(name, temp))
00120             {
00121                 error
00122                 (
00123                     glocn,
00124                     "host name %s not valid, suggest %s instead",
00125                     name.quote_c().c_str(),
00126                     temp.quote_c().c_str()
00127                 );
00128                 name = temp;
00129             }
00130         }
00131         else
00132         {
00133             //
00134             // Transfer IP address.
00135             //
00136             ip_address = name;
00137             name = "";
00138             if (temp != ip_address)
00139             {
00140                 error
00141                 (
00142                     glocn,
00143                     "IP address %s not in canonical format, use %s instead",
00144                     ip_address.quote_c().c_str(),
00145                     temp.quote_c().c_str()
00146                 );
00147                 ip_address = temp;
00148             }
00149         }
00150 
00151         record::pointer rp =
00152             record::create(glocn, mac_address, name, ip_address);
00153         assert(rp);
00154 
00155         //
00156         // Check record sequencing.
00157         // It may seem arbitrary, but this finds common typographical errors.
00158         //
00159         if (last_rp && *rp <= *last_rp)
00160         {
00161             error
00162             (
00163                 glocn,
00164                 "address %s out of order",
00165                 rp->get_mac_address().quote_c().c_str()
00166             );
00167             explain_sequence_errors();
00168         }
00169         last_rp = rp;
00170 
00171         //
00172         // return the record found.
00173         //
00174         return rp;
00175     }
00176 }
00177 
00178 
00179 space_ethers::record::~record()
00180 {
00181 }
00182 
00183 
00184 space_ethers::record::record(
00185     const source_location &a_locn,
00186     const rcstring &a_mac_address,
00187     const rcstring &a_name,
00188     const rcstring &a_ip_address
00189 ) :
00190     locn(a_locn),
00191     mac_address(a_mac_address),
00192     name(a_name),
00193     ip_address(a_ip_address)
00194 {
00195     ether_addr *eap = ether_aton(mac_address.c_str());
00196     if (eap)
00197         mac_address_binary = *eap;
00198     else
00199         memset(&mac_address_binary, 0, sizeof(mac_address_binary));
00200 }
00201 
00202 
00203 space_ethers::record::pointer
00204 space_ethers::record::create(const source_location &a_locn,
00205     const rcstring &a_mac_address, const rcstring &a_name,
00206     const rcstring &a_ip_address)
00207 {
00208     return
00209         pointer
00210         (
00211             new space_ethers::record
00212             (
00213                 a_locn,
00214                 a_mac_address,
00215                 a_name,
00216                 a_ip_address
00217             )
00218         );
00219 }
00220 
00221 
00222 rcstring
00223 space_ethers::record::representation(void)
00224     const
00225 {
00226     if (name.empty())
00227     {
00228         return (mac_address + " " + ip_address);
00229     }
00230     return (mac_address + " " + name);
00231 }
00232 
00233 
00234 int
00235 space_ethers::record::compare(const space_ethers::record &rhs)
00236     const
00237 {
00238     return
00239         memcmp
00240         (
00241             &mac_address_binary,
00242             &rhs.mac_address_binary,
00243             sizeof(mac_address_binary)
00244         );
00245 }
00246 
00247 
00248 bool
00249 space_ethers::record::operator>(const space_ethers::record &rhs)
00250     const
00251 {
00252     return (compare(rhs) > 0);
00253 }
00254 
00255 
00256 bool
00257 space_ethers::record::operator>=(const space_ethers::record &rhs)
00258     const
00259 {
00260     return (compare(rhs) >= 0);
00261 }
00262 
00263 
00264 bool
00265 space_ethers::record::operator<(const space_ethers::record &rhs)
00266     const
00267 {
00268     return (compare(rhs) < 0);
00269 }
00270 
00271 
00272 bool
00273 space_ethers::record::operator<=(const space_ethers::record &rhs)
00274     const
00275 {
00276     return (compare(rhs) <= 0);
00277 }
00278 
00279 
00280 // vim: set ts=8 sw=4 et :