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