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 #include "stdio.h"
00037
00038 #include <sstream>
00039
00040 using std::stringstream ;
00041 using std::endl ;
00042
00043 #include "BESCatalogDirectory.h"
00044 #include "BESCatalogUtils.h"
00045 #include "BESInfo.h"
00046 #include "BESResponseException.h"
00047 #include "BESResponseNames.h"
00048 #include "BESCatalogUtils.h"
00049 #include "BESContainerStorageList.h"
00050 #include "BESContainerStorageCatalog.h"
00051
00052 BESCatalogDirectory::BESCatalogDirectory( const string &name )
00053 : BESCatalog( name )
00054 {
00055 try
00056 {
00057 _utils = BESCatalogUtils::Utils( name ) ;
00058 }
00059 catch( BESException &e )
00060 {
00061 throw BESResponseException( e.get_message(), e.get_file(), e.get_line() ) ;
00062 }
00063 }
00064
00065 BESCatalogDirectory::~BESCatalogDirectory( )
00066 {
00067 }
00068
00069 bool
00070 BESCatalogDirectory::show_catalog( const string &node,
00071 const string &coi,
00072 BESInfo *info )
00073 {
00074
00075 string fullnode = node ;
00076 if( node != "" )
00077 {
00078 string::size_type stopat = node.length() - 1 ;
00079 while( node[stopat] == '/' )
00080 {
00081 stopat-- ;
00082 }
00083 fullnode = fullnode.substr( 0, stopat + 1 ) ;
00084 }
00085
00086 string::size_type dotdot = fullnode.find( ".." ) ;
00087 if( dotdot != string::npos )
00088 {
00089 string s = (string)"'../' not allowed in catalog node name " + fullnode;
00090 throw BESResponseException( s, __FILE__, __LINE__ ) ;
00091 }
00092
00093 if( fullnode == "" )
00094 {
00095 fullnode = _utils->get_root_dir() ;
00096 }
00097 else
00098 {
00099 fullnode = _utils->get_root_dir() + "/" + fullnode ;
00100 }
00101
00102 string basename ;
00103 string::size_type slash = fullnode.rfind( "/" ) ;
00104 if( slash != string::npos )
00105 {
00106 basename = fullnode.substr( slash+1, fullnode.length() - slash ) ;
00107 }
00108 else
00109 {
00110 basename = fullnode ;
00111 }
00112
00113
00114 DIR *dip = opendir( fullnode.c_str() ) ;
00115 if( dip != NULL )
00116 {
00117
00118
00119
00120
00121 if( _utils->exclude( basename ) )
00122 {
00123 return false ;
00124 }
00125 struct stat cbuf ;
00126 int statret = stat( fullnode.c_str(), &cbuf ) ;
00127 if( statret == 0 )
00128 {
00129 map<string,string> a1 ;
00130 a1["thredds_collection"] = "\"true\"" ;
00131 a1["isData"] = "\"false\"" ;
00132 info->begin_tag( "dataset", &a1 ) ;
00133 if( node == "" )
00134 {
00135 add_stat_info( info, cbuf, "/" ) ;
00136 }
00137 else
00138 {
00139 add_stat_info( info, cbuf, node ) ;
00140 }
00141
00142 struct dirent *dit;
00143 unsigned int cnt = 0 ;
00144 struct stat buf;
00145 while( ( dit = readdir( dip ) ) != NULL )
00146 {
00147 string dirEntry = dit->d_name ;
00148 if( dirEntry != "." && dirEntry != ".." )
00149 {
00150
00151 string fullPath = fullnode + "/" + dirEntry ;
00152 statret = stat( fullPath.c_str(), &buf ) ;
00153 if ( statret == 0 && S_ISDIR( buf.st_mode ) )
00154 {
00155 if( _utils->exclude( dirEntry ) == false )
00156 {
00157 cnt++ ;
00158 }
00159 }
00160
00161
00162
00163 else
00164 {
00165 if( _utils->include( dirEntry ) )
00166 {
00167 cnt++ ;
00168 }
00169 }
00170 }
00171 }
00172
00173 stringstream sscnt ;
00174 sscnt << cnt ;
00175 info->add_tag( "count", sscnt.str() ) ;
00176
00177 if( coi == CATALOG_RESPONSE )
00178 {
00179 rewinddir( dip ) ;
00180
00181 while( ( dit = readdir( dip ) ) != NULL )
00182 {
00183 string dirEntry = dit->d_name ;
00184 if( dirEntry != "." && dirEntry != ".." )
00185 {
00186
00187 string fullPath = fullnode + "/" + dirEntry ;
00188 statret = stat( fullPath.c_str(), &buf ) ;
00189 if ( statret == 0 && S_ISDIR( buf.st_mode ) )
00190 {
00191 if( _utils->exclude( dirEntry ) == false )
00192 {
00193 map<string,string> a2 ;
00194 a2["thredds_collection"] = "\"true\"" ;
00195 a2["isData"] = "\"false\"" ;
00196 a2["isAccessible"] = "\"true\"" ;
00197 info->begin_tag( "dataset", &a2 ) ;
00198 add_stat_info( info, buf, dirEntry ) ;
00199 info->end_tag( "dataset" ) ;
00200 }
00201 }
00202 else if ( statret == 0 && S_ISREG( buf.st_mode ) )
00203 {
00204 if( _utils->include( dirEntry ) )
00205 {
00206 map<string,string> a3 ;
00207 a3["thredds_collection"] = "\"false\"" ;
00208 list<string> provides ;
00209 if( isData( fullPath, provides ) )
00210 a3["isData"] = "\"true\"" ;
00211 else
00212 a3["isData"] = "\"false\"" ;
00213 a3["isAccessible"] = "\"true\"" ;
00214 info->begin_tag( "dataset", &a3 ) ;
00215 add_stat_info( info, buf, dirEntry ) ;
00216 info->end_tag( "dataset" ) ;
00217 }
00218 }
00219 else
00220 {
00221 if( _utils->include( dirEntry ) )
00222 {
00223 map<string,string> a3 ;
00224 a3["thredds_collection"] = "\"false\"" ;
00225 a3["isData"] = "\"false\"" ;
00226 a3["isAccessible"] = "\"false\"" ;
00227 info->begin_tag( "dataset", &a3 ) ;
00228 info->add_tag( "name", dirEntry ) ;
00229 info->end_tag( "dataset" ) ;
00230 }
00231 }
00232 }
00233 }
00234 }
00235 closedir( dip ) ;
00236 info->end_tag( "dataset" ) ;
00237 }
00238 else
00239 {
00240 map<string,string> a1 ;
00241 a1["thredds_collection"] = "\"true\"" ;
00242 a1["isData"] = "\"false\"" ;
00243 a1["isAccessible"] = "\"false\"" ;
00244 info->begin_tag( "dataset", &a1 ) ;
00245 if( node == "" )
00246 info->add_tag( "name", "/" ) ;
00247 else
00248 info->add_tag( "name", node ) ;
00249 info->end_tag( "dataset" ) ;
00250 }
00251 }
00252 else
00253 {
00254
00255
00256 if( _utils->include( basename ) )
00257 {
00258 struct stat buf;
00259 int statret = stat( fullnode.c_str(), &buf ) ;
00260 if ( statret == 0 && S_ISREG( buf.st_mode ) )
00261 {
00262 map<string,string> a4 ;
00263 a4["thredds_collection"] = "\"false\"" ;
00264 list<string> provides ;
00265 if( isData( node, provides ) )
00266 a4["isData"] = "\"true\"" ;
00267 else
00268 a4["isData"] = "\"false\"" ;
00269 a4["isAccessible"] = "\"true\"" ;
00270 info->begin_tag( "dataset", &a4 ) ;
00271 add_stat_info( info, buf, node ) ;
00272 info->end_tag( "dataset" ) ;
00273 }
00274 else
00275 {
00276 return false ;
00277 }
00278 }
00279 else
00280 {
00281 return false ;
00282 }
00283 }
00284
00285 return true ;
00286 }
00287
00288 void
00289 BESCatalogDirectory::add_stat_info( BESInfo *info,
00290 struct stat &buf,
00291 const string &node )
00292 {
00293 info->add_tag( "name", node ) ;
00294
00295 off_t sz = buf.st_size ;
00296 stringstream ssz ;
00297 ssz << sz ;
00298 info->add_tag( "size", ssz.str() ) ;
00299
00300
00301
00302 time_t mod = buf.st_mtime ;
00303 struct tm *stm = gmtime( &mod ) ;
00304 char mdate[64] ;
00305 strftime( mdate, 64, "%Y-%m-%d", stm ) ;
00306 char mtime[64] ;
00307 strftime( mtime, 64, "%T", stm ) ;
00308
00309 info->begin_tag( "lastmodified" ) ;
00310
00311 stringstream sdt ;
00312 sdt << mdate ;
00313 info->add_tag( "date", sdt.str() ) ;
00314
00315 stringstream stt ;
00316 stt << mtime ;
00317 info->add_tag( "time", stt.str() ) ;
00318
00319 info->end_tag( "lastmodified" ) ;
00320 }
00321
00322 bool
00323 BESCatalogDirectory::isData( const string &inQuestion,
00324 list<string> &provides )
00325 {
00326 BESContainerStorage *store =
00327 BESContainerStorageList::TheList()->find_persistence( get_catalog_name() ) ;
00328 if( !store )
00329 return false ;
00330
00331 BESContainerStorageCatalog *cat_store =
00332 dynamic_cast<BESContainerStorageCatalog *>(store ) ;
00333 if( !cat_store )
00334 return false ;
00335
00336 return cat_store->isData( inQuestion, provides ) ;
00337 }
00338
00346 void
00347 BESCatalogDirectory::dump( ostream &strm ) const
00348 {
00349 strm << BESIndent::LMarg << "BESCatalogDirectory::dump - ("
00350 << (void *)this << ")" << endl ;
00351 BESIndent::Indent() ;
00352
00353 strm << BESIndent::LMarg << "catalog utilities: " << endl ;
00354 BESIndent::Indent() ;
00355 _utils->dump( strm ) ;
00356 BESIndent::UnIndent() ;
00357 BESIndent::UnIndent() ;
00358 }
00359