Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Member Functions | Private Attributes
ArcSec::SimpleMap Class Reference

#include <SimpleMap.h>

Collaboration diagram for ArcSec::SimpleMap:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 SimpleMap (const std::string &dir)
 ~SimpleMap (void)
std::string map (const std::string &subject)
bool unmap (const std::string &subject)
 operator bool (void)
bool operator! (void)

Private Attributes

std::string dir_
int pool_handle_

Detailed Description

Definition at line 7 of file SimpleMap.h.


Constructor & Destructor Documentation

ArcSec::SimpleMap::SimpleMap ( const std::string &  dir)

Definition at line 65 of file SimpleMap.cpp.

                                        :dir_(dir) {
  if((dir_.length() == 0) || (dir_[dir_.length()-1] != '/')) dir_+="/";
  if(dir_[0] != '/') {
    char buf[PATH_MAX];
    if(getcwd(buf,sizeof(buf))) dir_=std::string(buf)+"/"+dir_;
  };
  pool_handle_=open((dir_+"pool").c_str(),O_RDWR);
}

Definition at line 74 of file SimpleMap.cpp.

                          {
  if(pool_handle_ != -1) close(pool_handle_);
  pool_handle_=-1;
}

Member Function Documentation

std::string ArcSec::SimpleMap::map ( const std::string &  subject)

Definition at line 88 of file SimpleMap.cpp.

                                                 {
  if(pool_handle_ == -1) failure("not initialized");
  if(subject.empty()) failure("missing subject");
  std::string filename(subject);
  for(std::string::size_type i = filename.find('/');i!=std::string::npos;
      i=filename.find('/',i+1)) filename[i]='_';
  filename=dir_+filename;
  FileLock lock(pool_handle_);
  if(!lock) failure("failed to lock pool file");
  // Check for existing mapping
  struct stat st;
  if(stat(filename.c_str(),&st) == 0) {
    if(!S_ISREG(st.st_mode)) failure("mapping is not a regular file");
    std::ifstream f(filename.c_str());
    if(!f.is_open()) failure("can't open mapping file");
    std::string name;
    getline(f,name);
    utime(filename.c_str(),NULL);
    return name;
  };
  // Look for unused names
  // Get full list first.
  std::list<std::string> names;
  {
    std::ifstream f((dir_+"pool").c_str());
    if(!f.is_open()) failure("can't open pool file")
    std::string name;
    while(!f.eof()) {
      std::getline(f,name);
      if(!f.fail()) break;
      if(name.empty()) continue;
      names.push_back(name);
    };
  };
  if(!names.size()) failure("pool is empty");
  // Remove all used names from list. Also find oldest maping.
  time_t oldmap_time = 0;
  std::string oldmap_name;
  std::string oldmap_subject;
  try {
    std::string file;
    Glib::Dir dir(dir_);
    for(;;) {
      file=dir.read_name();
      if(file.empty()) break;
      if(file == ".") continue;
      if(file == "..") continue;
      if(file == "pool") continue;
      std::string filename = dir_+file;
      struct stat st;
      if(stat(filename.c_str(),&st) != 0) continue;
      if(!S_ISREG(st.st_mode)) continue;
      std::ifstream f(filename.c_str());
      if(!f.is_open()) { // trash in directory
        failure("can't open one of mapping files"); 
      };
      std::string name;
      std::getline(f,name);
      // find this name in list
      std::list<std::string>::iterator i = names.begin();
      for(;i!=names.end();++i) if(*i == name) break;
      if(i == names.end()) {
        // Always try to destroy old mappings without corresponding 
        // entry in the pool file
        if(((unsigned int)(time(NULL) - st.st_mtime)) >= SELFUNMAP_TIME) {
          unlink(filename.c_str());
        };
      } else {
        names.erase(i);
        if( (oldmap_name.length() == 0) ||
            (((int)(oldmap_time - st.st_mtime)) > 0) ) {
          oldmap_name=name;
          oldmap_subject=file;
          oldmap_time=st.st_mtime;
        };
      };
    };
  } catch(Glib::FileError& e) {
    failure("can't list pool directory");
  };
  if(names.size()) {
    // Claim one of unused names
    std::ofstream f(filename.c_str());
    if(!f.is_open()) failure("can't create mapping file");
    f<<*(names.begin())<<std::endl;
    info(std::string("Mapped ")+subject+" to "+(*(names.begin())));
    return *(names.begin());
  };
  // Try to release one of old names
  if(oldmap_name.length() == 0) failure("no old mappings found");
  if(((unsigned int)(time(NULL) - oldmap_time)) < SELFUNMAP_TIME) failure("no old enough mappings found");
  // releasing the old entry
  info(std::string("Releasing expired mapping of ")+oldmap_subject+
       " to "+oldmap_name+" back to pool");
  if(unlink((dir_+oldmap_subject).c_str()) != 0) failure("failed to remove mapping file");
  // writing the new mapping to the file
  std::ofstream f(filename.c_str());
  if(!f.is_open()) failure("can't create mapping file");
  f<<oldmap_name<<std::endl;
  info(std::string("Mapped ")+subject+" to "+oldmap_name);
  return oldmap_name;
}

Here is the caller graph for this function:

ArcSec::SimpleMap::operator bool ( void  ) [inline]

Definition at line 16 of file SimpleMap.h.

{ return (pool_handle_ != -1); };
bool ArcSec::SimpleMap::operator! ( void  ) [inline]

Definition at line 17 of file SimpleMap.h.

{ return (pool_handle_ == -1); };
bool ArcSec::SimpleMap::unmap ( const std::string &  subject)

Definition at line 191 of file SimpleMap.cpp.

                                              {
  if(pool_handle_ == -1) return false;
  FileLock lock(pool_handle_);
  if(!lock) return false;
  if(unlink((dir_+subject).c_str()) == 0) return true;
  if(errno == ENOENT) return true;
  return false;
}

Member Data Documentation

std::string ArcSec::SimpleMap::dir_ [private]

Definition at line 9 of file SimpleMap.h.

Definition at line 10 of file SimpleMap.h.


The documentation for this class was generated from the following files: