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:
parent
5285711417
commit
72cfe268ad
14 changed files with 106 additions and 19 deletions
|
@ -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'}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
#ifndef _fsindexer_h_included_
|
||||
#define _fsindexer_h_included_
|
||||
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "indexer.h"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
70
src/internfile/mh_symlink.h
Normal file
70
src/internfile/mh_symlink.h
Normal 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_ */
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
BIN
src/qtgui/mtpics/emblem-symbolic-link.png
Normal file
BIN
src/qtgui/mtpics/emblem-symbolic-link.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue