added optional extended file attributes support

This commit is contained in:
dockes
2009-01-21 13:55:12 +00:00
parent 420e258478
commit 229645a0e2
19 changed files with 1044 additions and 11 deletions
+21 -3
View File
@@ -19,6 +19,7 @@ static char rcsid[] = "@(#$Id: internfile.cpp,v 1.46 2008-10-10 08:04:54 dockes
*/
#ifndef TEST_INTERNFILE
#include "autoconfig.h"
#include <unistd.h>
#include <fcntl.h>
@@ -132,7 +133,7 @@ void FileInterner::tmpcleanup()
//
// Empty handler on return says that we're in error, this will be
// processed by the first call to internfile().
FileInterner::FileInterner(const std::string &f, const struct stat *stp,
FileInterner::FileInterner(const string &f, const struct stat *stp,
RclConfig *cnf,
const string& td, const string *imime)
: m_cfg(cnf), m_fn(f), m_forPreview(imime?true:false), m_tdir(td)
@@ -337,7 +338,12 @@ static const string keytt("title");
bool FileInterner::dijontorcl(Rcl::Doc& doc)
{
Dijon::Filter *df = m_handlers.back();
const std::map<std::string, std::string>& docdata = df->get_meta_data();
if (df == 0) {
//??
LOGERR(("FileInterner::dijontorcl: null top handler ??\n"));
return false;
}
const map<string, string>& docdata = df->get_meta_data();
for (map<string,string>::const_iterator it = docdata.begin();
it != docdata.end(); it++) {
@@ -357,6 +363,18 @@ bool FileInterner::dijontorcl(Rcl::Doc& doc)
doc.meta[Rcl::Doc::keyabs] = doc.meta[keyds];
doc.meta.erase(keyds);
}
#ifdef RCL_USE_XATTR
// Finally set any data possibly coming out of the extended file attributes
// these override any values from inside the file.
RecollFilter *rf = dynamic_cast<RecollFilter*>(df);
if (rf != 0) {
const map<string, string>& ffa = rf->getFieldsFromAttrs();
for (map<string,string>::const_iterator it = ffa.begin();
it != ffa.end(); it++) {
doc.meta[it->first] = it->second;
}
}
#endif //RCL_USE_XATTR
return true;
}
@@ -425,7 +443,7 @@ enum addResols {ADD_OK, ADD_CONTINUE, ADD_BREAK, ADD_ERROR};
// and possibly add a filter/handler to the stack
int FileInterner::addHandler()
{
const std::map<std::string, std::string>& docdata =
const map<string, string>& docdata =
m_handlers.back()->get_meta_data();
string charset, mimetype;
getKeyValue(docdata, keycs, charset);
+1
View File
@@ -50,6 +50,7 @@ class MimeHandlerExec : public RecollFilter {
{}
virtual ~MimeHandlerExec() {}
virtual bool set_document_file(const string &file_path) {
RecollFilter::set_document_file(file_path);
m_fn = file_path;
m_havedoc = true;
return true;
+1
View File
@@ -41,6 +41,7 @@ using namespace std;
bool MimeHandlerHtml::set_document_file(const string &fn)
{
LOGDEB0(("textHtmlToDoc: %s\n", fn.c_str()));
RecollFilter::set_document_file(fn);
string otext;
if (!file_to_string(fn, otext)) {
LOGINFO(("textHtmlToDoc: cant read: %s\n", fn.c_str()));
+1
View File
@@ -78,6 +78,7 @@ void MimeHandlerMail::clear()
bool MimeHandlerMail::set_document_file(const string &fn)
{
LOGDEB(("MimeHandlerMail::set_document_file(%s)\n", fn.c_str()));
RecollFilter::set_document_file(fn);
if (m_fd >= 0) {
close(m_fd);
m_fd = -1;
+1
View File
@@ -57,6 +57,7 @@ void MimeHandlerMbox::clear()
bool MimeHandlerMbox::set_document_file(const string &fn)
{
LOGDEB(("MimeHandlerMbox::set_document_file(%s)\n", fn.c_str()));
RecollFilter::set_document_file(fn);
m_fn = fn;
if (m_vfp) {
fclose((FILE *)m_vfp);
+1
View File
@@ -34,6 +34,7 @@ using namespace std;
// Process a plain text file
bool MimeHandlerText::set_document_file(const string &fn)
{
RecollFilter::set_document_file(fn);
string otext;
string reason;
if (!file_to_string(fn, otext, &reason)) {
+2 -1
View File
@@ -30,7 +30,8 @@ class MimeHandlerUnknown : public RecollFilter {
public:
MimeHandlerUnknown(const string& mt) : RecollFilter(mt) {}
virtual ~MimeHandlerUnknown() {}
virtual bool set_document_string(const string&) {
virtual bool set_document_string(const string& fn) {
RecollFilter::set_document_file(fn);
return m_havedoc = true;
}
virtual bool set_document_file(const string&) {
+40 -1
View File
@@ -17,16 +17,21 @@ static char rcsid[] = "@(#$Id: mimehandler.cpp,v 1.25 2008-10-09 09:19:37 dockes
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "autoconfig.h"
#include <errno.h>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
#include "mimehandler.h"
#include "debuglog.h"
#include "rclconfig.h"
#include "smallut.h"
#ifdef RCL_USE_XATTR
#include "pxattr.h"
#endif // RCL_USE_XATTR
#include "mh_exec.h"
#include "mh_html.h"
@@ -35,6 +40,40 @@ using namespace std;
#include "mh_text.h"
#include "mh_unknown.h"
// Common code for all docs that are a file (not subdocs). If extended
// attributes support is enabled, fetch the data.
bool RecollFilter::set_document_file(const string& path)
{
#ifdef RCL_USE_XATTR
RclConfig* rclconfig = RclConfig::getMainConfig();
if (rclconfig == 0) {
LOGERR(("RecollFilter::set_document_file: no config\n"));
return false;
}
vector<string> xnames;
if (!pxattr::list(path, &xnames)) {
LOGERR(("xattrToMeta: pxattr::list failed, errno %d\n", errno));
return false;
}
const map<string, string>& xtof = rclconfig->getXattrToField();
for (vector<string>::const_iterator it = xnames.begin();
it != xnames.end(); it++) {
map<string, string>::const_iterator mit;
if ((mit = xtof.find(*it)) != xtof.end()) {
string value;
if (!pxattr::get(path, *it, &value, pxattr::PXATTR_NOFOLLOW)) {
LOGERR(("xattrToMeta: pxattr::get failed for %s, errno %d\n",
(*it).c_str(), errno));
continue;
}
// Encode should we ?
m_fieldsFromAttrs[mit->second] = value;
}
}
#endif // RCL_USE_XATTR
return true;
}
// Pool of already known and created handlers. There can be several instance
// for a given mime type (think email attachment in email message)
static multimap<string, Dijon::Filter*> o_handlers;
+23 -2
View File
@@ -17,11 +17,16 @@
#ifndef _MIMEHANDLER_H_INCLUDED_
#define _MIMEHANDLER_H_INCLUDED_
/* @(#$Id: mimehandler.h,v 1.16 2008-10-04 14:26:59 dockes Exp $ (C) 2004 J.F.Dockes */
#include "autoconfig.h"
#include <string>
#include <list>
using std::string;
using std::list;
#ifdef RCL_USE_XATTR
#include <map>
using std::map;
#endif // RCL_USE_XATTR
#include <Filter.h>
@@ -51,6 +56,10 @@ public:
// We don't use this for now
virtual bool set_document_uri(const std::string &) {return false;}
/// This does the extended attributes thing if enabled and should
/// be called from subclasses.
virtual bool set_document_file(const string &file_path);
// Default implementations
virtual bool set_document_string(const std::string &) {return false;}
virtual bool set_document_data(const char *cp, unsigned int sz) {
@@ -77,15 +86,26 @@ public:
}
virtual void clear() {
m_forPreview = m_havedoc = false;
Dijon::Filter::clear();
m_forPreview = m_havedoc = false;
m_defcharset.clear();
m_reason.clear();
#ifdef RCL_USE_XATTR
m_fieldsFromAttrs.clear();
#endif // RCL_USE_XATTR
}
#ifdef RCL_USE_XATTR
const map<string, string>& getFieldsFromAttrs() {return m_fieldsFromAttrs;}
#endif // RCL_USE_XATTR
protected:
bool m_forPreview;
string m_defcharset;
string m_reason;
bool m_havedoc;
#ifdef RCL_USE_XATTR
map<string, string> m_fieldsFromAttrs;
#endif // RCL_USE_XATTR
};
/**
@@ -97,11 +117,12 @@ protected:
* indexedmimetypes (if this is set at all).
*/
extern Dijon::Filter *getMimeHandler(const std::string &mtyp, RclConfig *cfg,
bool filtertypes=false);
/// Free up filter for reuse (you can also delete it)
extern void returnMimeHandler(Dijon::Filter *);
/// Can this mime type be interned ?
extern bool canIntern(const std::string mimetype, RclConfig *cfg);
#endif /* _MIMEHANDLER_H_INCLUDED_ */