• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdeutils API Reference
  • KDE Home
  • Contact Us
 

filelight

  • sources
  • kde-4.12
  • kdeutils
  • filelight
  • src
  • part
localLister.cpp
Go to the documentation of this file.
1 /***********************************************************************
2 * Copyright 2003-2004 Max Howell <max.howell@methylblue.com>
3 * Copyright 2008-2009 Martin Sandsmark <martin.sandsmark@kde.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License or (at your option) version 3 or any later version
9 * accepted by the membership of KDE e.V. (or its successor approved
10 * by the membership of KDE e.V.), which shall act as a proxy
11 * defined in Section 14 of version 3 of the license.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ***********************************************************************/
21 
22 #include "localLister.h"
23 
24 #include "Config.h"
25 #include "fileTree.h"
26 #include "scan.h"
27 
28 #include <KDebug>
29 #include <Solid/StorageVolume>
30 #include <Solid/StorageAccess>
31 #include <Solid/Device>
32 
33 #include <QtGui/QApplication> //postEvent()
34 #include <QtCore/QFile>
35 #include <QtCore/QByteArray>
36 
37 #include <kde_file.h>
38 #include <dirent.h>
39 #ifdef Q_OS_SOLARIS
40 #include <sys/vfstab.h>
41 #elif !defined(Q_WS_WIN)
42 #include <fstab.h>
43 #endif
44 #include <sys/stat.h>
45 #include <sys/types.h>
46 #include <unistd.h>
47 
48 #ifdef HAVE_MNTENT_H
49 #include <mntent.h>
50 #endif
51 
52 namespace Filelight
53 {
54 QStringList LocalLister::s_remoteMounts;
55 QStringList LocalLister::s_localMounts;
56 
57 LocalLister::LocalLister(const QString &path, Chain<Folder> *cachedTrees, ScanManager *parent)
58  : QThread()
59  , m_path(path)
60  , m_trees(cachedTrees)
61  , m_parent(parent)
62 {
63  //add empty directories for any mount points that are in the path
64  //TODO empty directories is not ideal as adds to fileCount incorrectly
65 
66  QStringList list(Config::skipList);
67  if (!Config::scanAcrossMounts) list += s_localMounts;
68  if (!Config::scanRemoteMounts) list += s_remoteMounts;
69 
70  foreach(const QString &ignorePath, list) {
71  if (ignorePath.startsWith(path)) {
72  m_trees->append(new Folder(ignorePath.toLocal8Bit()));
73  }
74  }
75 }
76 
77 void
78 LocalLister::run()
79 {
80  //recursively scan the requested path
81  const QByteArray path = QFile::encodeName(m_path);
82  Folder *tree = scan(path, path);
83 
84  //delete the list of trees useful for this scan,
85  //in a sucessful scan the contents would now be transferred to 'tree'
86  delete m_trees;
87 
88  if (m_parent->m_abort) //scan was cancelled
89  {
90  kDebug() << "Scan successfully aborted";
91  delete tree;
92  tree = 0;
93  }
94  kDebug() << "Emitting signal to cache results ...";
95  emit branchCompleted(tree, true);
96  kDebug() << "Thread terminating ...";
97 }
98 
99 #ifndef S_BLKSIZE
100 #define S_BLKSIZE 512
101 #endif
102 
103 
104 #include <errno.h>
105 static void
106 outputError(QByteArray path)
107 {
109 
110 #define out(s) kError() << s ": " << path; break
111 
112  switch (errno) {
113  case EACCES:
114  out("Inadequate access permissions");
115  case EMFILE:
116  out("Too many file descriptors in use by Filelight");
117  case ENFILE:
118  out("Too many files are currently open in the system");
119  case ENOENT:
120  out("A component of the path does not exist, or the path is an empty string");
121  case ENOMEM:
122  out("Insufficient memory to complete the operation");
123  case ENOTDIR:
124  out("A component of the path is not a folder");
125  case EBADF:
126  out("Bad file descriptor");
127  case EFAULT:
128  out("Bad address");
129 #ifndef Q_WS_WIN
130  case ELOOP: //NOTE shouldn't ever happen
131  out("Too many symbolic links encountered while traversing the path");
132 #endif
133  case ENAMETOOLONG:
134  out("File name too long");
135  }
136 
137 #undef out
138 }
139 
140 Folder*
141 LocalLister::scan(const QByteArray &path, const QByteArray &dirname)
142 {
143  Folder *cwd = new Folder(dirname);
144  DIR *dir = opendir(path);
145 
146  if (!dir) {
147  outputError(path);
148  return cwd;
149  }
150 
151 #ifdef _MSC_VER
152 //use a wider struct on win for nice handling of files larger than 2 GB
153 #undef KDE_struct_stat
154 #undef KDE_lstat
155 #define KDE_struct_stat struct _stat64
156 #define KDE_lstat kdewin32_stat64
157 #endif
158 
159  KDE_struct_stat statbuf;
160  dirent *ent;
161  while ((ent = KDE_readdir(dir)))
162  {
163  if (m_parent->m_abort)
164  return cwd;
165 
166  if (qstrcmp(ent->d_name, ".") == 0 || qstrcmp(ent->d_name, "..") == 0)
167  continue;
168 
169  QByteArray new_path = path;
170  new_path += ent->d_name;
171 
172  //get file information
173  if (KDE_lstat(new_path, &statbuf) == -1) {
174  outputError(new_path);
175  continue;
176  }
177 
178  if (S_ISLNK(statbuf.st_mode) ||
179  S_ISCHR(statbuf.st_mode) ||
180  S_ISBLK(statbuf.st_mode) ||
181  S_ISFIFO(statbuf.st_mode)||
182  S_ISSOCK(statbuf.st_mode))
183  {
184  continue;
185  }
186 
187  if (S_ISREG(statbuf.st_mode)) //file
188 #ifndef Q_WS_WIN
189  cwd->append(ent->d_name, (statbuf.st_blocks * S_BLKSIZE));
190 #else
191  cwd->append(ent->d_name, statbuf.st_size);
192 #endif
193 
194  else if (S_ISDIR(statbuf.st_mode)) //folder
195  {
196  Folder *d = 0;
197  QByteArray new_dirname = ent->d_name;
198  new_dirname += '/';
199  new_path += '/';
200 
201  //check to see if we've scanned this section already
202 
203  for (Iterator<Folder> it = m_trees->iterator(); it != m_trees->end(); ++it)
204  {
205  if (new_path == (*it)->name8Bit())
206  {
207  kDebug() << "Tree pre-completed: " << (*it)->name();
208  d = it.remove();
209  m_parent->m_files += d->children();
210  //**** ideally don't have this redundant extra somehow
211  cwd->append(d, new_dirname);
212  }
213  }
214 
215  if (!d) //then scan
216  if ((d = scan(new_path, new_dirname))) //then scan was successful
217  cwd->append(d);
218  }
219 
220  ++m_parent->m_files;
221  }
222 
223  closedir(dir);
224 
225  return cwd;
226 }
227 
228 void LocalLister::readMounts()
229 {
230  const Solid::StorageAccess *partition;
231  const Solid::StorageVolume *volume;
232  QStringList remoteFsTypes;
233  remoteFsTypes << QLatin1String( "smbfs" ) << QLatin1String( "nfs" ) << QLatin1String( "afs" ); //TODO: expand
234 
235  foreach (const Solid::Device &device, Solid::Device::listFromType(Solid::DeviceInterface::StorageAccess))
236  { // Iterate over all the partitions available.
237  if (!device.is<Solid::StorageAccess>()) continue; // It happens.
238  if (!device.is<Solid::StorageVolume>()) continue;
239 
240  partition = device.as<Solid::StorageAccess>();
241  if (!partition->isAccessible() || partition->filePath() == QLatin1String( "/" ) || partition->filePath().isEmpty()) continue;
242 
243  volume = device.as<Solid::StorageVolume>();
244  if (remoteFsTypes.contains(volume->fsType())) {
245  if (!s_remoteMounts.contains(partition->filePath())) {
246  s_remoteMounts.append(partition->filePath());
247  }
248  } else if (!s_localMounts.contains(partition->filePath())) {
249  s_localMounts.append(partition->filePath());
250  }
251  }
252 
253  kDebug() << "Found the following remote filesystems: " << s_remoteMounts;
254  kDebug() << "Found the following local filesystems: " << s_localMounts;
255 }
256 
257 }//namespace Filelight
258 
259 #include "localLister.moc"
260 
Filelight::LocalLister::readMounts
static void readMounts()
Definition: localLister.cpp:228
Filelight::Config::scanRemoteMounts
static bool scanRemoteMounts
Definition: Config.h:44
Config.h
Folder
Definition: fileTree.h:271
Folder::remove
void remove(const File *f)
removes a file
Definition: fileTree.h:303
fileTree.h
Chain::end
const Link< T > * end() const
Definition: fileTree.h:209
Folder::append
void append(Folder *d, const char *name=0)
appends a Folder
Definition: fileTree.h:284
Filelight::parent
http QObject * parent
Definition: part.cpp:74
Folder::children
uint children() const
Definition: fileTree.h:276
localLister.h
Iterator
Definition: fileTree.h:38
scan.h
Chain< Folder >
Filelight::LocalLister::branchCompleted
void branchCompleted(Folder *tree, bool finished)
File::name
QString name() const
Definition: fileTree.h:245
Filelight::ScanManager
Definition: scan.h:35
Filelight::LocalLister::LocalLister
LocalLister(const QString &path, Chain< Folder > *cachedTrees, ScanManager *parent)
Definition: localLister.cpp:57
out
#define out(s)
QThread
Filelight::Config::skipList
static QStringList skipList
Definition: Config.h:54
S_BLKSIZE
#define S_BLKSIZE
Definition: localLister.cpp:100
Filelight::Config::scanAcrossMounts
static bool scanAcrossMounts
Definition: Config.h:43
Filelight::outputError
static void outputError(QByteArray path)
Definition: localLister.cpp:106
Chain::append
void append(T *const data)
Definition: fileTree.h:170
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:08:07 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

filelight

Skip menu "filelight"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdeutils API Reference

Skip menu "kdeutils API Reference"
  • ark
  • filelight
  • kcalc
  • kcharselect
  • kdf
  • kfloppy
  • kgpg
  • kremotecontrol
  • ktimer
  • kwallet
  • superkaramba
  • sweeper

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal