krsearchmod.cpp 7.55 KB
Newer Older
Rafi Yanai's avatar
Rafi Yanai committed
1
/***************************************************************************
2 3 4 5
                                krsearchmod.cpp
                            -------------------
   copyright            : (C) 2001 by Shie Erlich & Rafi Yanai
   email                : krusader@users.sourceforge.net
Csaba Karai's avatar
 
Csaba Karai committed
6
   web site             : http://krusader.sourceforge.net
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
---------------------------------------------------------------------------
 Description
***************************************************************************

 A

    db   dD d8888b. db    db .d8888.  .d8b.  d8888b. d88888b d8888b.
    88 ,8P' 88  `8D 88    88 88'  YP d8' `8b 88  `8D 88'     88  `8D
    88,8P   88oobY' 88    88 `8bo.   88ooo88 88   88 88ooooo 88oobY'
    88`8b   88`8b   88    88   `Y8b. 88~~~88 88   88 88~~~~~ 88`8b
    88 `88. 88 `88. 88b  d88 db   8D 88   88 88  .8D 88.     88 `88.
    YP   YD 88   YD ~Y8888P' `8888Y' YP   YP Y8888D' Y88888P 88   YD

                                                    S o u r c e    F i l e

***************************************************************************
*                                                                         *
*   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.                                   *
*                                                                         *
***************************************************************************/
Rafi Yanai's avatar
Rafi Yanai committed
30 31 32

#include "krsearchmod.h"

Fathi Boudra's avatar
Fathi Boudra committed
33
#include <QtCore/QDir>
34 35
#include <QtCore/QMimeDatabase>
#include <QtCore/QMimeType>
Fathi Boudra's avatar
Fathi Boudra committed
36
#include <QtCore/QRegExp>
37
#include <QtWidgets/QApplication>
38
#include <qplatformdefs.h>
Rafi Yanai's avatar
Rafi Yanai committed
39

40 41
#include <KIO/Global>

Fathi Boudra's avatar
Fathi Boudra committed
42 43 44 45 46
#include "../VFS/krquery.h"
#include "../VFS/vfile.h"
#include "../VFS/krpermhandler.h"
#include "../VFS/krarchandler.h"

47 48
#define  EVENT_PROCESS_DELAY     250

49 50
extern KRarcHandler arcHandler;

Fathi Boudra's avatar
Fathi Boudra committed
51
KRSearchMod::KRSearchMod(const KRQuery* q)
Csaba Karai's avatar
 
Csaba Karai committed
52
{
Fathi Boudra's avatar
Fathi Boudra committed
53 54 55 56 57 58 59 60 61
    stopSearch = false; /// ===> added
    query = new KRQuery(*q);
    connect(query, SIGNAL(status(const QString &)),
            this,  SIGNAL(searching(const QString&)));
    connect(query, SIGNAL(processEvents(bool &)),
            this,  SLOT(slotProcessEvents(bool &)));

    remote_vfs = 0;
    virtual_vfs = 0;
Csaba Karai's avatar
 
Csaba Karai committed
62
}
Rafi Yanai's avatar
Rafi Yanai committed
63

64
KRSearchMod::~KRSearchMod()
Csaba Karai's avatar
 
Csaba Karai committed
65
{
Fathi Boudra's avatar
Fathi Boudra committed
66 67 68 69 70
    delete query;
    if (remote_vfs)
        delete remote_vfs;
    if (virtual_vfs)
        delete virtual_vfs;
Csaba Karai's avatar
 
Csaba Karai committed
71
}
Rafi Yanai's avatar
Rafi Yanai committed
72

73
void KRSearchMod::start()
Csaba Karai's avatar
 
Csaba Karai committed
74
{
Fathi Boudra's avatar
Fathi Boudra committed
75 76 77
    unScannedUrls.clear();
    scannedUrls.clear();
    timer.start();
Csaba Karai's avatar
 
Csaba Karai committed
78

79
    QList<QUrl> whereToSearch = query->searchInDirs();
Csaba Karai's avatar
 
Csaba Karai committed
80

Fathi Boudra's avatar
Fathi Boudra committed
81 82 83 84 85
    // search every dir that needs to be searched
    for (int i = 0; i < whereToSearch.count(); ++i)
        scanURL(whereToSearch [ i ]);

    emit finished();
Csaba Karai's avatar
 
Csaba Karai committed
86
}
Rafi Yanai's avatar
Rafi Yanai committed
87

88
void KRSearchMod::stop()
Csaba Karai's avatar
 
