Back to index

nordugrid-arc-nox  1.1.0~rc6
SRMInfo.cpp
Go to the documentation of this file.
00001 #include <vector>
00002 #include <errno.h>
00003 #include <stdio.h>
00004 #include <sys/stat.h>
00005 
00006 #include <glibmm.h>
00007 
00008 #include <arc/StringConv.h>
00009 #include <arc/Logger.h>
00010 
00011 #include "SRMInfo.h"
00012 
00013 Arc::Logger SRMInfo::logger(Arc::Logger::getRootLogger(), "SRMInfo");
00014 
00015 bool SRMFileInfo::operator ==(SRMURL srm_url) {
00016   const std::string proto_val = srm_url.Option("protocol");
00017   if (host == srm_url.Host() &&
00018       (!srm_url.PortDefined() || port == srm_url.Port()) &&
00019       (proto_val.empty() || ((protocol == "gssapi") == srm_url.GSSAPI())) &&
00020       version == srm_url.SRMVersion())
00021     return true;
00022   return false;
00023 }
00024 
00025 std::string SRMFileInfo::versionString() const {
00026   switch (version) {
00027     case SRMURL::SRM_URL_VERSION_1: {
00028       return "1";
00029     }; break;
00030     case SRMURL::SRM_URL_VERSION_2_2: {
00031       return "2.2";
00032     }; break;
00033     default: {
00034       return "";
00035     }
00036   }
00037   return "";
00038 }
00039 
00040 Arc::SimpleCondition * SRMInfo::filelock = new Arc::SimpleCondition();
00041 
00042 SRMInfo::SRMInfo(std::string dir) {
00043   srm_info_filename = dir + G_DIR_SEPARATOR_S + "srms.conf";
00044 }
00045 
00046 bool SRMInfo::getSRMFileInfo(SRMFileInfo& srm_file_info) {
00047   
00048   struct stat fileStat;
00049   int err = stat( srm_info_filename.c_str(), &fileStat ); 
00050   if (0 != err || fileStat.st_size == 0) {
00051     if (0 != err && errno != ENOENT)
00052       logger.msg(Arc::WARNING, "Error reading srm info file %s:%s", srm_info_filename, strerror(errno));
00053     return false;
00054   }
00055 
00056   filelock->lock();
00057   FILE * pFile;
00058   char mystring [fileStat.st_size+1];
00059   pFile = fopen (srm_info_filename.c_str(), "r");
00060   if (pFile == NULL) {
00061     logger.msg(Arc::WARNING, "Error reading srm info file %s:%s", srm_info_filename, strerror(errno));
00062     filelock->unlock();
00063     return false;
00064   }
00065 
00066   // read in file
00067   char * res = fgets (mystring, sizeof(mystring), pFile);
00068   while (res) {
00069     std::string line(mystring);
00070     line = Arc::trim(line);
00071     if (line.length() > 0 && line[0] == '#') {
00072       res = fgets (mystring, sizeof(mystring), pFile);
00073       continue;
00074     }
00075     // split line
00076     std::vector<std::string> fields;
00077     Arc::tokenize(line, fields);
00078     if (fields.size() != 4) {
00079       if (line.length() > 0) 
00080         logger.msg(Arc::WARNING, "Bad format detected in file %s, in line %s", srm_info_filename, line);
00081       res = fgets (mystring, sizeof(mystring), pFile);
00082       continue;
00083     }
00084     // look for our combination of host and version
00085     if (fields.at(0) == srm_file_info.host && fields.at(3) == srm_file_info.versionString()) {
00086       int port_i = Arc::stringtoi(fields.at(1));
00087       if (port_i == 0) {
00088         logger.msg(Arc::WARNING, "Can't convert string %s to int in file %s, line %s", fields.at(1), srm_info_filename, line);
00089         res = fgets (mystring, sizeof(mystring), pFile);
00090         continue;
00091       }        
00092       srm_file_info.port = port_i;
00093       srm_file_info.protocol = fields.at(2);
00094       fclose(pFile);
00095       filelock->unlock();
00096       return true;
00097     }
00098     res = fgets (mystring, sizeof(mystring), pFile);
00099   }
00100   fclose(pFile);
00101   filelock->unlock();
00102   return false;
00103 }
00104 
00105 void SRMInfo::putSRMFileInfo(const SRMFileInfo& srm_file_info) {
00106    
00107   struct stat fileStat;
00108   int err = stat( srm_info_filename.c_str(), &fileStat ); 
00109   if (0 != err || fileStat.st_size == 0) {
00110     if (0 != err && errno != ENOENT) {
00111       logger.msg(Arc::WARNING, "Error reading srm info file %s:%s", srm_info_filename, strerror(errno));
00112       return;
00113     }
00114     
00115     // write new file
00116     filelock->lock();
00117     
00118     FILE * pFile;
00119     pFile = fopen (srm_info_filename.c_str(), "w");
00120     if (pFile == NULL) {
00121       logger.msg(Arc::ERROR, "Error opening srm info file for writing %s:%s", srm_info_filename, strerror(errno));
00122       filelock->unlock();
00123       return;
00124     }
00125     std::string header("# This file was automatically generated by ARC for caching SRM information.\n");
00126     header += "# Its format is lines with 4 entries separated by spaces:\n";
00127     header += "# hostname port protocol(gsi/gssapi) version\n#\n";
00128     header += "# This file can be freely edited, but it is not advisable while there\n";
00129     header += "# are on-going transfers. Comments begin with #\n#\n";
00130     header += srm_file_info.host + ' ' + Arc::tostring(srm_file_info.port) + ' ' + srm_file_info.protocol + ' ' + srm_file_info.versionString() + '\n';                       
00131     fputs ((char*)header.c_str(), pFile);
00132     fclose (pFile);
00133     filelock->unlock();
00134     return;
00135   }
00136 
00137   // file already exists, so add this entry/replace existing entry
00138   filelock->lock();
00139   FILE * pFile;
00140   char mystring [fileStat.st_size+1];
00141   pFile = fopen (srm_info_filename.c_str(), "r");
00142   if (pFile == NULL) {
00143     logger.msg(Arc::WARNING, "Error opening srm info file %s:%s", srm_info_filename, strerror(errno));
00144     filelock->unlock();
00145     return;
00146   }
00147 
00148   // read in file
00149   std::vector<std::string> lines;
00150   
00151   char * res = fgets (mystring, sizeof(mystring), pFile);
00152   while (res) {
00153     std::string line(mystring);
00154     line = Arc::trim(line);
00155     if (line.length() > 0 && line[0] == '#') {
00156       lines.push_back(line+'\n');
00157       res = fgets (mystring, sizeof(mystring), pFile);
00158       continue;
00159     }
00160     // split line
00161     std::vector<std::string> fields;
00162     Arc::tokenize(line, fields);
00163     if (fields.size() != 4) {
00164       if (line.length() > 0) 
00165         logger.msg(Arc::WARNING, "Bad format detected in file %s, in line %s", srm_info_filename, line);
00166       res = fgets (mystring, sizeof(mystring), pFile);
00167       continue;
00168     }
00169     // if any line contains our combination of host and version, ignore it
00170     if (fields.at(0) == srm_file_info.host && fields.at(3) == srm_file_info.versionString()) {
00171       res = fgets (mystring, sizeof(mystring), pFile);
00172       continue;
00173     }
00174     lines.push_back(line+'\n');
00175     res = fgets (mystring, sizeof(mystring), pFile);
00176   }
00177   fclose(pFile);
00178 
00179   // write everything back to the file
00180   pFile = fopen (srm_info_filename.c_str(), "w");
00181   if (pFile == NULL) {
00182     logger.msg(Arc::WARNING, "Error opening srm info file for writing %s:%s", srm_info_filename, strerror(errno));
00183     filelock->unlock();
00184     return;
00185   }
00186   
00187   for (std::vector<std::string>::iterator i = lines.begin(); i != lines.end(); i++) {
00188     fputs ((char*)i->c_str(), pFile);
00189   }
00190   std::string this_info = srm_file_info.host + ' ' + Arc::tostring(srm_file_info.port) + ' ' + srm_file_info.protocol + ' ' + srm_file_info.versionString() + '\n';                       
00191   fputs ((char*)this_info.c_str(), pFile);
00192   fclose (pFile);
00193   filelock->unlock();
00194 }