nis-util
1.0.D108
|
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 :