1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
|
/* This file is part of Strigi Desktop Search
*
* Copyright (C) 2006 Jos van den Oever <jos@vandenoever.info>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* 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; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#define STRIGI_IMPORT_API //todo: could also define this in cmake...
#include <strigi/strigiconfig.h>
#include <strigi/streamthroughanalyzer.h>
#include <strigi/analyzerplugin.h>
#include <strigi/analysisresult.h>
#include <sys/types.h>
#include <attr/xattr.h>
#include <errno.h>
using namespace Strigi;
using namespace std;
class XattrAnalyzer : public Strigi::StreamThroughAnalyzer {
private:
static const int maxnamesize = 262144;
int namesize;
char* namebuffer;
static const int maxvalsize = 262144;
int valsize;
char* valbuffer;
Strigi::AnalysisResult* idx;
const char* retrieveAttribute(const char*);
public:
XattrAnalyzer() {
namebuffer = (char*)malloc(1024);
namesize = 1024;
valbuffer = (char*)malloc(1024);
valsize = 1024;
}
~XattrAnalyzer() {
free(namebuffer);
free(valbuffer);
}
void setIndexable(Strigi::AnalysisResult*i) {
idx = i;
}
Strigi::InputStream *connectInputStream(Strigi::InputStream *in);
bool isReadyWithStream() { return true; }
};
Strigi::InputStream *
XattrAnalyzer::connectInputStream(Strigi::InputStream *in) {
if (idx->depth() != 0) return in;
ssize_t s;
errno = 0;
do {
if (errno == ERANGE && namesize < maxnamesize) {
namesize *= 2;
namebuffer = (char*)realloc(namebuffer, namesize);
}
s = llistxattr(idx->path().c_str(), namebuffer, namesize);
} while (s == -1 && errno == ERANGE && namesize < maxnamesize);
if (s == -1) return in;
const char*start = namebuffer;
const char*end = namebuffer;
while (start-namebuffer < s) {
if (*end == '\0') {
if (end != start) {
const char* val = retrieveAttribute(start);
if (val) {
idx->addValue(start, val);
}
start = end+1;
}
}
end++;
}
return in;
}
const char*
XattrAnalyzer::retrieveAttribute(const char* name) {
ssize_t s;
errno = 0;
do {
if (errno == ERANGE && valsize < maxvalsize) {
valsize *= 2;
valbuffer = (char*)realloc(valbuffer, valsize);
}
s = lgetxattr(idx->path().c_str(), name, valbuffer, valsize-1);
} while (s == -1 && errno == ERANGE && valsize < maxvalsize);
if (s == -1) return 0;
valbuffer[s] = '\0';
return valbuffer;
}
//define all the available analyzers in this plugin
class XattrThroughAnalyzerFactory : public StreamThroughAnalyzerFactory {
private:
const char* name() const {
return "XattrThroughAnalyzer";
}
StreamThroughAnalyzer* newInstance() const {
return new XattrAnalyzer();
}
};
class Factory : public AnalyzerFactoryFactory {
public:
list<StreamThroughAnalyzerFactory*>
streamThroughAnalyzerFactories() const {
list<StreamThroughAnalyzerFactory*> af;
af.push_back(new XattrThroughAnalyzerFactory());
return af;
}
};
STRIGI_ANALYZER_FACTORY(Factory);
|