1 /*
2  *   File name: FileInfo.h
3  *   Summary:	Support classes for QDirStat
4  *   License:	GPL V2 - See file LICENSE for details.
5  *
6  *   Author:	Stefan Hundhammer <Stefan.Hundhammer@gmx.de>
7  */
8 
9 
10 #ifndef FileInfo_h
11 #define FileInfo_h
12 
13 
14 #include <sys/types.h>
15 #include <sys/stat.h>
16 #include <limits.h>
17 
18 #include <QTextStream>
19 #include <QList>
20 
21 #include "FileSize.h"
22 #include "Logger.h"
23 
24 // The size of a standard disk block.
25 //
26 // Notice that this is different from st_blksize in the struct that the stat()
27 // syscall returns, yet it is the reference unit for st_blocks in that same
28 // struct.
29 
30 #define STD_BLOCK_SIZE	512L
31 
32 
33 namespace QDirStat
34 {
35 #define FileInfoMagic 4242
36 
37     // Forward declarations
38     class DirInfo;
39     class DotEntry;
40     class Attic;
41     class PkgInfo;
42     class DirTree;
43 
44 
45     /**
46      * Status of a directory read job.
47      **/
48     enum DirReadState
49     {
50 	DirQueued,		// Waiting in the directory read queue
51 	DirReading,		// Reading in progress
52 	DirFinished,		// Reading finished and OK
53 	DirOnRequestOnly,	// Will be read upon explicit request only (mount points)
54 	DirCached,		// Content was read from a cache
55 	DirAborted,		// Reading aborted upon user request
56 	DirPermissionDenied,	// Insufficient permissions for reading
57 	DirError		// Error while reading
58     };
59 
60 
61     /**
62      * The most basic building block of a DirTree:
63      *
64      * Information about one single directory entry. This is the type of info
65      * typically obtained by stat() / lstat() or similar calls.
66      *
67      * This class is tuned for size rather than speed: A typical Linux system
68      * easily has 150,000+ filesystem objects, and at least one entry of this
69      * sort is required for each of them.
70      *
71      * This class provides stubs for children management, yet those stubs all
72      * are default implementations that don't really deal with children.
73      * Derived classes need to take care of that.
74      *
75      * @short Basic file information (like obtained by the lstat() sys call)
76      **/
77     class FileInfo
78     {
79     public:
80 	/**
81 	 * Default constructor.
82 	 **/
83 	FileInfo( DirTree    * tree,
84 		  DirInfo    * parent = 0,
85 		  const char * name   = 0 );
86 
87 	/**
88 	 * Constructor from a stat buffer (i.e. based on an lstat() call).
89 	 **/
90 	FileInfo( const QString & filenameWithoutPath,
91 		  struct stat	* statInfo,
92 		  DirTree	* tree,
93 		  DirInfo	* parent = 0 );
94 
95 	/**
96 	 * Constructor from the bare necessary fields
97 	 * for use from a cache file reader
98 	 *
99 	 * If 'blocks' is -1, it will be calculated from 'size'.
100 	 **/
101 	FileInfo( DirTree *	  tree,
102 		  DirInfo *	  parent,
103 		  const QString & filenameWithoutPath,
104 		  mode_t	  mode,
105 		  FileSize	  size,
106 		  time_t	  mtime,
107 		  FileSize	  blocks = -1,
108 		  nlink_t	  links	 = 1 );
109 
110 	/**
111 	 * Destructor.
112 	 *
113 	 * Don't forget to call FileInfo::unlinkChild() when deleting
114 	 * objects of this class!
115 	 **/
116 	virtual ~FileInfo();
117 
118 	/**
119 	 * Check with the magic number if this object is valid.
120 	 * Return 'true' if it is valid, 'false' if invalid.
121 	 *
122 	 * Notice that this is intentionally not a virtual function to avoid
123 	 * a segfault via the vptr if it is not valid.
124 	 **/
125 	bool checkMagicNumber() const;
126 
127 	/**
128 	 * Returns whether or not this is a local file (protocol "file:").
129 	 * It might as well be a remote file ("ftp:", "smb:" etc.).
130 	 **/
isLocalFile()131 	bool isLocalFile() const { return _isLocalFile; }
132 
133 	/**
134 	 * Returns the file or directory name without path, i.e. only the last
135 	 * path name component (i.e. "printcap" rather than "/etc/printcap").
136 	 *
137 	 * If a directory scan doesn't begin at the root directory and this is
138 	 * the top entry of this directory scan, it will also contain the base
139 	 * path, i.e. "/usr/share/man" rather than just "man" if a scan was
140 	 * requested for "/usr/share/man". Notice, however, that the entry for
141 	 * "/usr/share/man/man1" will only return "man1" in this example.
142 	 **/
name()143 	QString name() const { return _name; }
144 
145 	/**
146 	 * Returns the base name of this object, i.e. the last path component,
147 	 * even if this is a toplevel item.
148 	 **/
149 	QString baseName() const;
150 
151 	/**
152 	 * Returns the full URL of this object with full path.
153 	 *
154 	 * This is a (somewhat) expensive operation since it will recurse up
155 	 * to the top of the tree.
156 	 **/
157 	virtual QString url() const;
158 
159 	/**
160 	 * Returns the full path of this object. Unlike url(), this never has a
161 	 * protocol prefix or a part that identifies the package this belongs
162 	 * to. This is the path that can be used to find this object in the
163 	 * filesystem.
164 	 *
165 	 * url()  might return	"Pkg:/chromium-browser/usr/lib/chromium/foo.z"
166 	 * path() returns just	"/usr/lib/chromium/foo.z"
167 	 *
168 	 * Like url(), this is somewhat expensive since it recurses up the
169 	 * tree, but it stops when a PkgInfo node is found there.
170 	 **/
171 	virtual QString path() const;
172 
173 	/**
174 	 * Very much like FileInfo::url(), but with "/<Files>" appended if this
175 	 * is a dot entry. Useful for debugging.
176 	 *
177 	 * Notice: You can simply use the QTextStream operator<< to output
178 	 * exactly this:
179 	 *
180 	 * logDebug() << "Found fileInfo " << info << endl;
181 	 **/
182 	virtual QString debugUrl() const;
183 
184 	/**
185 	 * Returns the major and minor device numbers of the device this file
186 	 * resides on or 0 if this is a remote file.
187 	 **/
device()188 	dev_t device() const { return _device; }
189 
190 	/**
191 	 * The file permissions and object type as returned by lstat().
192 	 * You might want to use the repective convenience methods instead:
193 	 * isDir(), isFile(), ...
194 	 *
195 	 * See also symbolicPermissions(), octalPermissions()
196 	 **/
mode()197 	mode_t mode() const { return _mode;   }
198 
199 	/**
200 	 * The number of hard links to this file. Relevant for size summaries
201 	 * to avoid counting one file several times.
202 	 **/
links()203 	nlink_t links() const { return _links;	}
204 
205 	/**
206 	 * User ID of the owner.
207 	 *
208 	 * Notice that this might be undefined if this tree branch was read
209 	 * from a cache file. Check that with hasUid().
210 	 **/
uid()211 	uid_t uid() const { return _uid; }
212 
213 	/**
214 	 * Return the user name of the owner.
215 	 *
216 	 * If this tree branch was read from a cache file, this returns an
217 	 * empty string.
218 	 **/
219 	QString userName() const;
220 
221 	/**
222 	 * Return 'true' if this FileInfo has a UID (user ID).
223 	 *
224 	 * It might not have that information e.g. if it was read from a cache
225 	 * file.
226 	 **/
227 	bool hasUid() const;
228 
229 	/**
230 	 * Group ID of the owner.
231 	 *
232 	 * Notice that this might be undefined if this tree branch was read
233 	 * from a cache file. Check that with hasGid().
234 	 **/
gid()235 	gid_t gid() const { return _gid; }
236 
237 	/**
238 	 * Return the group name of the owner.
239 	 *
240 	 * If this tree branch was read from a cache file, this returns an
241 	 * empty string.
242 	 **/
243 	QString groupName() const;
244 
245 	/**
246 	 * Return 'true' if this FileInfo has a GID (group ID).
247 	 *
248 	 * It might not have that information e.g. if it was read from a cache
249 	 * file.
250 	 **/
251 	bool hasGid() const;
252 
253 	/**
254 	 * File permissions formatted like in "ls -l", i.e. "-rwxrwxrwx",
255 	 * "drwxrwxrwx"
256 	 **/
257 	QString symbolicPermissions() const;
258 
259 	/**
260 	 * File permissions formatted as octal number (like used by the "chmod"
261 	 * command, i.e. "0644"
262 	 **/
263 	QString octalPermissions() const;
264 
265 	/**
266 	 * The file size, taking into account multiple links for plain files or
267 	 * the true allocated size for sparse files. For plain files with
268 	 * multiple links this will be size/no_links, for sparse files it is
269 	 * the number of bytes actually allocated.
270 	 **/
271 	FileSize size() const;
272 
273 	/**
274 	 * The file size in bytes without taking multiple hard links into
275 	 * account.
276 	 **/
rawByteSize()277 	FileSize rawByteSize() const { return _size; }
278 
279 	/**
280 	 * The number of bytes actually allocated on the filesystem, taking
281 	 * multiple hard links (for plain files) into account.
282 	 *
283 	 * Usually this will be more than size() since the last few bytes of a
284 	 * file usually consume an additional cluster on the filesystem.
285 	 *
286 	 * In the case of sparse files, however, this might as well be
287 	 * considerably less than size() - this means that this file has
288 	 * "holes", i.e. large portions filled with zeros. This is typical for
289 	 * large core dumps for example. The only way to create such a file is
290 	 * to lseek() far ahead of the previous file size and then writing
291 	 * data. Most filesystem utilities will however disregard the fact that
292 	 * files are sparse files and simply allocate the holes as well, thus
293 	 * greatly increasing the disk space consumption of such a file. Only
294 	 * some few filesystem utilities like "cp", "rsync", "tar" have options
295 	 * to handle this more graciously - but usually only when specifically
296 	 * requested. See the respective man pages.
297 	 **/
298 	FileSize allocatedSize() const;
299 
300         /**
301          * The ratio of size() / allocatedSize() in percent.
302          **/
303         int usedPercent() const;
304 
305 	/**
306 	 * The allocated size without taking multiple hard links into account.
307 	 *
308 	 * If the filesystem can properly report the number of disk blocks
309 	 * used, this is the same as blocks() * 512.
310 	 **/
rawAllocatedSize()311 	FileSize rawAllocatedSize() const { return _allocatedSize; }
312 
313 	/**
314 	 * The file size in 512 byte blocks.
315 	 **/
blocks()316 	FileSize blocks() const { return _blocks; }
317 
318 	/**
319 	 * The modification time of the file (not the inode).
320 	 **/
mtime()321 	time_t mtime() const { return _mtime; }
322 
323         /**
324          * The year of the modification time of the file (1970-2037).
325          *
326          * The first call to this will calculate the value from _mtime and
327          * cache it (and the corresponding month); that's why this is not a
328          * const method.
329          **/
330         short mtimeYear();
331 
332         /**
333          * The month of the modification time of the file (1-12).
334          *
335          * The first call to this will calculate the value from _mtime and
336          * cache it (and the corresponding year); that's why this is not a
337          * const method.
338          **/
339         short mtimeMonth();
340 
341 	/**
342 	 * Returns the total size in bytes of this subtree.
343 	 * Derived classes that have children should overwrite this.
344 	 **/
totalSize()345 	virtual FileSize totalSize() { return size(); }
346 
347 	/**
348 	 * Returns the total allocated size in bytes of this subtree.
349 	 * Derived classes that have children should overwrite this.
350 	 **/
totalAllocatedSize()351 	virtual FileSize totalAllocatedSize() { return allocatedSize(); }
352 
353 	/**
354 	 * Returns the total size in blocks of this subtree.
355 	 * Derived classes that have children should overwrite this.
356 	 **/
totalBlocks()357 	virtual FileSize totalBlocks() { return _blocks; }
358 
359 	/**
360 	 * Returns the total number of children in this subtree, excluding this
361 	 * item.
362 	 * Derived classes that have children should overwrite this.
363 	 **/
totalItems()364 	virtual int totalItems() { return 0; }
365 
366 	/**
367 	 * Returns the total number of subdirectories in this subtree,
368 	 * excluding this item. Dot entries and "." or ".." are not counted.
369 	 * Derived classes that have children should overwrite this.
370 	 **/
totalSubDirs()371 	virtual int totalSubDirs() { return 0; }
372 
373 	/**
374 	 * Returns the total number of plain file children in this subtree,
375 	 * excluding this item.
376 	 * Derived classes that have children should overwrite this.
377 	 **/
totalFiles()378 	virtual int totalFiles() { return 0; }
379 
380 	/**
381 	 * Returns the total number of non-directory items in this subtree,
382 	 * excluding this item.
383 	 * Derived classes that have children should overwrite this.
384 	 **/
totalNonDirItems()385 	virtual int totalNonDirItems() { return 0; }
386 
387 	/**
388 	 * Returns the total number of ignored (non-directory!) items in this
389 	 * subtree, excluding this item.
390 	 * Derived classes that have children should overwrite this.
391 	 **/
totalIgnoredItems()392 	virtual int totalIgnoredItems() { return 0; }
393 
394 	/**
395 	 * Returns the total number of not ignored (non-directory!) items in
396 	 * this subtree, excluding this item.
397 	 *
398 	 * Derived classes that have children should overwrite this.
399 	 **/
totalUnignoredItems()400 	virtual int totalUnignoredItems() { return 0; }
401 
402 	/**
403 	 * Returns the total number of direct children of this item.
404 	 *
405 	 * Derived classes that have children should overwrite this.
406 	 **/
directChildrenCount()407 	virtual int directChildrenCount() { return 0; }
408 
409 	/**
410 	 * Returns the number of subdirectories below this item that could not
411 	 * be read (typically due to insufficient permissions).
412 	 *
413 	 * Notice that this does NOT include this item if it is a directory
414 	 * that could not be read.
415 	 *
416 	 * Derived classes that have children should overwrite this.
417 	 **/
errSubDirCount()418 	virtual int errSubDirCount() { return 0; }
419 
420 	/**
421 	 * Returns the latest modification time of this subtree.
422 	 * Derived classes that have children should overwrite this.
423 	 **/
latestMtime()424 	virtual time_t latestMtime() { return _mtime; }
425 
426 	/**
427 	 * Returns the oldest modification time of any file in this subtree or
428 	 * 0 if there is no file.
429 	 *
430 	 * Derived classes that have children should overwrite this.
431 	 **/
oldestFileMtime()432 	virtual time_t oldestFileMtime() { return isFile() ? _mtime : 0; }
433 
434 	/**
435 	 * Return the percentage of this subtree in regard to its parent
436 	 * (0.0..100.0). Return a negative value if for any reason this cannot
437 	 * be calculated or it would not make any sense.
438 	 *
439 	 * Derived classes are free to overwrite this, but this default
440 	 * implementation should work well enough.
441 	 **/
442 	virtual float subtreePercent();
443 
444 	/**
445 	 * Return the percentage of this subtree's allocated size in regard to
446 	 * its parent's allocated size.  (0.0..100.0). Return a negative value
447 	 * if for any reason this cannot be calculated or it would not make any
448 	 * sense.
449 	 *
450 	 * Derived classes are free to overwrite this, but this default
451 	 * implementation should work well enough.
452 	 **/
453 	virtual float subtreeAllocatedPercent();
454 
455 	/**
456 	 * Returns 'true' if this had been excluded while reading.
457 	 * Derived classes may want to overwrite this.
458 	 **/
isExcluded()459 	virtual bool isExcluded() const { return false; }
460 
461 	/**
462 	 * Set the 'excluded' status.
463 	 *
464 	 * This default implementation silently ignores the value passed and
465 	 * does nothing. Derived classes may want to overwrite this.
466 	 **/
setExcluded(bool excl)467 	virtual void setExcluded( bool excl ) { Q_UNUSED( excl); return; }
468 
469 	/**
470 	 * Returns whether or not this is a mount point.
471 	 * Derived classes may want to overwrite this.
472 	 **/
isMountPoint()473 	virtual bool isMountPoint() const  { return false; }
474 
475 	/**
476 	 * Sets the mount point state, i.e. whether or not this is a mount
477 	 * point.
478 	 *
479 	 * This default implementation silently ignores the value passed and
480 	 * does nothing. Derived classes may want to overwrite this.
481 	 **/
482 	virtual void setMountPoint( bool isMountPoint = true )
483 	    { Q_UNUSED( isMountPoint ); return; }
484 
485 	/**
486 	 * Returns true if this subtree is finished reading.
487 	 *
488 	 * This default implementation always returns 'true';
489 	 * derived classes should overwrite this.
490 	 **/
isFinished()491 	virtual bool isFinished() { return true; }
492 
493 	/**
494 	 * Returns true if this subtree is busy, i.e. it is not finished
495 	 * reading yet.
496 	 *
497 	 * This default implementation always returns 'false';
498 	 * derived classes should overwrite this.
499 	 **/
isBusy()500 	virtual bool isBusy() { return false; }
501 
502 	/**
503 	 * Returns the number of pending read jobs in this subtree. When this
504 	 * number reaches zero, the entire subtree is done.
505 	 * Derived classes that have children should overwrite this.
506 	 **/
pendingReadJobs()507 	virtual int pendingReadJobs() { return 0; }
508 
509 	/**
510 	 * Return 'true' if the filesystem can report block sizes.
511 	 *
512 	 * This is determined heuristically from the nearest DirInfo parent: If
513 	 * it has blocks() > 0 and size() > 0, we can safely assume that the
514 	 * filesystem does report the number of blocks.
515 	 **/
516 	bool filesystemCanReportBlocks() const;
517 
518 
519 	//
520 	// Tree management
521 	//
522 
523 	/**
524 	 * Returns a pointer to the DirTree this entry belongs to.
525 	 **/
tree()526 	DirTree * tree() const { return _tree; }
527 
528 	/**
529 	 * Returns a pointer to this entry's parent entry or 0 if there is
530 	 * none.
531 	 **/
parent()532 	DirInfo * parent() const { return _parent; }
533 
534 	/**
535 	 * Set the "parent" pointer.
536 	 **/
setParent(DirInfo * newParent)537 	void setParent( DirInfo *newParent ) { _parent = newParent; }
538 
539 	/**
540 	 * Returns a pointer to the next entry on the same level
541 	 * or 0 if there is none.
542 	 **/
next()543 	FileInfo * next() const { return _next;	  }
544 
545 	/**
546 	 * Set the "next" pointer.
547 	 **/
setNext(FileInfo * newNext)548 	void  setNext( FileInfo *newNext ) { _next = newNext; }
549 
550 	/**
551 	 * Returns the first child of this item or 0 if there is none.
552 	 * Use the child's next() method to get the next child.
553 	 *
554 	 * This default implementation always returns 0.
555 	 **/
firstChild()556 	virtual FileInfo * firstChild() const { return 0; }
557 
558 	/**
559 	 * Set this entry's first child.
560 	 * Use this method only if you know exactly what you are doing.
561 	 *
562 	 * This default implementation does nothing.
563 	 * Derived classes might want to overwrite this.
564 	 **/
setFirstChild(FileInfo * newFirstChild)565 	virtual void setFirstChild( FileInfo *newFirstChild )
566 	    { Q_UNUSED( newFirstChild ); }
567 
568 	/**
569 	 * Returns true if this entry has any children.
570 	 **/
571 	virtual bool hasChildren() const;
572 
573 	/**
574 	 * Returns true if this entry is in subtree 'subtree', i.e. if this is
575 	 * a child or grandchild etc. of 'subtree'.
576 	 **/
577 	bool isInSubtree( const FileInfo *subtree ) const;
578 
579 	/**
580 	 * Locate a child somewhere in this subtree whose URL (i.e. complete
581 	 * path) matches the URL passed. Returns 0 if there is no such child.
582 	 *
583 	 * Notice: This is a very expensive operation since the entire subtree
584 	 * is searched recursively.
585 	 *
586 	 * Derived classes might or might not wish to overwrite this method;
587 	 * it's only advisable to do so if a derived class comes up with a
588 	 * different method than brute-force searching all children.
589 	 *
590 	 * 'findPseudoDirs' specifies if locating pseudo directories like "dot
591 	 * entries" (".../<Files>") or "attics" (".../<Ignored>") is desired.
592 	 **/
593 	virtual FileInfo * locate( QString url, bool findPseudoDirs = false );
594 
595 	/**
596 	 * Insert a child into the children list.
597 	 *
598 	 * The order of children in this list is absolutely undefined;
599 	 * don't rely on any implementation-specific order.
600 	 *
601 	 * This default implementation does nothing.
602 	 **/
insertChild(FileInfo * newChild)603 	virtual void insertChild( FileInfo *newChild ) { Q_UNUSED( newChild ); }
604 
605 	/**
606 	 * Return the "Dot Entry" for this node if there is one (or 0
607 	 * otherwise): This is a pseudo entry that directory nodes use to store
608 	 * non-directory children separately from directories. This way the end
609 	 * user can easily tell which summary fields belong to the directory
610 	 * itself and which are the accumulated values of the entire subtree.
611 	 *
612 	 * This default implementation always returns 0.
613 	 **/
dotEntry()614 	virtual DotEntry * dotEntry() const { return 0; }
615 
616 	/**
617 	 * Set a "Dot Entry". This makes sense for directories only.
618 	 *
619 	 * This default implementation does nothing.
620 	 **/
setDotEntry(FileInfo * newDotEntry)621 	virtual void setDotEntry( FileInfo *newDotEntry )
622 	    { Q_UNUSED( newDotEntry ); }
623 
624 	/**
625 	 * Return 'true' if this is a pseudo directory: A "dot entry" or an
626 	 * "attic".
627 	 **/
isPseudoDir()628 	virtual bool isPseudoDir() const
629 	    { return isDotEntry() || isAttic(); }
630 
631 	/**
632 	 * Returns true if this is a "Dot Entry".
633 	 * See dotEntry() for details.
634 	 *
635 	 * This default implementation always returns false.
636 	 **/
isDotEntry()637 	virtual bool isDotEntry() const { return false; }
638 
639 	/**
640 	 * Return the "Attic" entry for this node if there is one (or 0
641 	 * otherwise): This is a pseudo entry that directory nodes use to store
642 	 * ignored files and directories separately from the normal tree
643 	 * hierarchy.
644 	 *
645 	 * This default implementation always returns 0.
646 	 **/
attic()647 	virtual Attic * attic() const { return 0; }
648 
649 	/**
650 	 * Check if this is an attic entry where ignored files and directories
651 	 * are stored.
652 	 *
653 	 * This default implementation always returns false.
654 	 **/
isAttic()655 	virtual bool isAttic() const { return false; }
656 
657 	/**
658 	 * (Translated) user-visible string for a "Dot Entry" ("<Files>").
659 	 **/
660 	static QString dotEntryName();
661 
662 	/**
663 	 * (Translated) user-visible string for the "Attic" ("<Ignored>").
664 	 **/
665 	static QString atticName();
666 
667 	/**
668 	 * Returns the tree level (depth) of this item.
669 	 * The topmost level is 0.
670 	 *
671 	 * This is a (somewhat) expensive operation since it will recurse up
672 	 * to the top of the tree.
673 	 **/
674 	int treeLevel() const;
675 
676 	/**
677 	 * Notification that a child has been added somewhere in the subtree.
678 	 *
679 	 * This default implementation does nothing.
680 	 **/
childAdded(FileInfo * newChild)681 	virtual void childAdded( FileInfo *newChild ) { Q_UNUSED( newChild ); }
682 
683 	/**
684 	 * Remove a child from the children list.
685 	 *
686 	 * IMPORTANT: This MUST be called just prior to deleting an object of
687 	 * this class. Regrettably, this cannot simply be moved to the
688 	 * destructor: Important parts of the object might already be destroyed
689 	 * (e.g., the virtual table - no more virtual methods).
690 	 *
691 	 * This default implementation does nothing.
692 	 * Derived classes that can handle children should overwrite this.
693 	 **/
unlinkChild(FileInfo * deletedChild)694 	virtual void unlinkChild( FileInfo *deletedChild ) { Q_UNUSED( deletedChild ); }
695 
696 	/**
697 	 * Notification that a child is about to be deleted somewhere in the
698 	 * subtree.
699 	 **/
deletingChild(FileInfo * deletedChild)700 	virtual void deletingChild( FileInfo *deletedChild ) { Q_UNUSED( deletedChild ); }
701 
702 	/**
703 	 * Get the current state of the directory reading process:
704 	 *
705 	 * This default implementation always returns DirFinished.
706 	 * Derived classes should overwrite this.
707 	 **/
readState()708 	virtual DirReadState readState() const { return DirFinished; }
709 
710 	/**
711 	 * Check if readState() is anything that indicates an error reading the
712 	 * directory, i.e. DirError or DirPermissionDenied.
713 	 *
714 	 * This default implementation always returns 'false'.
715 	 * Derived classes should overwrite this.
716 	 **/
readError()717 	virtual bool readError() const { return false; }
718 
719 	/**
720 	 * Return a prefix for the total size (and similar accumulated fields)
721 	 * of this item: ">" if there might be more, i.e. if a subdirectory
722 	 * could not be read or if reading was aborted, an empty string
723 	 * otherwise.
724 	 *
725 	 * This default implementation returns an empty string. Derived classes
726 	 * that can handle child items should reimplement this.
727 	 **/
sizePrefix()728 	virtual QString sizePrefix() const { return ""; }
729 
730 	/**
731 	 * Returns true if this is a DirInfo object.
732 	 *
733 	 * Don't confuse this with isDir() which tells whether or not this is a
734 	 * disk directory! Both should return the same, but you'll never know -
735 	 * better be safe than sorry!
736 	 *
737 	 * This default implementation always returns 'false'. Derived classes
738 	 * (in particular, those derived from DirInfo) should overwrite this.
739 	 **/
isDirInfo()740 	virtual bool isDirInfo() const { return false; }
741 
742 	/**
743 	 * Returns true if this is a PkgInfo object.
744 	 *
745 	 * This default implementation always returns 'false'. Derived classes
746 	 * (in particular, those derived from PkgInfo) should overwrite this.
747 	 **/
isPkgInfo()748 	virtual bool isPkgInfo() const { return false; }
749 
750 	/**
751 	 * Try to convert this to a DirInfo pointer. This returns null if this
752 	 * is not a DirInfo.
753 	 **/
754 	DirInfo * toDirInfo();
755 
756 	/**
757 	 * Try to convert this to a DirInfo pointer. This returns null if this
758 	 * is not a DirInfo.
759 	 **/
760 	DotEntry * toDotEntry();
761 
762 	/**
763 	 * Try to convert this to a DirInfo pointer. This returns null if this
764 	 * is not a DirInfo.
765 	 **/
766 	Attic * toAttic();
767 
768 	/**
769 	 * Try to convert this to a PkgInfo pointer. This returns null if this
770 	 * is not a DirInfo.
771 	 **/
772 	PkgInfo * toPkgInfo();
773 
774 	/**
775 	 * Returns true if this is a sparse file, i.e. if this file has
776 	 * actually fewer disk blocks allocated than its byte size would call
777 	 * for.
778 	 *
779 	 * This is a cheap operation since it relies on a cached flag that is
780 	 * calculated in the constructor rather than doing repeated
781 	 * calculations and comparisons.
782 	 *
783 	 * Please not that size() already takes this into account.
784 	 **/
isSparseFile()785 	bool isSparseFile() const { return _isSparseFile; }
786 
787 	/**
788 	 * Returns true if this FileInfo was read from a cache file.
789 	 **/
790 	bool isCached() const;
791 
792 	/**
793 	 * Returns true if this FileInfo was ignored by some rule (e.g. in the
794 	 * "unpackaged files" view).
795 	 **/
isIgnored()796 	bool isIgnored() const { return _isIgnored; }
797 
798 	/**
799 	 * Set the "ignored" flag. Notice that this only sets the flag; it does
800 	 * not reparent the FileInfo or anything like that.
801 	 **/
setIgnored(bool ignored)802 	void setIgnored( bool ignored ) { _isIgnored = ignored; }
803 
804 	/**
805 	 * Return the nearest PkgInfo parent or 0 if there is none.
806 	 **/
807 	PkgInfo * pkgInfoParent() const;
808 
809 
810 	//
811 	// File type / mode convenience methods.
812 	// These are simply shortcuts to the respective macros from
813 	// <sys/stat.h>.
814 	//
815 
816 	/**
817 	 * Returns true if this is a directory.
818 	 **/
isDir()819 	bool isDir()		const { return S_ISDIR( _mode ) ? true : false; }
820 
821 	/**
822 	 * Returns true if this is a regular file.
823 	 **/
isFile()824 	bool isFile()		const { return S_ISREG( _mode ) ? true : false; }
825 
826 	/**
827 	 * Returns true if this is a symbolic link.
828 	 **/
isSymLink()829 	bool isSymLink()	const { return S_ISLNK( _mode ) ? true : false; }
830 
831 
832 	/**
833 	 * Returns true if this is a (block or character) device.
834 	 **/
isDevice()835 	bool isDevice()		const { return ( S_ISBLK ( _mode ) ||
836 						 S_ISCHR ( _mode )   ) ? true : false; }
837 
838 	/**
839 	 * Returns true if this is a block device.
840 	 **/
isBlockDevice()841 	bool isBlockDevice()	const { return S_ISBLK ( _mode ) ? true : false; }
842 
843 	/**
844 	 * Returns true if this is a block device.
845 	 **/
isCharDevice()846 	bool isCharDevice()	const { return S_ISCHR ( _mode ) ? true : false; }
847 
848 	/**
849 	 * Returns true if this is a FIFO.
850 	 **/
isFifo()851 	bool isFifo()		const { return S_ISFIFO ( _mode ) ? true : false; }
852 
853 	/**
854 	 * Returns true if this is a socket.
855 	 **/
isSocket()856 	bool isSocket()		const { return S_ISSOCK ( _mode ) ? true : false; }
857 
858 	/**
859 	 * Returns true if this is a "special" file, i.e. a (block or character)
860 	 * device, a FIFO (named pipe) or a socket.
861 	 **/
isSpecial()862 	bool isSpecial()	const { return ( S_ISBLK ( _mode ) ||
863 						 S_ISCHR ( _mode ) ||
864 						 S_ISFIFO( _mode ) ||
865 						 S_ISSOCK( _mode )   ) ? true : false; }
866 
867         /**
868          * Returns true if this is a symlink, but the (direct) link target does
869          * not exist. This does NOT check multiple symlink indirections,
870          * i.e. it does not check if the target is also a symlink if the target
871          * of that also exists.
872          *
873          * Intentionally not declaring this as 'const' since this might some
874          * day use cached information and do lazy initialization on its first
875          * call.
876          **/
877         bool isBrokenSymLink();
878 
879         /**
880          * Return the (direct) target path if this is a symlink. This does not
881          * follow multiple symlink indirections, only the direct target.
882          *
883          * If this is not a symlink, an empty string is returned.
884          *
885          * Intentionally not declaring this as 'const' since this might some
886          * day use cached information and do lazy initialization on its first
887          * call.
888          **/
889         QString symLinkTarget();
890 
891 	/**
892 	 * Set the policy how hard links are handled: By default, for files
893 	 * with multiple hard links, the size is distributed among each
894 	 * individual hard link for that file. So a file with a size of 4 kB
895 	 * and 4 hard links reports 1 kB to its parent directory.
896 	 *
897 	 * When this flag is set to 'true', it will report the full 4 kB each
898 	 * time, so all 4 hard links together will now add up to 16 kB. While
899 	 * this is probably a very bad idea if those links are all in the same
900 	 * directory (or subtree), it might even be useful if there are several
901 	 * separate subtrees that all share hard links between each other, but
902 	 * not within the same subtree. Some backup systems use this strategy
903 	 * to save disk space.
904 	 *
905 	 * Use this with caution.
906 	 *
907 	 * This flag will be read from the config file from the outside
908 	 * (DirTree) and set from there using this function.
909 	 **/
910 	static void setIgnoreHardLinks( bool ignore );
911 
912 	/**
913 	 * Return the current hard links accounting policy.
914 	 * See setIgnoreHardLinks() for details.
915 	 **/
ignoreHardLinks()916 	static bool ignoreHardLinks() { return _ignoreHardLinks; }
917 
918 
919     protected:
920 
921         /**
922          * Calculate values that are dependent on _mtime, yet quite expensive
923          * to calculate, and cache them: _mtimeYear, _mtimeMonth
924          **/
925         void processMtime();
926 
927 
928 	// Data members.
929 	//
930 	// Keep this short in order to use as little memory as possible -
931 	// there will be a _lot_ of entries of this kind!
932 
933 	short		_magic;			// magic number to detect if this object is valid
934 	QString		_name;			// the file name (without path!)
935 	bool		_isLocalFile  :1;	// flag: local or remote file?
936 	bool		_isSparseFile :1;	// (cache) flag: sparse file (file with "holes")?
937 	bool		_isIgnored    :1;	// flag: ignored by rule?
938 	dev_t		_device;		// device this object resides on
939 	mode_t		_mode;			// file permissions + object type
940 	nlink_t		_links;			// number of links
941 	uid_t		_uid;			// User ID of owner
942 	gid_t		_gid;			// Group ID of owner
943 	FileSize	_size;			// size in bytes
944 	FileSize	_blocks;		// 512 bytes blocks
945 	FileSize	_allocatedSize;		// allocated size in bytes
946 	time_t		_mtime;			// modification time
947         short           _mtimeYear;             // year  of the modification time or -1
948         short           _mtimeMonth;            // month of the modification time or -1
949 
950 	DirInfo	 *	_parent;		// pointer to the parent entry
951 	FileInfo *	_next;			// pointer to the next entry
952 	DirTree	 *	_tree;			// pointer to the parent tree
953 
954 	static bool	_ignoreHardLinks;	// don't distribute size for multiple hard links
955 
956     };	// class FileInfo
957 
958 
959 
960     typedef QList<FileInfo *> FileInfoList;
961 
962 
963 
964     //----------------------------------------------------------------------
965     //			       Static Functions
966     //----------------------------------------------------------------------
967 
968 
969     /**
970      * Return the last pathname component of a file name.
971      *
972      * Examples:
973      *
974      *	   "/home/bob/foo.txt"	-> "foo.txt"
975      *	   "foo.txt"		-> "foo.txt"
976      *	   "/usr/bin"		-> "bin"
977      *	   "/usr/bin/"		-> "bin"
978      *
979      * Notice that FileInfo also has a member function baseName().
980      **/
981     QString baseName( const QString & fileName );
982 
983 
984     /**
985      * Print the debugUrl() of a FileInfo in a debug stream.
986      **/
987     inline QTextStream & operator<< ( QTextStream & stream, const FileInfo * info )
988     {
989 	if ( info )
990 	{
991 	    if ( info->checkMagicNumber() )
992 		stream << info->debugUrl();
993 	    else
994 		stream << "<INVALID FileInfo *>";
995 	}
996 	else
997 	    stream << "<NULL FileInfo *>";
998 
999 	return stream;
1000     }
1001 
1002 }	// namespace QDirStat
1003 
1004 
1005 #endif // ifndef FileInfo_h
1006 
1007