summaryrefslogtreecommitdiff
path: root/server/src/macrolist.cc
diff options
context:
space:
mode:
Diffstat (limited to 'server/src/macrolist.cc')
-rw-r--r--server/src/macrolist.cc116
1 files changed, 100 insertions, 16 deletions
diff --git a/server/src/macrolist.cc b/server/src/macrolist.cc
index 0d0916d..89abfe8 100644
--- a/server/src/macrolist.cc
+++ b/server/src/macrolist.cc
@@ -33,6 +33,24 @@
#include "debug.h"
#include "macroheaderparser.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+static inline bool isdir(std::string name)
+{
+ struct stat s;
+ stat(name.c_str(), &s);
+ return S_ISDIR(s.st_mode);
+}
+
+static inline bool isfile(std::string name)
+{
+ struct stat s;
+ stat(name.c_str(), &s);
+ return S_ISREG(s.st_mode);
+}
+
static std::vector<std::string> listdir(std::string path)
{
std::vector<std::string> files;
@@ -45,11 +63,21 @@ static std::vector<std::string> listdir(std::string path)
struct dirent *d;
while((d = readdir(dir)) != 0) {
- //if(d->d_type == DT_DIR) {
- std::string name = d->d_name;
- if(name.length() >= 4 && name.substr(name.length() - 4) == ".xml")
- files.push_back(name);
- //}
+ if(std::string(d->d_name) == "." || std::string(d->d_name) == "..") continue;
+
+ PRACRO_DEBUG(macrolist, "d_name: %s - d_type: %d\n", d->d_name, d->d_type);
+
+ if(isdir(path + "/" + d->d_name)) {
+ std::vector<std::string> sub = listdir(path + "/" + d->d_name);
+ files.insert(files.end(), sub.begin(), sub.end());
+ continue;
+ }
+
+ if(isfile(path + "/" + d->d_name)) {
+ std::string name = d->d_name;
+ if(name.length() >= 4 && name.substr(name.length() - 4) == ".xml")
+ files.push_back(path + "/" + name);
+ }
}
closedir(dir);
@@ -60,18 +88,16 @@ MacroList::MacroList(std::string macropath)
{
MutexAutolock lock(mutex);
+ inotify.addDirectory(macropath, WATCH_DEEP_FOLLOW,
+ IN_CLOSE_WRITE |
+ IN_MOVED_FROM | IN_MOVED_TO | IN_MOVE_SELF |
+ IN_DELETE | IN_DELETE_SELF);
+
this->macropath = macropath;
std::vector<std::string> macros = listdir(macropath);
std::vector<std::string>::iterator i = macros.begin();
while(i != macros.end()) {
- MacroHeaderParser parser(macropath + "/" + *i);
- try {
- parser.parse();
- Macro *macro = parser.getMacro();
- (*this)[macro->attributes["name"]][VersionStr(macro->attributes["version"])] = *i;
- } catch(Exception &e) {
- PRACRO_WARN(macrolist, "Skipping %s: %s\n", i->c_str(), e.what());
- }
+ addFile(*i);
i++;
}
@@ -91,19 +117,77 @@ MacroList::MacroList(std::string macropath)
}
}
+bool MacroList::removeFile(std::string file)
+{
+ // Check if the file is already in the tree.
+ iterator i = begin();
+ while(i != end()) {
+ MacroListItem::iterator j = i->second.begin();
+ while(j != i->second.end()) {
+ if(file == j->second) {
+ PRACRO_DEBUG(macrolist, "Removing file: %s\n", file.c_str());
+ i->second.erase(j->first);
+ /*
+ if(i->second.size() == 0) erase(i->first);
+ */
+ return true;
+ }
+ j++;
+ }
+ i++;
+ }
+
+ return false;
+}
+
+void MacroList::addFile(std::string file)
+{
+ PRACRO_DEBUG(macrolist, "Adding file: %s\n", file.c_str());
+ MacroHeaderParser parser(file);
+ try {
+ parser.parse();
+ Macro *macro = parser.getMacro();
+ (*this)[macro->attributes["name"]][VersionStr(macro->attributes["version"])] = file;
+ } catch(Exception &e) {
+ PRACRO_WARN(macrolist, "Skipping %s: %s\n", file.c_str(), e.what());
+ }
+}
+
+void MacroList::updateFile(std::string file)
+{
+ removeFile(file);
+ addFile(file);
+}
+
+void MacroList::updateList()
+{
+ while(inotify.hasEvents()) {
+ INotify::Event event = inotify.getNextEvent();
+ if(event.isCloseWriteEvent()) updateFile(event.name()+"/"+event.file());
+ if(event.isMovedFromEvent()) removeFile(event.name()+"/"+event.file());
+ if(event.isMovedToEvent()) updateFile(event.name()+"/"+event.file());
+ if(event.isDeleteEvent()) removeFile(event.name()+"/"+event.file());
+
+ if(event.isMoveSelfEvent()) {/* TODO: what to do here? */}
+ if(event.isDeleteSelfEvent()) {/* TODO: what to do here? */}
+ }
+}
+
std::string MacroList::getLatestVersion(std::string macro) throw(Exception)
{
MutexAutolock lock(mutex);
+ updateList();
+
if(find(macro) == end()) throw Exception("Macro ["+macro+"] does not exist");
MacroListItem mli = (*this)[macro];
- if(mli.size() == 0) return "";
+ if(mli.size() == 0) throw Exception("Macro ["+macro+"] does not exist");
PRACRO_DEBUG(macrolist, "Search for %s - found %s v%s\n",
macro.c_str(),
- (macropath + "/" + mli.begin()->second).c_str(),
+ mli.begin()->second.c_str(),
((std::string)mli.begin()->first).c_str());
- return macropath + "/" + mli.begin()->second;
+ return mli.begin()->second;
}
#ifdef TEST_MACROLIST