35 #include <sys/types.h>
49 #include "BESCatalogDirectory.h"
50 #include "BESCatalogUtils.h"
51 #include "BESCatalogEntry.h"
53 #include "CatalogNode.h"
54 #include "CatalogItem.h"
57 #include "BESContainerStorageList.h"
58 #include "BESFileContainerStorage.h"
61 #include "BESInternalError.h"
62 #include "BESForbiddenError.h"
63 #include "BESNotFoundError.h"
71 #define PROLOG "BESCatalogDirectory::" << __func__ << "() - "
93 BESCatalogDirectory::~BESCatalogDirectory()
110 string use_node = node;
113 if (!node.empty() && node !=
"/") {
114 string::size_type pos = use_node.find_last_not_of(
"/");
115 use_node = use_node.substr(0, pos + 1);
120 if (use_node.empty()) use_node =
"/";
123 string fullnode = rootdir;
124 if (!use_node.empty()) {
130 fullnode = fullnode +
"/" + use_node;
134 string::size_type slash = fullnode.rfind(
"/");
135 if (slash != string::npos) {
136 basename = fullnode.substr(slash + 1, fullnode.length() - slash);
146 "BESCatalogDirectory::show_catalog: " <<
"use_node = " << use_node << endl <<
"rootdir = " << rootdir << endl <<
"fullnode = " << fullnode << endl <<
"basename = " << basename << endl);
160 entry->add_entry(myentry);
169 DIR *dip = opendir(fullnode.c_str());
177 string error =
"You do not have permission to view the node " + use_node;
185 bool dirs_only =
false;
198 BESCatalogUtils::bes_add_stat_info(myentry, fullnode);
207 (void) lstat(fullnode.c_str(), &buf);
208 if (S_ISLNK(buf.st_mode)) {
209 string error =
"You do not have permission to access node " + use_node;
213 statret = stat(fullnode.c_str(), &buf);
214 if (statret == 0 && S_ISREG(buf.st_mode)) {
215 BESCatalogUtils::bes_add_stat_info(myentry, fullnode);
217 list<string> services;
219 myentry->set_service_list(services);
221 else if (statret == 0) {
222 string error =
"You do not have permission to access " + use_node;
228 if (errno == ENOENT) {
229 string error =
"Node " + use_node +
" does not exist";
230 char *s_err = strerror(errno);
238 string error =
"Access denied for node " + use_node;
239 char *s_err = strerror(errno);
241 error = error + s_err;
248 string error =
"You do not have permission to access " + use_node;
275 static string get_time(time_t the_time,
bool use_local_time =
false)
277 char buf[
sizeof "YYYY-MM-DDTHH:MM:SSzone"];
287 status = strftime(buf,
sizeof buf,
"%FT%T%Z", gmtime(&the_time));
289 status = strftime(buf,
sizeof buf,
"%FT%T%Z", localtime(&the_time));
292 LOG(
"Error getting last modified time time for a leaf item in BESCatalogDirectory.");
300 CatalogItem *BESCatalogDirectory::make_item(
string path_prefix,
string item)
const
302 if (item ==
"." || item ==
"..")
306 BESDEBUG(MODULE, PROLOG <<
"Processing POSIX entry: " << item_path << endl);
311 BESDEBUG(MODULE, PROLOG <<
"catalog: " << this->
get_catalog_name() << endl);
312 BESDEBUG(MODULE, PROLOG <<
"include_item: " << (include_item?
"true":
"false") << endl);
313 BESDEBUG(MODULE, PROLOG <<
"exclude_item: " << (exclude_item?
"true":
"false") << endl);
325 (void) lstat(item_path.c_str(), &lbuf);
326 if (S_ISLNK(lbuf.st_mode))
331 int statret = stat(item_path.c_str(), &buf);
332 if (statret == 0 && S_ISDIR(buf.st_mode) && !exclude_item) {
333 BESDEBUG(MODULE, PROLOG << item_path <<
" is NODE" << endl);
334 return new CatalogItem(item, 0, get_time(buf.st_mtime), CatalogItem::node);
336 else if (statret == 0 && S_ISREG(buf.st_mode) && include_item) {
337 BESDEBUG(MODULE, PROLOG << item_path <<
" is LEAF" << endl);
338 return new CatalogItem(item, buf.st_size, get_time(buf.st_mtime),
345 if(exclude_item || !include_item){
346 msg = string(
"Excluded the item '").append(item_path).append(
"' from the catalog '").append(
get_catalog_name()).append(
"' node listing.");
349 string msg = string(
"Unable to create CatalogItem for '").append(
"' from the catalog '").append(
get_catalog_name()).append(
",' SKIPPING.");
351 BESDEBUG(MODULE, PROLOG << msg << endl);
391 throw BESInternalError(
"The path sent to BESCatalogDirectory::get_node() must start with a slash (/)", __FILE__, __LINE__);
402 struct stat full_path_stat_buf;
403 int stat_result = stat(fullpath.c_str(), &full_path_stat_buf);
406 string(
"Unable to 'stat' the path '") + fullpath +
"' errno says: " + std::strerror(errno),
411 if(S_ISREG(full_path_stat_buf.st_mode)){
412 BESDEBUG(MODULE, PROLOG <<
"The requested node '"+fullpath+
"' is actually a leaf. Wut do?" << endl);
416 node->set_leaf(item);
419 string msg(__func__);
420 msg +=
"() - Failed to build CatalogItem for "+ path +
" BESCatlogDirectory::make_item() returned NULL.",
424 BESDEBUG(MODULE, PROLOG <<
"Actually, I'm a LEAF (" << (
void*)item <<
")" << endl);
427 else if(S_ISDIR(full_path_stat_buf.st_mode)){
428 BESDEBUG(MODULE, PROLOG <<
"Processing directory node: "<< fullpath << endl);
436 string(
"The path '") + path +
"' is not included in the catalog '" +
get_catalog_name() +
"'.",
440 node->set_lmt(get_time(full_path_stat_buf.st_mtime));
442 dip = opendir(fullpath.c_str());
447 BESDEBUG(MODULE, PROLOG <<
"Unable to open '" << fullpath <<
"' SKIPPING (errno: " << std::strerror(errno) <<
")"<< endl);
452 while ((dit = readdir(dip)) != NULL) {
453 CatalogItem * item = make_item(fullpath, dit->d_name);
455 if(item->
get_type() == CatalogItem::node){
456 node->add_node(item);
459 node->add_leaf(item);
467 sort(node->nodes_begin(), node->nodes_end(), ordering);
468 sort(node->leaves_begin(), node->leaves_end(), ordering);
478 "A BESCatalogDirectory can only return nodes for directories and regular files. The path '" + path
479 +
"' is not a directory or a regular file for BESCatalog '" +
get_catalog_name() +
"'.", __FILE__, __LINE__);
509 if (path[0] !=
'/')
throw BESInternalError(
"The path sent to BESCatalogDirectory::get_node() must start with a slash (/)", __FILE__, __LINE__);
519 string fullpath = rootdir + path;
521 DIR *dip = opendir(fullpath.c_str());
524 "A BESCatalogDirectory can only return nodes for directory. The path '" + path
525 +
"' is not a directory for BESCatalog '" +
get_catalog_name() +
"'.", __FILE__, __LINE__);
534 string(
"The path '") + path +
"' is not included in the catalog '" +
get_catalog_name() +
"'.",
541 int statret = stat(fullpath.c_str(), &buf);
543 node->set_lmt(get_time(buf.st_mtime));
546 while ((dit = readdir(dip)) != NULL) {
547 string item = dit->d_name;
548 if (item ==
"." || item ==
"..")
continue;
550 string item_path = fullpath +
"/" + item;
562 (void) lstat(item_path.c_str(), &lbuf);
563 if (S_ISLNK(lbuf.st_mode))
continue;
567 statret = stat(item_path.c_str(), &buf);
568 if (statret == 0 && S_ISDIR(buf.st_mode) && !
get_catalog_utils()->exclude(item)) {
571 node->add_item(
new CatalogItem(item, 0, get_time(buf.st_mtime), CatalogItem::node));
573 node->add_node(
new CatalogItem(item, 0, get_time(buf.st_mtime), CatalogItem::node));
575 else if (statret == 0 && S_ISREG(buf.st_mode) &&
get_catalog_utils()->include(item)) {
578 node->add_item(
new CatalogItem(item, buf.st_size, get_time(buf.st_mtime),
581 node->add_leaf(
new CatalogItem(item, buf.st_size, get_time(buf.st_mtime),
585 VERBOSE(
"Excluded the item '" << item_path <<
"' from the catalog '" <<
get_catalog_name() <<
"' node listing.");
593 sort(node->nodes_begin(), node->nodes_end(), ordering);
594 sort(node->leaves_begin(), node->leaves_end(), ordering);
625 ostream &out,
const string &path)
const
627 auto_ptr<CatalogNode> node(
get_node(path));
630 for (CatalogNode::item_citer i = node->items_begin(), e = node->items_end(); i != e; ++i) {
631 if ((*i)->get_type() == CatalogItem::leaf && (*i)->is_data()) {
632 out << prefix << path << (*i)->get_name() << leaf_suffix << endl;
634 else if ((*i)->get_type() == CatalogItem::node) {
635 get_site_map(prefix, leaf_suffix, out, path + (*i)->get_name() +
"/");
640 if (!node_suffix.empty())
641 out << prefix << path << node_suffix << endl;
644 for (CatalogNode::item_citer i = node->nodes_begin(), e = node->nodes_end(); i != e; ++i) {
645 assert((*i)->get_type() == CatalogItem::node);
646 get_site_map(prefix, node_suffix, leaf_suffix, out, path + (*i)->get_name() +
"/");
650 for (CatalogNode::item_citer i = node->leaves_begin(), e = node->leaves_end(); i != e; ++i) {
651 assert((*i)->get_type() == CatalogItem::leaf);
652 if ((*i)->is_data() && !leaf_suffix.empty())
653 out << prefix << path << (*i)->get_name() << leaf_suffix << endl;
666 strm << BESIndent::LMarg <<
"BESCatalogDirectory::dump - (" << (
void *)
this <<
")" << endl;
669 strm << BESIndent::LMarg <<
"catalog utilities: " << endl;
672 BESIndent::UnIndent();
673 BESIndent::UnIndent();