Back to index

nordugrid-arc-nox  1.1.0~rc6
ngconfig.cpp
Go to the documentation of this file.
00001 #ifdef HAVE_CONFIG_H
00002 #include "config.h"
00003 #endif
00004 
00005 #include <fstream>
00006 #include <iostream>
00007 #include <list>
00008 #include <string>
00009 
00010 #include "configcore.h"
00011 #include "ngconfig.h"
00012 
00013 namespace ARex {
00014 
00015 Config NGConfig::Read(std::istream& is) {
00016 
00017        Config config;
00018 
00019        std::string line;
00020        std::list<std::string> conf;
00021 
00022        while (getline(is, line))
00023               conf.push_back(line);
00024 
00025        // Default section - allows to read very old ~/.ngrc
00026        std::string section("UNDEFINED");
00027        std::string id;
00028        std::list<Option> options;
00029 
00030        // Loop over lines
00031        for (std::list<std::string>::iterator lineit = conf.begin();
00032             lineit != conf.end(); lineit++) {
00033 
00034               std::string line = *lineit;
00035 
00036               // Find line delimiters - remove external whitespaces
00037               std::string::size_type pos1 = line.find_first_not_of(" \t");
00038               std::string::size_type pos2 = line.find_last_not_of(" \t");
00039 
00040               // Drop comments and empty lines
00041               if (pos1 == std::string::npos || line[pos1] == '#')
00042                      continue;
00043 
00044               // Is this a section - otherwise must be a statement
00045               if (line[pos1] == '[' && line[pos2] == ']') {
00046 
00047                      if (section != "UNDEFINED" || !options.empty())
00048                             config.AddConfGrp(ConfGrp(section, id, options));
00049 
00050                      section = line.substr(pos1 + 1, pos2 - pos1 - 1);
00051                      id.clear();
00052                      options.clear();
00053                      continue;
00054               }
00055 
00056               std::string::size_type sep = line.find('=');
00057 
00058               // Skip statements with missing =
00059               // Skip statements where the = is the first or last character
00060               if (sep == std::string::npos || sep == pos1 || sep == pos2)
00061                      continue;
00062 
00063               std::string::size_type pos3 = line.find_first_not_of(" \t", sep + 1);
00064               std::string::size_type pos4 = line.find_last_not_of(" \t", sep - 1);
00065 
00066               std::map<std::string, std::string> suboptions;
00067 
00068               // Special treatment of suboptions for group acl rules
00069               if (line[pos1] == '!') {
00070                      suboptions["match"] = "inverted";
00071                      pos1++;
00072               }
00073               if (line[pos1] == '+') {
00074                      suboptions["rule"] = "allow";
00075                      pos1++;
00076               }
00077               else if (line[pos1] == '-') {
00078                      suboptions["rule"] = "deny";
00079                      pos1++;
00080               }
00081 
00082               // Get Attributes
00083               std::string attr = line.substr(pos1, pos4 - pos1 + 1);
00084               std::string value = line.substr(pos3, pos2 - pos3 + 1);
00085 
00086               if ((attr[0] == '"' && attr[attr.size() - 1] == '"') ||
00087                   (attr[0] == '\'' && attr[attr.size() - 1] == '\''))
00088                      attr = attr.substr(1, attr.size() - 2);
00089               if ((value[0] == '"' && value[value.size() - 1] == '"') ||
00090                   (value[0] == '\'' && value[value.size() - 1] == '\''))
00091                      value = value.substr(1, value.size() - 2);
00092 
00093               // Special treatment of the state for backward compatibility
00094               std::string::size_type pos = value.find_first_of(" \t");
00095               if (pos != std::string::npos) {
00096                      std::string firstval = value.substr(0, pos);
00097                      if (firstval == "ACCEPTING" || firstval == "ACCEPTED" ||
00098                          firstval == "PREPARING" || firstval == "PREPARED" ||
00099                          firstval == "FINISHING" || firstval == "FINISHED" ||
00100                          firstval == "SUBMIT"    || firstval == "DELETED") {
00101                             suboptions["state"] = firstval;
00102                             std::string::size_type
00103                                    pos2 = value.find_first_not_of(" \t", pos + 1);
00104                             value = value.substr(pos2);
00105                      }
00106               }
00107 
00108               // Tricky to reliably detect a suboption string...
00109               // Check only attributes known to have suboptions...
00110               if ((attr == "plugin" || attr == "authplugin" ||
00111                    attr == "localcred") &&
00112                   (value[0] != '/' || value.find("@/") != std::string::npos)) {
00113                      std::string::size_type pos1 = value.find_first_of(" \t");
00114                      if (pos1 != std::string::npos) {
00115                             std::string firstval = value.substr(0, pos1);
00116                             std::string::size_type del1 = 0;
00117                             while (del1 != std::string::npos) {
00118                                    std::string::size_type del2 = firstval.find(',', del1);
00119                                    std::string subopt;
00120                                    if (del2 == std::string::npos) {
00121                                           subopt = firstval.substr(del1);
00122                                           del1 = std::string::npos;
00123                                    }
00124                                    else {
00125                                           subopt = firstval.substr(del1, del2 - del1);
00126                                           del1 = del2 + 1;
00127                                    }
00128                                    std::string::size_type eqpos = subopt.find('=');
00129                                    if (eqpos == std::string::npos)
00130                                           suboptions["timeout"] = subopt;
00131                                    else
00132                                           suboptions[subopt.substr(0, eqpos)] =
00133                                                  subopt.substr(eqpos + 1);
00134                             }
00135                             pos2 = value.find_first_not_of(" \t", pos1 + 1);
00136                             value = value.substr(pos2);
00137                      }
00138               }
00139 
00140               // Find the configuration group ID
00141               // search for "name" for backward compatibility
00142               if (attr == "id" || attr == "name") {
00143                      id = value;
00144                      continue;
00145               }
00146 
00147               options.push_back(Option(attr, value, suboptions));
00148        }
00149 
00150        if (section != "UNDEFINED" || !options.empty())
00151               config.AddConfGrp(ConfGrp(section, id, options));
00152 
00153        return config;
00154 }
00155 
00156 
00157 void NGConfig::WriteOption(const Option& opt, std::ostream& os) {
00158 
00159        std::map<std::string, std::string>::const_iterator it;
00160 
00161        // Special treatment of suboptions for group ACL.
00162        it = opt.GetSubOptions().find("match");
00163        if (it != opt.GetSubOptions().end())
00164               if (it->second == "inverted")
00165                      os << '!';
00166        it = opt.GetSubOptions().find("rule");
00167        if (it != opt.GetSubOptions().end()) {
00168               if (it->second == "allow")
00169                      os << '+';
00170               else if (it->second == "deny")
00171                      os << '-';
00172        }
00173 
00174        os << opt.GetAttr() << '=' << '"';
00175 
00176        // Special treatment of state suboption.
00177        it = opt.GetSubOptions().find("state");
00178        if (it != opt.GetSubOptions().end())
00179               os << it->second << ' ';
00180 
00181        // Other suboptions
00182        bool first = true;
00183        for (it = opt.GetSubOptions().begin();
00184             it != opt.GetSubOptions().end(); it++) {
00185               if (it->first != "match" &&
00186                   it->first != "rule" &&
00187                   it->first != "state") {
00188                      if (!first) os << ',';
00189                      os << it->first << '=' << it->second;
00190                      first = false;
00191               }
00192        }
00193        if (!first) os << ' ';
00194 
00195        os << opt.GetValue() << '"' << std::endl;
00196 }
00197 
00198 
00199 void NGConfig::Write(const Config& conf, std::ostream& os) {
00200 
00201        for (std::list<ConfGrp>::const_iterator it = conf.GetConfigs().begin();
00202             it != conf.GetConfigs().end(); it++) {
00203               os << '[' << it->GetSection() << ']' << std::endl;
00204               if (!it->GetID().empty())
00205                      os << "id=" << '"' << it->GetID() << '"' << std::endl;
00206               for (std::list<Option>::const_iterator oit = it->GetOptions().begin();
00207                    oit != it->GetOptions().end(); oit++)
00208                      WriteOption(*oit, os);
00209               os << std::endl;
00210        }
00211 }
00212 
00213 }