nis-util  1.0.D108
lib/space/automap/row.cc
Go to the documentation of this file.
00001 //
00002 // nis-util - NIS Administration Utilities
00003 // Copyright (C) 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 along
00016 // with this program. If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 
00019 #include <lib/ac/string.h>
00020 #include <map>
00021 #include <lib/rcstring/accumulator.h>
00022 
00023 #include <lib/space/automap/row.h>
00024 #include <lib/sizeof.h>
00025 #include <lib/space/automap.h>
00026 
00027 
00028 space_automap_row::~space_automap_row()
00029 {
00030 }
00031 
00032 
00033 space_automap_row::space_automap_row(
00034     const mount_point &a_key,
00035     const rcstring &a_options
00036 ) :
00037     key(a_key),
00038     options(a_options)
00039 {
00040 }
00041 
00042 
00043 static bool
00044 is_a_number(const rcstring &s)
00045 {
00046     // no leading zeros
00047     if (s.size() > 1 && s.c_str()[0] == '0')
00048         return false;
00049     for (const char *cp = s.c_str(); *cp; ++cp)
00050         if (!isdigit((unsigned char)*cp))
00051             return false;
00052     return true;
00053 }
00054 
00055 
00056 void
00057 space_automap_row::option_verify(const rcstring &name, const rcstring &value,
00058     space *ctx)
00059 {
00060     enum
00061     {
00062         otab_type_none,
00063         otab_type_integer,
00064         otab_type_string,
00065         otab_type_filename
00066     };
00067 
00068     struct otab_t
00069     {
00070         const char *name;
00071         int type;
00072     };
00073 
00074     static const otab_t otab[] =
00075     {
00076         { "acdirmax", otab_type_integer },
00077         { "acdirmin", otab_type_integer },
00078         { "acregmax", otab_type_integer },
00079         { "acregmin", otab_type_integer },
00080         { "actimeo", otab_type_integer },
00081         { "backfstype", otab_type_string },
00082         { "backpath", otab_type_filename },
00083         { "bg", otab_type_none },
00084         { "cachedir", otab_type_filename },
00085         { "cacheid", otab_type_string },
00086         { "fg", otab_type_none },
00087         { "grpid", otab_type_none },
00088         { "hard", otab_type_none },
00089         { "intr", otab_type_none },
00090         { "local-access", otab_type_none },
00091         { "noac", otab_type_none },
00092         { "noconst", otab_type_none },
00093         { "nocto", otab_type_none },
00094         { "non-shared", otab_type_none },
00095         { "noquota", otab_type_none },
00096         { "norrip", otab_type_none },
00097         { "nosuid", otab_type_none },
00098         { "port", otab_type_integer },
00099         { "posix", otab_type_none },
00100         { "purge", otab_type_none },
00101         { "quota", otab_type_none },
00102         { "retrans", otab_type_integer },
00103         { "retry", otab_type_integer },
00104         { "ro", otab_type_none },
00105         { "rsize", otab_type_integer },
00106         { "rw", otab_type_none },
00107         { "secure", otab_type_none },
00108         { "soft", otab_type_none },
00109         { "suid", otab_type_none },
00110         { "timeo", otab_type_integer },
00111         { "write-around", otab_type_none },
00112         { "wsize", otab_type_integer },
00113     };
00114 
00115     // typedef std::map<rcstring, otab_type_t> stp_t;
00116     typedef std::map<rcstring, int> stp_t;
00117     static stp_t stp;
00118 
00119     if (stp.empty())
00120     {
00121         for (const otab_t *otp = otab; otp < ENDOF(otab); ++otp)
00122         {
00123             stp.insert(stp_t::value_type(otp->name, otp->type));
00124         }
00125     }
00126     stp_t::const_iterator it = stp.find(name);
00127     if (it == stp.end())
00128     {
00129         ctx->error
00130         (
00131             ctx->yak_location(),
00132             "option %s unknown",
00133             name.quote_c().c_str()
00134         );
00135         return;
00136     }
00137 
00138     if (it->second != otab_type_none && value.empty())
00139     {
00140         ctx->error
00141         (
00142             ctx->yak_location(),
00143             "option %s requires an argument",
00144             name.quote_c().c_str()
00145         );
00146         return;
00147     }
00148 
00149     switch (it->second)
00150     {
00151     default:
00152         assert(!"should never reach here");
00153 
00154     case otab_type_none:
00155         if (!value.empty())
00156         {
00157             ctx->error
00158             (
00159                 ctx->yak_location(),
00160                 "option %s should have no argument",
00161                 name.quote_c().c_str()
00162             );
00163         }
00164         break;
00165 
00166     case otab_type_integer:
00167         if (!is_a_number(value))
00168         {
00169             ctx->error
00170             (
00171                 ctx->yak_location(),
00172                 "option %s requires an integer argument",
00173                 name.quote_c().c_str()
00174             );
00175         }
00176         break;
00177 
00178     case otab_type_string:
00179         // existence already checked
00180         break;
00181 
00182     case otab_type_filename:
00183         if (value.c_str()[0] != '/')
00184         {
00185             ctx->error
00186             (
00187                 ctx->yak_location(),
00188                 "option %s requires an absolute path argument",
00189                 name.quote_c().c_str()
00190             );
00191         }
00192         break;
00193     }
00194 }
00195 
00196 
00197 void
00198 space_automap_row::options_verify(const rcstring &text, space *ctx)
00199 {
00200     // get rid of leading hyphen
00201     const char *cp = text.c_str();
00202     if (*cp == '-')
00203         ++cp;
00204 
00205     // break into comma separated things
00206     typedef std::list<std::pair<rcstring, rcstring> > wl_t;
00207     wl_t wl;
00208     for (;;)
00209     {
00210         if (!*cp)
00211             break;
00212         if (*cp == ',')
00213         {
00214             ++cp;
00215             continue;
00216         }
00217         const char *comma = strchr(cp, ',');
00218         const char *next = cp + 1;
00219         if (comma)
00220         {
00221             next = comma + 1;
00222         }
00223         else
00224         {
00225             comma = cp + strlen(cp);
00226             next = comma;
00227         }
00228         const char *eq = (const char *)memchr(cp, '=', comma - cp);
00229         rcstring name;
00230         rcstring value;
00231         if (eq)
00232         {
00233             name = rcstring(cp, eq - cp);
00234             ++eq;
00235             value = rcstring(eq, comma - eq);
00236         }
00237         else
00238         {
00239             name = rcstring(cp, comma - cp);
00240         }
00241 
00242         // make sure we like each of the options
00243         option_verify(name, value, ctx);
00244 
00245         cp = next;
00246     }
00247 }
00248 
00249 
00250 void
00251 space_automap_row::space_automap_insert_sub(space_automap *)
00252     const
00253 {
00254 }
00255 
00256 
00257 // vim: set ts=8 sw=4 et :