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