Back to index

nordugrid-arc-nox  1.1.0~rc6
DataPointLDAP.cpp
Go to the documentation of this file.
00001 // -*- indent-tabs-mode: nil -*-
00002 
00003 #ifdef HAVE_CONFIG_H
00004 #include <config.h>
00005 #endif
00006 
00007 #include <arc/StringConv.h>
00008 #include <arc/UserConfig.h>
00009 #include <arc/data/DataBuffer.h>
00010 
00011 #include "DataPointLDAP.h"
00012 #include "LDAPQuery.h"
00013 
00014 namespace Arc {
00015 
00016   Logger DataPointLDAP::logger(DataPoint::logger, "LDAP");
00017 
00018   DataPointLDAP::DataPointLDAP(const URL& url, const UserConfig& usercfg)
00019     : DataPointDirect(url, usercfg) {}
00020 
00021   DataPointLDAP::~DataPointLDAP() {
00022     StopReading();
00023     StopWriting();
00024   }
00025 
00026   Plugin* DataPointLDAP::Instance(PluginArgument *arg) {
00027     DataPointPluginArgument *dmcarg =
00028       dynamic_cast<DataPointPluginArgument*>(arg);
00029     if (!dmcarg)
00030       return NULL;
00031     if (((const URL&)(*dmcarg)).Protocol() != "ldap")
00032       return NULL;
00033     return new DataPointLDAP(*dmcarg, *dmcarg);
00034   }
00035 
00036   DataStatus DataPointLDAP::Check() {
00037     return DataStatus::Success;
00038   }
00039 
00040   DataStatus DataPointLDAP::Remove() {
00041     return DataStatus::UnimplementedError;
00042   }
00043 
00044   void DataPointLDAP::CallBack(const std::string& attr,
00045                                const std::string& value,
00046                                void *ref) {
00047     DataPointLDAP& point = *(DataPointLDAP*)ref;
00048     if (attr == "dn") {
00049       point.entry = point.node;
00050 
00051       std::list<std::pair<std::string, std::string> > pairs;
00052       std::string::size_type pos = 0;
00053 
00054       while (pos != std::string::npos) {
00055         std::string::size_type pos2 = value.find(',', pos);
00056         std::string attr = (pos2 == std::string::npos ?
00057                             value.substr(pos) :
00058                             value.substr(pos, pos2 - pos));
00059         pos = pos2;
00060         if (pos != std::string::npos)
00061           pos++;
00062         pos2 = attr.find('=');
00063         std::string s1 = attr.substr(0, pos2);
00064         std::string s2 = attr.substr(pos2 + 1);
00065 
00066         while (s1[0] == ' ')
00067           s1 = s1.erase(0, 1);
00068         while (s1[s1.size() - 1] == ' ')
00069           s1 = s1.erase(s1.size() - 1);
00070         while (s2[0] == ' ')
00071           s2 = s2.erase(0, 1);
00072         while (s2[s2.size() - 1] == ' ')
00073           s2 = s2.erase(s2.size() - 1);
00074 
00075         pairs.push_back(std::make_pair(s1, s2));
00076       }
00077 
00078       for (std::list<std::pair<std::string, std::string> >::reverse_iterator
00079            it = pairs.rbegin(); it != pairs.rend(); it++) {
00080         bool found = false;
00081         for (int i = 0; point.entry[it->first][i]; i++)
00082           if ((std::string)point.entry[it->first][i] == it->second) {
00083             point.entry = point.entry[it->first][i];
00084             found = true;
00085             break;
00086           }
00087         if (!found)
00088           point.entry = point.entry.NewChild(it->first) = it->second;
00089       }
00090     }
00091     else
00092       point.entry.NewChild(attr) = value;
00093   }
00094 
00095   DataStatus DataPointLDAP::StartReading(DataBuffer& buf) {
00096     buffer = &buf;
00097     LDAPQuery q(url.Host(), url.Port(), usercfg.Timeout());
00098     if (!q.Query(url.Path(), url.LDAPFilter(), url.LDAPAttributes(),
00099                  url.LDAPScope()))
00100       return DataStatus::ReadStartError;
00101     NS ns;
00102     XMLNode(ns, "LDAPQueryResult").New(node);
00103     if (!q.Result(CallBack, this))
00104       return DataStatus::ReadStartError;
00105     CreateThreadFunction(&ReadThread, this);
00106     return DataStatus::Success;
00107   }
00108 
00109   DataStatus DataPointLDAP::StopReading() {
00110     if (!buffer)
00111       return DataStatus::ReadStopError;
00112     buffer = NULL;
00113     return DataStatus::Success;
00114   }
00115 
00116   DataStatus DataPointLDAP::StartWriting(DataBuffer&, DataCallback*) {
00117     return DataStatus::UnimplementedError;
00118   }
00119 
00120   DataStatus DataPointLDAP::StopWriting() {
00121     return DataStatus::UnimplementedError;
00122   }
00123 
00124   DataStatus DataPointLDAP::ListFiles(std::list<FileInfo>&, bool, bool, bool) {
00125     return DataStatus::UnimplementedError;
00126   }
00127 
00128   void DataPointLDAP::ReadThread(void *arg) {
00129     DataPointLDAP& point = *(DataPointLDAP*)arg;
00130     std::string text;
00131     point.node.GetDoc(text);
00132     std::string::size_type length = text.size();
00133     unsigned long long int pos = 0;
00134     int transfer_handle = -1;
00135     do {
00136       unsigned int transfer_size = 0;
00137       point.buffer->for_read(transfer_handle, transfer_size, true);
00138       if (length < transfer_size)
00139         transfer_size = length;
00140       memcpy((*point.buffer)[transfer_handle], &text[pos], transfer_size);
00141       point.buffer->is_read(transfer_handle, transfer_size, pos);
00142       length -= transfer_size;
00143       pos += transfer_size;
00144     } while (length > 0);
00145     point.buffer->eof_read(true);
00146   }
00147 
00148 } // namespace Arc
00149 
00150 Arc::PluginDescriptor PLUGINS_TABLE_NAME[] = {
00151   { "ldap", "HED:DMC", 0, &Arc::DataPointLDAP::Instance },
00152   { NULL, NULL, 0, NULL }
00153 };