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 DIR *dip = opendir( fullnode.c_str() ) ;
00113 if( dip != NULL )
00114 {
00115
00116
00117 if( _utils->exclude( basename ) )
00118 {
00119 return false ;
00120 }
00121 struct stat cbuf ;
00122 stat( fullnode.c_str(), &cbuf ) ;
00123 map<string,string> a1 ;
00124 a1["thredds_collection"] = "\"true\"" ;
00125 a1["isData"] = "\"false\"" ;
00126 info->begin_tag( "dataset", &a1 ) ;
00127 if( node == "" )
00128 {
00129 add_stat_info( info, cbuf, "/" ) ;
00130 }
00131 else
00132 {
00133 add_stat_info( info, cbuf, node ) ;
00134 }
00135
00136 struct dirent *dit;
00137 unsigned int cnt = 0 ;
00138 struct stat buf;
00139 while( ( dit = readdir( dip ) ) != NULL )
00140 {
00141 string dirEntry = dit->d_name ;
00142 if( dirEntry != "." && dirEntry != ".." )
00143 {
00144
00145 string fullPath = fullnode + "/" + dirEntry ;
00146 stat( fullPath.c_str(), &buf ) ;
00147 if ( S_ISDIR( buf.st_mode ) )
00148 {
00149 if( _utils->exclude( dirEntry ) == false )
00150 {
00151 cnt++ ;
00152 }
00153 }
00154 else if ( S_ISREG( buf.st_mode ) )
00155 {
00156 if( _utils->include( dirEntry ) )
00157 {
00158 cnt++ ;
00159 }
00160 }
00161 }
00162 }
00163
00164 stringstream sscnt ;
00165 sscnt << cnt ;
00166 info->add_tag( "count", sscnt.str() ) ;
00167
00168 if( coi == CATALOG_RESPONSE )
00169 {
00170 rewinddir( dip ) ;
00171
00172 while( ( dit = readdir( dip ) ) != NULL )
00173 {
00174 string dirEntry = dit->d_name ;
00175 if( dirEntry != "." && dirEntry != ".." )
00176 {
00177
00178 string fullPath = fullnode + "/" + dirEntry ;
00179 stat( fullPath.c_str(), &buf ) ;
00180 if ( S_ISDIR( buf.st_mode ) )
00181 {
00182 if( _utils->exclude( dirEntry ) == false )
00183 {
00184 map<string,string> a2 ;
00185 a2["thredds_collection"] = "\"true\"" ;
00186 a2["isData"] = "\"false\"" ;
00187 info->begin_tag( "dataset", &a2 ) ;
00188 add_stat_info( info, buf, dirEntry ) ;
00189 info->end_tag( "dataset" ) ;
00190 }
00191 }
00192 else if ( S_ISREG( buf.st_mode ) )
00193 {
00194 if( _utils->include( dirEntry ) )
00195 {
00196 map<string,string> a3 ;
00197 a3["thredds_collection"] = "\"false\"" ;
00198 list<string> provides ;
00199 if( isData( dirEntry, provides ) )
00200 a3["isData"] = "\"true\"" ;
00201 else
00202 a3["isData"] = "\"false\"" ;
00203 info->begin_tag( "dataset", &a3 ) ;
00204 add_stat_info( info, buf, dirEntry ) ;
00205 info->end_tag( "dataset" ) ;
00206 }
00207 }
00208 }
00209 }
00210 }
00211 closedir( dip ) ;
00212 info->end_tag( "dataset" ) ;
00213 }
00214 else
00215 {
00216
00217
00218 if( _utils->include( basename ) )
00219 {
00220 struct stat buf;
00221 int statret = stat( fullnode.c_str(), &buf ) ;
00222 if ( statret == 0 && S_ISREG( buf.st_mode ) )
00223 {
00224 map<string,string> a4 ;
00225 a4["thredds_collection"] = "\"false\"" ;
00226 list<string> provides ;
00227 if( isData( node, provides ) )
00228 a4["isData"] = "\"true\"" ;
00229 else
00230 a4["isData"] = "\"false\"" ;
00231 info->begin_tag( "dataset", &a4 ) ;
00232 add_stat_info( info, buf, node ) ;
00233 info->end_tag( "dataset" ) ;
00234 }
00235 else
00236 {
00237 return false ;
00238 }
00239 }
00240 else
00241 {
00242 return false ;
00243 }
00244 }
00245
00246 return true ;
00247 }
00248
00249 void
00250 BESCatalogDirectory::add_stat_info( BESInfo *info,
00251 struct stat &buf,
00252 const string &node )
00253 {
00254 info->add_tag( "name", node ) ;
00255
00256 off_t sz = buf.st_size ;
00257 stringstream ssz ;
00258 ssz << sz ;
00259 info->add_tag( "size", ssz.str() ) ;
00260
00261
00262
00263 time_t mod = buf.st_mtime ;
00264 struct tm *stm = gmtime( &mod ) ;
00265 char mdate[64] ;
00266 strftime( mdate, 64, "%Y-%m-%d", stm ) ;
00267 char mtime[64] ;
00268 strftime( mtime, 64, "%T", stm ) ;
00269
00270 info->begin_tag( "lastmodified" ) ;
00271
00272 stringstream sdt ;
00273 sdt << mdate ;
00274 info->add_tag( "date", sdt.str() ) ;
00275
00276 stringstream stt ;
00277 stt << mtime ;
00278 info->add_tag( "time", stt.str() ) ;
00279
00280 info->end_tag( "lastmodified" ) ;
00281 }
00282
00283 bool
00284 BESCatalogDirectory::isData( const string &inQuestion,
00285 list<string> &provides )
00286 {
00287 BESContainerStorage *store =
00288 BESContainerStorageList::TheList()->find_persistence( get_catalog_name() ) ;
00289 if( !store )
00290 return false ;
00291
00292 BESContainerStorageCatalog *cat_store =
00293 dynamic_cast<BESContainerStorageCatalog *>(store ) ;
00294 if( !cat_store )
00295 return false ;
00296
00297 return cat_store->isData( inQuestion, provides ) ;
00298 }
00299
00307 void
00308 BESCatalogDirectory::dump( ostream &strm ) const
00309 {
00310 strm << BESIndent::LMarg << "BESCatalogDirectory::dump - ("
00311 << (void *)this << ")" << endl ;
00312 BESIndent::Indent() ;
00313
00314 strm << BESIndent::LMarg << "catalog utilities: " << endl ;
00315 BESIndent::Indent() ;
00316 _utils->dump( strm ) ;
00317 BESIndent::UnIndent() ;
00318 BESIndent::UnIndent() ;
00319 }
00320