Csaba Karai committed
89
{
Fathi Boudra's avatar
Fathi Boudra committed
90
    stopSearch = true;
Csaba Karai's avatar
 
Csaba Karai committed
91
}
92

93
void KRSearchMod::scanURL(QUrl url)
Csaba Karai's avatar
 
Csaba Karai committed
94
{
Fathi Boudra's avatar
Fathi Boudra committed
95
    if (stopSearch) return;
Csaba Karai's avatar
 
Csaba Karai committed
96

Fathi Boudra's avatar
Fathi Boudra committed
97 98
    unScannedUrls.push(url);
    while (!unScannedUrls.isEmpty()) {
99
        QUrl urlToCheck = unScannedUrls.pop();
Csaba Karai's avatar
 
Csaba Karai committed
100

Fathi Boudra's avatar
Fathi Boudra committed
101
        if (stopSearch) return;
Csaba Karai's avatar
 
Csaba Karai committed
102

Fathi Boudra's avatar
Fathi Boudra committed
103 104 105 106
        if (query->isExcluded(urlToCheck)) {
            if (!query->searchInDirs().contains(urlToCheck))
                continue;
        }
Csaba Karai's avatar
 
Csaba Karai committed
107

Fathi Boudra's avatar
Fathi Boudra committed
108 109 110
        if (scannedUrls.contains(urlToCheck))
            continue;
        scannedUrls.push(urlToCheck);
Csaba Karai's avatar
 
Csaba Karai committed
111

112
        emit searching(urlToCheck.toDisplayString(QUrl::PreferLocalFile));
Csaba Karai's avatar
 
Csaba Karai committed
113

Fathi Boudra's avatar
Fathi Boudra committed
114 115 116 117 118
        if (urlToCheck.isLocalFile())
            scanLocalDir(urlToCheck);
        else
            scanRemoteDir(urlToCheck);
    }
Csaba Karai's avatar
 
Csaba Karai committed
119
}
Csaba Karai's avatar
 
Csaba Karai committed
120

121
void KRSearchMod::scanLocalDir(QUrl urlToScan)
Csaba Karai's avatar
 
Csaba Karai committed
122
{
123
    QString dir = vfs::ensureTrailingSlash(urlToScan).path();
124

125
    QT_DIR* d = QT_OPENDIR(dir.toLocal8Bit());
Fathi Boudra's avatar
Fathi Boudra committed
126
    if (!d) return ;
127

128
    QT_DIRENT* dirEnt;
129

130
    while ((dirEnt = QT_READDIR(d)) != NULL) {
Fathi Boudra's avatar
Fathi Boudra committed
131
        QString name = QString::fromLocal8Bit(dirEnt->d_name);
Csaba Karai's avatar
 
Csaba Karai committed
132

Fathi Boudra's avatar
Fathi Boudra committed
133 134
        // we don't scan the ".",".." enteries
        if (name == "." || name == "..") continue;
135

136 137
        QT_STATBUF stat_p;
        QT_LSTAT((dir + name).toLocal8Bit(), &stat_p);
Csaba Karai's avatar
 
Csaba Karai committed
138

139
        QUrl url = QUrl::fromLocalFile(dir + name);
Csaba Karai's avatar
 
Csaba Karai committed
140

Fathi Boudra's avatar
Fathi Boudra committed
141
        QString mime;
Fathi Boudra's avatar
Fathi Boudra committed
142
        if (query->searchInArchives() || !query->hasMimeType()) {
143 144 145 146
            QMimeDatabase db;
            QMimeType mt = db.mimeTypeForUrl(url);
            if (mt.isValid())
                mime = mt.name();
Fathi Boudra's avatar
Fathi Boudra committed
147
        }
Csaba Karai's avatar
 
Csaba Karai committed
148

Fathi Boudra's avatar
Fathi Boudra committed
149 150
        // creating a vfile object for matching with krquery
        vfile * vf = new vfile(name, (KIO::filesize_t)stat_p.st_size, KRpermHandler::mode2QString(stat_p.st_mode),
151
                               stat_p.st_mtime, S_ISLNK(stat_p.st_mode), false/*FIXME*/, stat_p.st_uid, stat_p.st_gid,
Fathi Boudra's avatar
Fathi Boudra committed
152 153 154 155 156
                               mime, "", stat_p.st_mode);
        vf->vfile_setUrl(url);

        if (query->isRecursive()) {
            if (S_ISLNK(stat_p.st_mode) && query->followLinks())
157
                unScannedUrls.push(QUrl::fromLocalFile(QDir(dir + name).canonicalPath()));
Fathi Boudra's avatar
Fathi Boudra committed
158 159 160 161
            else if (S_ISDIR(stat_p.st_mode))
                unScannedUrls.push(url);
        }
        if (query->searchInArchives()) {
162
            if (KRarcHandler::arcSupported(mime)) {
163
                QUrl archiveURL = url;
Fathi Boudra's avatar
Fathi Boudra committed
164
                bool encrypted;
165
                QString realType = arcHandler.getType(encrypted, url.path(), mime);
Fathi Boudra's avatar
Fathi Boudra committed
166 167 168

                if (!encrypted) {
                    if (realType == "-tbz" || realType == "-tgz" || realType == "tarz" || realType == "-tar" || realType == "-tlz")
169
                        archiveURL.setScheme("tar");
Fathi Boudra's avatar
Fathi Boudra committed
170
                    else
171
                        archiveURL.setScheme("krarc");
Fathi Boudra's avatar
Fathi Boudra committed
172 173 174 175

                    unScannedUrls.push(archiveURL);
                }
            }
176
        }
Csaba Karai's avatar
 
Csaba Karai committed
177

Fathi Boudra's avatar
Fathi Boudra committed
178 179 180
        if (query->match(vf)) {
            // if we got here - we got a winner
            results.append(dir + name);
181 182
            emit found(name, dir, (KIO::filesize_t) stat_p.st_size, stat_p.st_mtime,
                       KRpermHandler::mode2QString(stat_p.st_mode), stat_p.st_uid, stat_p.st_gid, query->foundText());
Fathi Boudra's avatar
Fathi Boudra committed
183 184
        }
        delete vf;
185

Fathi Boudra's avatar
Fathi Boudra committed
186 187 188 189 190
        if (timer.elapsed() >= EVENT_PROCESS_DELAY) {
            qApp->processEvents();
            timer.start();
            if (stopSearch) return;
        }
191
    }
Fathi Boudra's avatar
Fathi Boudra committed
192
    // clean up
193
    QT_CLOSEDIR(d);
Csaba Karai's avatar
 
Csaba Karai committed
194
}
195

