/* * "$Id: filedex.cc,v 1.8 2007-02-18 21:46:49 rmf24 Exp $" * * Other Bits for RetroShare. * * Copyright 2004-2006 by Robert Fernie. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License Version 2 as published by the Free Software Foundation. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA. * * Please report all bugs and problems to "retroshare@lunamutt.com". * */ #include "filedex.h" #include #include #include #include #include fdex::fdex() { return; } fdex::fdex(const char *p, const char *d, const char *f, const char *e, int l, int v) :path(p), subdir(d), file(f), ext(e), len(l), vis(v) { return; } int filedex::load(std::list dirs) { std::list::iterator it; /* these must be done in the correct order to ensure * that the visibility is correct */ for(int i = FD_VIS_EXACT_ONLY; i <= FD_VIS_LISTING; i++) { for(it = dirs.begin(); it != dirs.end(); it++) { if (i == it -> vis) { //std::cerr << "Adding Type(" << it -> vis << ") " << it -> basepath; //std::cerr << std::endl; dirtodo.push_back(*it); } } } return processdirs(); } int filedex::clear() { std::list::iterator it; dirtodo.clear(); dirdone.clear(); for(it = files.begin(); it != files.end(); it++) { delete(*it); } files.clear(); for(it = dirlist.begin(); it != dirlist.end(); it++) { delete(*it); } dirlist.clear(); return 1; } std::string strtolower2(std::string in) { std::string out = in; for(int i = 0; i < (signed) out.length(); i++) { if (isupper(out[i])) { out[i] += 'a' - 'A'; } } return out; } std::string fileextension2(std::string in) { std::string out; bool found = false; for(int i = in.length() -1; (i >= 0) && (found == false); i--) { if (in[i] == '.') { found = true; for(int j = i+1; j < (signed) in.length(); j++) { out += in[j]; } } } return strtolower2(out); } std::list filedex::search(std::list terms, int limit, bool local) { bool found; std::list newlist; int matches = 0; std::list::iterator fit; std::list::iterator tit; //std::cerr << "filedex::search() looking for" << std::endl; //for(tit = terms.begin(); tit != terms.end(); tit++) // std::cerr << "\t(" << *tit << ")" << std::endl; //std::cerr << "Checking:" << std::endl; for(fit = files.begin(); fit != files.end(); fit++) { // ignore named only files. if ((!local) && ((*fit)->vis < FD_VIS_SEARCH)) continue; found = true; for(tit = terms.begin(); (tit != terms.end()) && (found); tit++) { std::string path = (*fit) -> subdir+"/"+(*fit)->file; std::string lowerpath = strtolower2(path); std::string lowerterm = strtolower2(*tit); //std::cerr << "\tLooking for (" << lowerterm; //std::cerr << ") in (" << lowerpath << ") "; if (strstr(lowerpath.c_str(), lowerterm.c_str()) == NULL) { found = false; //std::cerr << "\tFalse..." << std::endl; } else { //std::cerr << "\tTrue..." << std::endl; } } if (found) { //std::cerr << "Found Matching!" << std::endl; newlist.push_back(*fit); if (++matches == limit) { //std::cerr << "Reached Limit(" << limit << ")"; //std::cerr << "Returning Results" << std::endl; return newlist; } } } return newlist; } std::list filedex::dirlisting(std::string basedir) { std::list newlist; std::list::iterator fit; //std::cerr << "filedex::dirlisting() looking for subdir: " << basedir << std::endl; //std::cerr << "Checking:" << std::endl; for(fit = dirlist.begin(); fit != dirlist.end(); fit++) { //std::cerr << "DCHK(" << basedir << ") vs (" << (*fit) -> subdir << ")" << std::endl; if (basedir == (*fit) -> subdir) { /* in the dir */ //std::cerr << "Found Matching SubDir:"; //std::cerr << (*fit) -> subdir << std::endl; newlist.push_back(*fit); } } for(fit = files.begin(); fit != files.end(); fit++) { //std::cerr << "FCHK(" << basedir << ") vs (" << (*fit) -> subdir << ")" << std::endl; if (basedir == (*fit) -> subdir) { /* in the dir */ //std::cerr << "Found Matching File:"; //std::cerr << (*fit) -> subdir << std::endl; newlist.push_back(*fit); } } return newlist; } std::list filedex::findfilename(std::string name) { std::list newlist; std::list::iterator fit; std::cerr << "filedex::findfilename() looking for: " << name << std::endl; std::cerr << "Checking:" << std::endl; for(fit = files.begin(); fit != files.end(); fit++) { if (name == (*fit) -> file) { /* in the dir */ std::cerr << "Found Matching File!" << std::endl; newlist.push_back(*fit); } } return newlist; } int filedex::processdirs() { std::list::iterator it; std::list::iterator sit; std::string dirname; std::string subdir; std::string fname; std::string fullname; struct dirent *ent; struct stat buf; bool found = false; fdex *fx; int count = 0; int ficount = 0; while(dirtodo.size() > 0) { count++; it = dirtodo.begin(); DirItem currDir(*it); dirname = currDir.getFullPath(); dirtodo.erase(it); //std::cerr << "\tExamining: " << currDir.basepath; //std::cerr << " -/- " << currDir.subdir << std::endl; //std::cerr << "\t\t" << count << " Directories done, "; //std::cerr << dirtodo.size() << " to go! " << std::endl; // open directory. DIR *dir = opendir(dirname.c_str()); if (dir != NULL) { // read the directory. while(NULL != (ent = readdir(dir))) { fname = ent -> d_name; fullname = dirname + "/" + fname; subdir = currDir.subdir; // std::cerr << "Statting dirent: " << fullname.c_str() < getFullPath() == fullname) found = true; } for(sit = dirdone.begin(); sit != dirdone.end(); sit++) { if ((*sit) == fullname) found = true; } if (found == false) { // add to list to read. DirItem ndir(currDir.basepath, subdir+"/"+fname, currDir.vis); // Push to the front of the list -> so processing done in order. dirtodo.push_front(ndir); // std::cerr << "\t Adding Directory: " << fullname; // std::cerr << " to dirtodo" << std::endl; if (currDir.vis == FD_VIS_LISTING) { // add to dirlist dbase. fx = new fdex(fullname.c_str(), subdir.c_str(), fname.c_str(), "DIR", 0, currDir.vis); dirlist.push_back(fx); // std::cerr << "\t Adding Directory: " << fullname; // std::cerr << " to dirlist" << std::endl; } } } else if (S_ISREG(buf.st_mode)) { // add to dbase. fx = new fdex(fullname.c_str(), subdir.c_str(), fname.c_str(), (fileextension2(fname)).c_str(), buf.st_size, currDir.vis); //fx -> path = fullname; files.push_back(fx); ficount++; if (ficount % 100 == 0) { //std::cerr << "\tIndex(" << ficount << ") : "; //std::cerr << "\tIndexing File: " << fname; //std::cerr << std::endl; } } else { // warning. std::cerr << "\t Ignoring Unknown FileType"; std::cerr << std::endl; } } else { } } // should check error message. dirdone.push_back(dirname); closedir(dir); } else { //std::cerr << "Cannot Open Directory:" << dirname << std::endl; } } return 1; }