Add support for indexing symlinks as such. Use inode/directory instead of application/x-fsdirectory as directory mime type. Fix stat/lstat usage in places (wipedir)

This commit is contained in:
Jean-Francois Dockes 2013-04-17 18:34:02 +02:00
parent 5285711417
commit 72cfe268ad
14 changed files with 106 additions and 19 deletions

View file

@ -65,6 +65,7 @@ def _get_thumbnail_path(url):
# Icon names for some recoll mime types which don't have standard icon by the
# normal method
SPEC_MIME_ICONS = {'application/x-fsdirectory' : 'gnome-fs-directory.svg',
'inode/directory' : 'gnome-fs-directory.svg',
'message/rfc822' : 'mail-read',
'application/x-recoll' : 'recoll'}

View file

@ -31,7 +31,8 @@
using std::string;
static bool urltopath(const Rcl::Doc& idoc, string& fn, struct stat& st)
static bool urltopath(RclConfig* cnf,
const Rcl::Doc& idoc, string& fn, struct stat& st)
{
// The url has to be like file://
if (idoc.url.find(cstr_fileu) != 0) {
@ -40,7 +41,11 @@ static bool urltopath(const Rcl::Doc& idoc, string& fn, struct stat& st)
return false;
}
fn = idoc.url.substr(7, string::npos);
if (stat(fn.c_str(), &st) < 0) {
cnf->setKeyDir(path_getfather(fn));
bool follow = false;
cnf->getConfParam("followLinks", &follow);
if ((follow ? stat(fn.c_str(), &st) : lstat(fn.c_str(), &st))< 0) {
LOGERR(("FSDocFetcher::fetch: stat errno %d for [%s]\n",
errno, fn.c_str()));
return false;
@ -51,7 +56,7 @@ static bool urltopath(const Rcl::Doc& idoc, string& fn, struct stat& st)
bool FSDocFetcher::fetch(RclConfig* cnf, const Rcl::Doc& idoc, RawDoc& out)
{
string fn;
if (!urltopath(idoc, fn, out.st))
if (!urltopath(cnf, idoc, fn, out.st))
return false;
out.kind = RawDoc::RDK_FILENAME;
out.data = fn;
@ -62,7 +67,7 @@ bool FSDocFetcher::makesig(RclConfig* cnf, const Rcl::Doc& idoc, string& sig)
{
string fn;
struct stat st;
if (!urltopath(idoc, fn, st))
if (!urltopath(cnf, idoc, fn, st))
return false;
FsIndexer::makesig(&st, sig);
return true;

View file

@ -17,8 +17,6 @@
#ifndef _fsindexer_h_included_
#define _fsindexer_h_included_
#include <sys/stat.h>
#include <list>
#include "indexer.h"

View file

@ -122,9 +122,11 @@ string mimetype(const string &fn, const struct stat *stp,
// 'mime:' filter with the query language, but it's not work
// changing (would force a reindex).
if (S_ISDIR(stp->st_mode))
return "application/x-fsdirectory";
return "inode/directory";
if (S_ISLNK(stp->st_mode))
return "inode/symlink";
if (!S_ISREG(stp->st_mode))
return "application/x-fsspecial";
return "inode/x-fsspecial";
}
string mtype;
@ -191,7 +193,7 @@ int main(int argc, const char **argv)
while (--argc > 0) {
string filename = *++argv;
struct stat st;
if (stat(filename.c_str(), &st)) {
if (lstat(filename.c_str(), &st)) {
fprintf(stderr, "Can't stat %s\n", filename.c_str());
continue;
}

View file

@ -0,0 +1,70 @@
/* Copyright (C) 2004 J.F.Dockes
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the
* Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _MH_SYMLINK_H_INCLUDED_
#define _MH_SYMLINK_H_INCLUDED_
#include <string>
#include <unistd.h>
#include <errno.h>
#include "cstr.h"
#include "mimehandler.h"
#include "transcode.h"
#include "pathut.h"
#include "debuglog.h"
/** Index symlink target
*
* Not sure that this is such a good idea, so it's disabled by default in
* the config. Add inode/symlink = internal to the index section of mimeconf
* to enable.
*/
class MimeHandlerSymlink : public RecollFilter {
public:
MimeHandlerSymlink(RclConfig *cnf, const std::string& mt)
: RecollFilter(cnf, mt) {}
virtual ~MimeHandlerSymlink() {}
virtual bool set_document_file(const string& fn)
{
RecollFilter::set_document_file(fn);
m_fn = fn;
return m_havedoc = true;
}
virtual bool next_document()
{
if (m_havedoc == false)
return false;
m_havedoc = false;
m_metaData[cstr_dj_keycontent] = cstr_null;
char lc[1024];
ssize_t bytes = readlink(m_fn.c_str(), lc, 1024);
if (bytes != (ssize_t)-1) {
string slc(lc, bytes);
transcode(path_getsimple(slc), m_metaData[cstr_dj_keycontent],
m_config->getDefCharset(true), "UTF-8");
} else {
LOGDEB(("Symlink: readlink [%s] failed, errno %d\n", m_fn.c_str(),
errno));
}
m_metaData[cstr_dj_keymt] = cstr_textplain;
return true;
}
private:
std::string m_fn;
};
#endif /* _MH_SYMLINK_H_INCLUDED_ */

View file

@ -37,6 +37,7 @@ using namespace std;
#include "mh_mail.h"
#include "mh_mbox.h"
#include "mh_text.h"
#include "mh_symlink.h"
#include "mh_unknown.h"
#include "ptmutex.h"
@ -148,6 +149,9 @@ static Dijon::Filter *mhFactory(RclConfig *config, const string &mime)
} else if ("message/rfc822" == lmime) {
LOGDEB2(("mhFactory(%s): returning MimeHandlerMail\n", mime.c_str()));
return new MimeHandlerMail(config, lmime);
} else if ("inode/symlink" == lmime) {
LOGDEB2(("mhFactory(%s): ret MimeHandlerSymlink\n", mime.c_str()));
return new MimeHandlerSymlink(config, lmime);
} else if (lmime.find("text/") == 0) {
// Try to handle unknown text/xx as text/plain. This
// only happen if the text/xx was defined as "internal" in

View file

@ -102,7 +102,8 @@ static const UDSEntry resultToUDSEntry(const Rcl::Doc& doc, int num)
char cnum[30];sprintf(cnum, "%04d", num);
entry.insert(KIO::UDSEntry::UDS_NAME, resultBaseName + cnum);
if (!doc.mimetype.compare("application/x-fsdirectory")) {
if (!doc.mimetype.compare("application/x-fsdirectory") ||
!doc.mimetype.compare("inode/directory")) {
entry.insert(KIO::UDSEntry::UDS_MIME_TYPE, "inode/directory");
entry.insert( KIO::UDSEntry::UDS_FILE_TYPE, S_IFDIR);
} else {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -1019,7 +1019,7 @@ void ResList::menuPreviewParent()
// No parent doc: show enclosing folder with app configured for
// directories
pdoc.url = path_getfather(doc.url);
pdoc.mimetype = "application/x-fsdirectory";
pdoc.mimetype = "inode/directory";
emit editRequested(pdoc);
}
}
@ -1038,7 +1038,7 @@ void ResList::menuOpenParent()
pdoc.url = path_getfather(doc.url);
pdoc.meta[Rcl::Doc::keychildurl] = doc.url;
pdoc.meta[Rcl::Doc::keyapptg] = "parentopen";
pdoc.mimetype = "application/x-fsdirectory";
pdoc.mimetype = "inode/directory";
emit editRequested(pdoc);
}
}

View file

@ -793,7 +793,7 @@ void ResTable::menuPreviewParent()
pdoc.url = path_getfather(doc.url);
pdoc.meta[Rcl::Doc::keychildurl] = doc.url;
pdoc.meta[Rcl::Doc::keyapptg] = "parentopen";
pdoc.mimetype = "application/x-fsdirectory";
pdoc.mimetype = "inode/directory";
emit editRequested(pdoc);
}
}
@ -815,7 +815,7 @@ void ResTable::menuOpenParent()
pdoc.url = path_getfather(doc.url);
pdoc.meta[Rcl::Doc::keychildurl] = doc.url;
pdoc.meta[Rcl::Doc::keyapptg] = "parentopen";
pdoc.mimetype = "application/x-fsdirectory";
pdoc.mimetype = "inode/directory";
emit editRequested(pdoc);
}
}

View file

@ -114,6 +114,7 @@ image/tiff = execm rclimg
image/vnd.djvu = exec rcldjvu
image/svg+xml = exec rclsvg
image/x-xcf = execm rclimg
inode/symlink = internal
message/rfc822 = internal
text/calendar = execm rclics;mimetype=text/plain
text/html = internal
@ -212,6 +213,8 @@ image/tiff = image
image/vnd.djvu = document
image/x-xcf = image
image/x-xpmi = image
inode/directory = folder
inode/symlink = emblem-symbolic-link
message/rfc822 = message
text/html = html
text/html|chm = bookchap
@ -340,6 +343,8 @@ other = application/vnd.sun.xml.draw \
application/x-tar \
application/x-webarchive \
application/zip \
inode/directory \
inode/symlink \
[guifilters]
# This defines the top level filters in the GUI (accessed by the the

View file

@ -18,7 +18,7 @@
# parent document instead of a temporary html file.
xallexcepts = application/pdf application/postscript application/x-dvi \
text/html|gnuinfo text/html|chm text/html|epub \
application/x-fsdirectory|parentopen
application/x-fsdirectory|parentopen inode/directory|parentopen
[view]
# Pseudo entry used if the 'use desktop' preference is set in the GUI
@ -80,8 +80,9 @@ application/x-chm = kchmviewer %f
application/x-dia-diagram = dia %f
application/x-fsdirectory = dolphin %f
#application/x-fsdirectory|parentopen = nautilus %(childurl)
inode/directory = dolphin %f
application/x-fsdirectory|parentopen = dolphin --select %(childurl) %f
inode/directory|parentopen = dolphin --select %(childurl) %f
application/x-gnuinfo = xterm -e "info -f %f"
application/x-gnumeric = gnumeric %f

View file

@ -399,7 +399,7 @@ FsTreeWalker::Status FsTreeWalker::iwalk(const string &top,
if ((status = cb.processone(top, &st, FtwDirReturn))
& (FtwStop|FtwError))
goto out;
} else if (S_ISREG(st.st_mode)) {
} else if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) {
if ((status = cb.processone(fn, &st, FtwRegular)) &
(FtwStop|FtwError)) {
goto out;

View file

@ -41,7 +41,7 @@ int wipedir(const string& dir, bool selfalso, bool recurse)
int statret;
int ret = -1;
statret = stat(dir.c_str(), &st);
statret = lstat(dir.c_str(), &st);
if (statret == -1) {
LOGERR(("wipedir: cant stat %s, errno %d\n", dir.c_str(), errno));
return -1;
@ -70,7 +70,7 @@ int wipedir(const string& dir, bool selfalso, bool recurse)
string fn = path_cat(dir, ent->d_name);
struct stat st;
int statret = stat(fn.c_str(), &st);
int statret = lstat(fn.c_str(), &st);
if (statret == -1) {
LOGERR(("wipedir: cant stat %s, errno %d\n", fn.c_str(), errno));
goto out;