diff --git a/src/desktop/unity-lens-recoll/recollscope/rclsearch.py b/src/desktop/unity-lens-recoll/recollscope/rclsearch.py index 50caec4a..ae4766d2 100755 --- a/src/desktop/unity-lens-recoll/recollscope/rclsearch.py +++ b/src/desktop/unity-lens-recoll/recollscope/rclsearch.py @@ -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'} diff --git a/src/index/fsfetcher.cpp b/src/index/fsfetcher.cpp index cc809d86..f1dc6f13 100644 --- a/src/index/fsfetcher.cpp +++ b/src/index/fsfetcher.cpp @@ -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; diff --git a/src/index/fsindexer.h b/src/index/fsindexer.h index 37dd0798..ad561562 100644 --- a/src/index/fsindexer.h +++ b/src/index/fsindexer.h @@ -17,8 +17,6 @@ #ifndef _fsindexer_h_included_ #define _fsindexer_h_included_ -#include - #include #include "indexer.h" diff --git a/src/index/mimetype.cpp b/src/index/mimetype.cpp index 508a4385..be4c8999 100644 --- a/src/index/mimetype.cpp +++ b/src/index/mimetype.cpp @@ -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; } diff --git a/src/internfile/mh_symlink.h b/src/internfile/mh_symlink.h new file mode 100644 index 00000000..8ce2dbea --- /dev/null +++ b/src/internfile/mh_symlink.h @@ -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 +#include +#include + +#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_ */ diff --git a/src/internfile/mimehandler.cpp b/src/internfile/mimehandler.cpp index 61a9d514..5f33e759 100644 --- a/src/internfile/mimehandler.cpp +++ b/src/internfile/mimehandler.cpp @@ -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 diff --git a/src/kde/kioslave/kio_recoll/dirif.cpp b/src/kde/kioslave/kio_recoll/dirif.cpp index 29afe7fb..447e7f7b 100644 --- a/src/kde/kioslave/kio_recoll/dirif.cpp +++ b/src/kde/kioslave/kio_recoll/dirif.cpp @@ -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 { diff --git a/src/qtgui/mtpics/emblem-symbolic-link.png b/src/qtgui/mtpics/emblem-symbolic-link.png new file mode 100644 index 00000000..9f35b79e Binary files /dev/null and b/src/qtgui/mtpics/emblem-symbolic-link.png differ diff --git a/src/qtgui/reslist.cpp b/src/qtgui/reslist.cpp index 21e12249..e639fa0f 100644 --- a/src/qtgui/reslist.cpp +++ b/src/qtgui/reslist.cpp @@ -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); } } diff --git a/src/qtgui/restable.cpp b/src/qtgui/restable.cpp index 9c68a408..baa1a2b0 100644 --- a/src/qtgui/restable.cpp +++ b/src/qtgui/restable.cpp @@ -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); } } diff --git a/src/sampleconf/mimeconf b/src/sampleconf/mimeconf index 598ae6d8..2e67f545 100644 --- a/src/sampleconf/mimeconf +++ b/src/sampleconf/mimeconf @@ -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 diff --git a/src/sampleconf/mimeview b/src/sampleconf/mimeview index 7969cd4d..23b3c90c 100644 --- a/src/sampleconf/mimeview +++ b/src/sampleconf/mimeview @@ -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 diff --git a/src/utils/fstreewalk.cpp b/src/utils/fstreewalk.cpp index 044c7f51..b9683e2c 100644 --- a/src/utils/fstreewalk.cpp +++ b/src/utils/fstreewalk.cpp @@ -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; diff --git a/src/utils/wipedir.cpp b/src/utils/wipedir.cpp index d5b2e882..847d705f 100644 --- a/src/utils/wipedir.cpp +++ b/src/utils/wipedir.cpp @@ -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;