196
void KRSearchMod::scanRemoteDir(QUrl url)
Csaba Karai's avatar
 
Csaba Karai committed
197
{
Fathi Boudra's avatar
Fathi Boudra committed
198 199 200
    vfs * vfs_;


201
    if (url.scheme() == QStringLiteral("virt")) {
Fathi Boudra's avatar
Fathi Boudra committed
202 203 204 205 206 207 208
        if (virtual_vfs == 0)
            virtual_vfs = new virt_vfs(0);
        vfs_ = virtual_vfs;
    } else {
        if (remote_vfs == 0)
            remote_vfs = new ftp_vfs(0);
        vfs_ = remote_vfs;
209 210
    }

Fathi Boudra's avatar
Fathi Boudra committed
211 212 213 214
    if (!vfs_->vfs_refresh(url)) return ;

    for (vfile * vf = vfs_->vfs_getFirstFile(); vf != 0 ; vf = vfs_->vfs_getNextFile()) {
        QString name = vf->vfile_getName();
215
        QUrl fileURL = vfs_->vfs_getFile(name);
Fathi Boudra's avatar
Fathi Boudra committed
216 217 218 219 220 221

        if (query->isRecursive() && ((vf->vfile_isSymLink() && query->followLinks()) || vf->vfile_isDir()))
            unScannedUrls.push(fileURL);

        if (query->match(vf)) {
            // if we got here - we got a winner
222
            results.append(fileURL.toDisplayString(QUrl::PreferLocalFile));
Fathi Boudra's avatar
Fathi Boudra committed
223

224 225 226
            emit found(fileURL.fileName(), KIO::upUrl(fileURL).toDisplayString(QUrl::PreferLocalFile | QUrl::StripTrailingSlash),
                       vf->vfile_getSize(), vf->vfile_getTime_t(), vf->vfile_getPerm(), vf->vfile_getUid(),
                       vf->vfile_getGid(), query->foundText());
Fathi Boudra's avatar
Fathi Boudra committed
227 228 229 230 231 232 233
        }

        if (timer.elapsed() >= EVENT_PROCESS_DELAY) {
            qApp->processEvents();
            timer.start();
            if (stopSearch) return;
        }
Csaba Karai's avatar
 
Csaba Karai committed
234 235
    }
}
Rafi Yanai's avatar
Rafi Yanai committed
236

Fathi Boudra's avatar
Fathi Boudra committed
237 238 239 240
void KRSearchMod::slotProcessEvents(bool & stopped)
{
    qApp->processEvents();
    stopped = stopSearch;
241 242
}