00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "config.h"
00034
00035 #include <sys/types.h>
00036 #include <sys/stat.h>
00037 #include <dirent.h>
00038
00039 #include <iostream>
00040 using std::cout ;
00041 using std::endl ;
00042
00043 #include "BESCatalogUtils.h"
00044 #include "TheBESKeys.h"
00045 #include "BESInternalError.h"
00046 #include "BESSyntaxUserError.h"
00047 #include "BESNotFoundError.h"
00048 #include "GNURegex.h"
00049 #include "Error.h"
00050 #include "BESUtil.h"
00051
00052 using namespace libdap ;
00053
00054 map<string, BESCatalogUtils *> BESCatalogUtils::_instances ;
00055
00056 BESCatalogUtils::
00057 BESCatalogUtils( const string &n )
00058 : _follow_syms( false )
00059 {
00060 string key = "BES.Catalog." + n + ".RootDirectory" ;
00061 bool found = false ;
00062 TheBESKeys::TheKeys()->get_value( key, _root_dir, found ) ;
00063 if( !found || _root_dir == "" )
00064 {
00065 string s = key + " not defined in BES configuration file" ;
00066 throw BESSyntaxUserError( s, __FILE__, __LINE__ ) ;
00067 }
00068 DIR *dip = opendir( _root_dir.c_str() ) ;
00069 if( dip == NULL )
00070 {
00071 string serr = "BESCatalogDirectory - root directory "
00072 + _root_dir + " does not exist" ;
00073 throw BESNotFoundError( serr, __FILE__, __LINE__ ) ;
00074 }
00075 closedir( dip ) ;
00076
00077 found = false ;
00078 key = (string)"BES.Catalog." + n + ".Exclude" ;
00079 vector<string> vals ;
00080 TheBESKeys::TheKeys()->get_values( key, vals, found ) ;
00081 vector<string>::iterator ei = vals.begin() ;
00082 vector<string>::iterator ee = vals.end() ;
00083 for( ; ei != ee; ei++ )
00084 {
00085 string e_str = (*ei) ;
00086 if( !e_str.empty() && e_str != ";" )
00087 BESUtil::explode( ';', e_str, _exclude ) ;
00088 }
00089
00090 key = (string)"BES.Catalog." + n + ".Include" ;
00091 vals.clear() ;
00092 TheBESKeys::TheKeys()->get_values( key, vals, found ) ;
00093 vector<string>::iterator ii = vals.begin() ;
00094 vector<string>::iterator ie = vals.end() ;
00095 for( ; ii != ie; ii++ )
00096 {
00097 string i_str = (*ii) ;
00098 if( !i_str.empty() && i_str != ";" )
00099 BESUtil::explode( ';', i_str, _include ) ;
00100 }
00101
00102 key = "BES.Catalog." + n + ".TypeMatch" ;
00103 list<string> match_list ;
00104 vals.clear() ;
00105 TheBESKeys::TheKeys()->get_values( key, vals, found ) ;
00106 if( !found || vals.size() == 0 )
00107 {
00108 string s = key + " not defined in key file" ;
00109 throw BESInternalError( s, __FILE__, __LINE__ ) ;
00110 }
00111 vector<string>::iterator vi = vals.begin() ;
00112 vector<string>::iterator ve = vals.end() ;
00113 for( ; vi != ve; vi++ )
00114 {
00115 BESUtil::explode( ';', (*vi), match_list ) ;
00116 }
00117
00118 list<string>::iterator mli = match_list.begin() ;
00119 list<string>::iterator mle = match_list.end() ;
00120 for( ; mli != mle; mli++ )
00121 {
00122 if( !((*mli).empty()) && *(mli) != ";" )
00123 {
00124 list<string> amatch ;
00125 BESUtil::explode( ':', (*mli), amatch ) ;
00126 if( amatch.size() != 2 )
00127 {
00128 string s = (string)"Catalog type match malformed, "
00129 + "looking for type:regexp;[type:regexp;]" ;
00130 throw BESInternalError( s, __FILE__, __LINE__ ) ;
00131 }
00132 list<string>::iterator ami = amatch.begin() ;
00133 type_reg newval ;
00134 newval.type = (*ami) ;
00135 ami++ ;
00136 newval.reg = (*ami) ;
00137 _match_list.push_back( newval ) ;
00138 }
00139 }
00140
00141 key = (string)"BES.Catalog." + n + ".FollowSymLinks" ;
00142 string s_str ;
00143 TheBESKeys::TheKeys()->get_value( key, s_str, found ) ;
00144 s_str = BESUtil::lowercase( s_str ) ;
00145 if( s_str == "yes" || s_str == "on" || s_str == "true" )
00146 {
00147 _follow_syms = true ;
00148 }
00149 }
00150
00151 bool
00152 BESCatalogUtils::include( const string &inQuestion ) const
00153 {
00154 bool toInclude = false ;
00155
00156
00157
00158
00159 if( _include.size() == 0 )
00160 {
00161 toInclude = true ;
00162 }
00163 else
00164 {
00165 list<string>::const_iterator i_iter = _include.begin() ;
00166 list<string>::const_iterator i_end = _include.end() ;
00167 for( ; i_iter != i_end; i_iter++ )
00168 {
00169 string reg = *i_iter ;
00170 try
00171 {
00172
00173
00174 Regex reg_expr( reg.c_str() ) ;
00175 if( reg_expr.match( inQuestion.c_str(), inQuestion.length() ) ==
00176 static_cast<int>(inQuestion.length()) )
00177 {
00178 toInclude = true ;
00179 }
00180 }
00181 catch( Error &e )
00182 {
00183 string serr = (string)"Unable to get catalog information, "
00184 + "malformed Catalog Include parameter "
00185 + "in bes configuration file around "
00186 + reg + ": " + e.get_error_message() ;
00187 throw BESInternalError( serr, __FILE__, __LINE__ ) ;
00188 }
00189 }
00190 }
00191
00192 if( toInclude == true )
00193 {
00194 if( exclude( inQuestion ) )
00195 {
00196 toInclude = false ;
00197 }
00198 }
00199
00200 return toInclude ;
00201 }
00202
00203 bool
00204 BESCatalogUtils::exclude( const string &inQuestion ) const
00205 {
00206 list<string>::const_iterator e_iter = _exclude.begin() ;
00207 list<string>::const_iterator e_end = _exclude.end() ;
00208 for( ; e_iter != e_end; e_iter++ )
00209 {
00210 string reg = *e_iter ;
00211 try
00212 {
00213 Regex reg_expr( reg.c_str() ) ;
00214 if( reg_expr.match( inQuestion.c_str(), inQuestion.length() ) ==
00215 static_cast<int>(inQuestion.length()) )
00216 {
00217 return true ;
00218 }
00219 }
00220 catch( Error &e )
00221 {
00222 string serr = (string)"Unable to get catalog information, "
00223 + "malformed Catalog Exclude parameter "
00224 + "in bes configuration file around "
00225 + reg + ": " + e.get_error_message() ;
00226 throw BESInternalError( serr, __FILE__, __LINE__ ) ;
00227 }
00228 }
00229 return false ;
00230 }
00231
00232 BESCatalogUtils::match_citer
00233 BESCatalogUtils::match_list_begin() const
00234 {
00235 return _match_list.begin() ;
00236 }
00237
00238 BESCatalogUtils::match_citer
00239 BESCatalogUtils::match_list_end() const
00240 {
00241 return _match_list.end() ;
00242 }
00243
00244 void
00245 BESCatalogUtils::dump( ostream &strm ) const
00246 {
00247 strm << BESIndent::LMarg << "BESCatalogUtils::dump - ("
00248 << (void *)this << ")" << endl ;
00249 BESIndent::Indent() ;
00250
00251 strm << BESIndent::LMarg << "root directory: " << _root_dir << endl ;
00252
00253 if( _include.size() )
00254 {
00255 strm << BESIndent::LMarg << "include list:" << endl ;
00256 BESIndent::Indent() ;
00257 list<string>::const_iterator i_iter = _include.begin() ;
00258 list<string>::const_iterator i_end = _include.end() ;
00259 for( ; i_iter != i_end; i_iter++ )
00260 {
00261 strm << BESIndent::LMarg << *i_iter << endl ;
00262 }
00263 BESIndent::UnIndent() ;
00264 }
00265 else
00266 {
00267 strm << BESIndent::LMarg << "include list: empty" << endl ;
00268 }
00269
00270 if( _exclude.size() )
00271 {
00272 strm << BESIndent::LMarg << "exclude list:" << endl ;
00273 BESIndent::Indent() ;
00274 list<string>::const_iterator e_iter = _exclude.begin() ;
00275 list<string>::const_iterator e_end = _exclude.end() ;
00276 for( ; e_iter != e_end; e_iter++ )
00277 {
00278 strm << BESIndent::LMarg << *e_iter << endl ;
00279 }
00280 BESIndent::UnIndent() ;
00281 }
00282 else
00283 {
00284 strm << BESIndent::LMarg << "exclude list: empty" << endl ;
00285 }
00286
00287 if( _match_list.size() )
00288 {
00289 strm << BESIndent::LMarg << "type matches:" << endl ;
00290 BESIndent::Indent() ;
00291 BESCatalogUtils::match_citer i = _match_list.begin() ;
00292 BESCatalogUtils::match_citer ie = _match_list.end() ;
00293 for( ; i != ie; i++ )
00294 {
00295 type_reg match = (*i) ;
00296 strm << BESIndent::LMarg << match.type << " : "
00297 << match.reg << endl ;
00298 }
00299 BESIndent::UnIndent() ;
00300 }
00301 else
00302 {
00303 strm << BESIndent::LMarg << " type matches: empty" << endl ;
00304 }
00305
00306 if( _follow_syms )
00307 {
00308 strm << BESIndent::LMarg << " follow symbolic links: on" << endl ;
00309 }
00310 else
00311 {
00312 strm << BESIndent::LMarg << " follow symbolic links: off" << endl ;
00313 }
00314
00315 BESIndent::UnIndent() ;
00316 }
00317
00318 const BESCatalogUtils *
00319 BESCatalogUtils::Utils( const string &cat_name )
00320 {
00321 BESCatalogUtils *utils = BESCatalogUtils::_instances[cat_name] ;
00322 if( !utils )
00323 {
00324 utils = new BESCatalogUtils( cat_name );
00325 BESCatalogUtils::_instances[cat_name] = utils ;
00326 }
00327 return utils ;
00328 }
00329