1 /* fileentry.cc
2 * This file belongs to Worker, a file manager for UN*X/X11.
3 * Copyright (C) 2001-2020 Ralf Hoffmann.
4 * You can contact me at: ralf@boomerangsworld.de
5 * or http://www.boomerangsworld.de/worker
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 #include "fileentry.hh"
23 #include "aguix/lowlevelfunc.h"
24 #include "aguix/fieldlistviewdnd.h"
25 #include "wconfig.h"
26 #include "grouphash.h"
27 #include "pdatei.h"
28 #include "nmrowdata.h"
29 #include "condparser.h"
30 #include "stringbuf.h"
31 #include "wcfiletype.hh"
32 #include "magic_db.hh"
33 #include "worker.h"
34 #include "nwc_os.hh"
35
36 class FEBookmarkInfo {
37 public:
FEBookmarkInfo()38 FEBookmarkInfo() : m_bookmark_match( FileEntry::NOT_IN_BOOKMARKS ),
39 m_matching_labels( NULL )
40 {
41 }
FEBookmarkInfo(const FEBookmarkInfo & other)42 FEBookmarkInfo( const FEBookmarkInfo &other ) : m_bookmark_match( other.m_bookmark_match ),
43 m_matching_labels( NULL )
44 {
45 if ( other.m_matching_labels != NULL ) {
46 m_matching_labels = new std::list<std::string>( *other.m_matching_labels );
47 }
48 }
49
~FEBookmarkInfo()50 ~FEBookmarkInfo()
51 {
52 if ( m_matching_labels != NULL ) {
53 delete m_matching_labels;
54 }
55 }
56
operator =(const FEBookmarkInfo & rhs)57 FEBookmarkInfo &operator=( const FEBookmarkInfo &rhs )
58 {
59 if ( this != &rhs ) {
60 m_bookmark_match = rhs.m_bookmark_match;
61
62 if ( m_matching_labels != NULL ) delete m_matching_labels;
63 if ( rhs.m_matching_labels != NULL ) {
64 m_matching_labels = new std::list<std::string>( *rhs.m_matching_labels );
65 } else {
66 m_matching_labels = NULL;
67 }
68 }
69 return *this;
70 }
71
72
73 FileEntry::bookmark_match_t m_bookmark_match;
74 std::list<std::string> *m_matching_labels;
75 };
76
FileEntry()77 FileEntry::FileEntry()
78 {
79 name=NULL;
80 fullname=NULL;
81 filetype=NULL;
82 use=true;
83 isHidden=false;
84 isCorrupt = false;
85
86 reclistQueued = false;
87
88 memset( &statbuf, 0, sizeof( statbuf ) );
89 memset( &dstatbuf, 0, sizeof( dstatbuf ) );
90
91 contentBuf.content = NULL;
92 contentBuf.size = 0;
93
94 outputBuf = NULL;
95
96 _ID = -1;
97
98 m_bookmark_info = NULL;
99 }
100
~FileEntry()101 FileEntry::~FileEntry()
102 {
103 if(name!=NULL) _freesafe(name);
104 if(fullname!=NULL) _freesafe(fullname);
105 freeContentBuf();
106 freeOutputBuf();
107
108 if ( m_bookmark_info != NULL ) delete m_bookmark_info;
109 }
110
isDir() const111 bool FileEntry::isDir() const
112 {
113 bool dir=false;
114 if ( isLink == true ) {
115 if ( isCorrupt == false ) {
116 if ( S_ISDIR( dstatbuf.mode ) ) dir = true;
117 }
118 } else if ( S_ISDIR( statbuf.mode ) ) dir = true;
119 return dir;
120 }
121
duplicate()122 FileEntry *FileEntry::duplicate()
123 {
124 #if 0
125 FileEntry *tfe=new FileEntry();
126 tfe->fullname=dupstring(fullname);
127 tfe->name=dupstring(name);
128 tfe->dirsize=dirsize;
129 tfe->select=select;
130 tfe->isLink=isLink;
131 tfe->isCorrupt=isCorrupt;
132 tfe->inFilter=inFilter;
133 tfe->filetype=filetype;
134
135 memcpy( &( tfe->statbuf ), &statbuf, sizeof( statbuf ) );
136 memcpy( &( tfe->dstatbuf ), &dstatbuf, sizeof( dstatbuf ) );
137
138 tfe->setCustomColors( customcolors );
139 tfe->setColor( 0, fg );
140 tfe->setColor( 1, bg );
141
142 return tfe;
143 #endif
144 return new FileEntry( *this );
145 }
146
readInfos()147 int FileEntry::readInfos()
148 {
149 return readInfos(false);
150 }
151
readInfos(bool update)152 int FileEntry::readInfos( bool update )
153 {
154 //TODO: auf update achten
155 worker_struct_stat stbuf;
156
157 select = false;
158 dirsize = -1;
159 filetype = NULL;
160 isCorrupt = false;
161 isLink = false;
162
163 if ( fullname == NULL ) return 1;
164
165 memset( &statbuf, 0, sizeof( statbuf ) );
166 memset( &dstatbuf, 0, sizeof( dstatbuf ) );
167
168 if ( worker_lstat( fullname, &stbuf ) == 0 ) {
169 statbuf.size = stbuf.st_size;
170 statbuf.lastaccess = stbuf.st_atime;
171 statbuf.lastmod = stbuf.st_mtime;
172 statbuf.lastchange = stbuf.st_ctime;
173 statbuf.mode = stbuf.st_mode;
174 statbuf.userid = stbuf.st_uid;
175 statbuf.groupid = stbuf.st_gid;
176 statbuf.inode = stbuf.st_ino;
177 statbuf.nlink = stbuf.st_nlink;
178 statbuf.blocks = stbuf.st_blocks;
179 statbuf.rdev = stbuf.st_rdev;
180 statbuf.dev = stbuf.st_dev;
181 } else {
182 isCorrupt = true;
183 return 2;
184 }
185
186 if ( S_ISLNK( statbuf.mode ) ) {
187 isLink = true;
188 if ( worker_stat( fullname, &stbuf ) == 0 ) {
189 dstatbuf.size = stbuf.st_size;
190 dstatbuf.lastaccess = stbuf.st_atime;
191 dstatbuf.lastmod = stbuf.st_mtime;
192 dstatbuf.lastchange = stbuf.st_ctime;
193 dstatbuf.mode = stbuf.st_mode;
194 dstatbuf.userid = stbuf.st_uid;
195 dstatbuf.groupid = stbuf.st_gid;
196 dstatbuf.inode = stbuf.st_ino;
197 dstatbuf.nlink = stbuf.st_nlink;
198 dstatbuf.blocks = stbuf.st_blocks;
199 dstatbuf.rdev = stbuf.st_rdev;
200 dstatbuf.dev = stbuf.st_dev;
201 } else {
202 /* corrupt link */
203 isCorrupt = true;
204 dstatbuf.mode = 0; // to prevent corrupt links treated as dirs
205 if ( errno == ENOENT ) {
206 // Eventl. fuer spaetere Betrachtungen
207 }
208 }
209 }
210 return 0;
211 }
212
getDestination() const213 char *FileEntry::getDestination() const
214 {
215 char *str = NULL;
216 if ( isLink == true && fullname != NULL ) {
217 str = NWC::OS::getLinkTarget( fullname );
218 }
219 return str;
220 }
221
getPermissionString()222 const char *FileEntry::getPermissionString()
223 {
224 static char str[WORKER_PERMCHARS + 1];
225
226 if ( isLink == true ) str[0] = 'l';
227 else {
228 if ( isCorrupt ) str[0] = '?';
229 else if ( S_ISDIR( statbuf.mode ) ) str[0] = 'd';
230 else if ( S_ISFIFO( statbuf.mode ) ) str[0] = 'p';
231 else if ( S_ISSOCK( statbuf.mode ) ) str[0] = 's';
232 else if ( S_ISCHR( statbuf.mode ) ) str[0] = 'c';
233 else if ( S_ISBLK( statbuf.mode ) ) str[0] = 'b';
234 else str[0] = '-';
235 }
236 if ( ( statbuf.mode & S_IRUSR ) == S_IRUSR ) str[1] = 'r'; else str[1] = '-';
237 if ( ( statbuf.mode & S_IWUSR ) == S_IWUSR ) str[2] = 'w'; else str[2] = '-';
238 if ( ( statbuf.mode & S_ISUID ) == S_ISUID ) {
239 if ( ( statbuf.mode & S_IXUSR ) == S_IXUSR ) str[3] = 's'; else str[3] = 'S';
240 } else {
241 if ( ( statbuf.mode & S_IXUSR ) == S_IXUSR ) str[3] = 'x'; else str[3] = '-';
242 }
243 if ( ( statbuf.mode & S_IRGRP ) == S_IRGRP ) str[4] = 'r'; else str[4] = '-';
244 if ( ( statbuf.mode & S_IWGRP ) == S_IWGRP ) str[5] = 'w'; else str[5] = '-';
245 if ( ( statbuf.mode & S_ISGID ) == S_ISGID ) {
246 if ( ( statbuf.mode & S_IXGRP ) == S_IXGRP ) str[6] = 's'; else str[6] = 'S';
247 } else {
248 if ( ( statbuf.mode & S_IXGRP ) == S_IXGRP ) str[6] = 'x'; else str[6] = '-';
249 }
250 if ( ( statbuf.mode & S_IROTH ) == S_IROTH ) str[7] = 'r'; else str[7] = '-';
251 if ( ( statbuf.mode & S_IWOTH ) == S_IWOTH ) str[8] = 'w'; else str[8] = '-';
252 if ( ( statbuf.mode & S_ISVTX ) == S_ISVTX ) {
253 if ( ( statbuf.mode & S_IXOTH ) == S_IXOTH ) str[9] = 't'; else str[9] = 'T';
254 } else {
255 if ( ( statbuf.mode & S_IXOTH ) == S_IXOTH ) str[9] = 'x'; else str[9] = '-';
256 }
257 str[10]=0;
258 return str;
259 }
260
isExe(bool fastTest) const261 bool FileEntry::isExe( bool fastTest ) const
262 {
263 if ( fastTest == true ) {
264 if ( ( statbuf.mode & S_IXUSR ) == S_IXUSR ) return true;
265 if ( ( statbuf.mode & S_IXGRP ) == S_IXGRP ) return true;
266 if ( ( statbuf.mode & S_IXOTH ) == S_IXOTH ) return true;
267 } else {
268 uid_t uid;
269 gid_t gid;
270 mode_t m;
271 bool e = false;
272
273 if ( isLink == false ) {
274 uid = userid();
275 gid = groupid();
276 m = mode();
277 } else if ( isCorrupt == false ) {
278 uid = duserid();
279 gid = dgroupid();
280 m = dmode();
281 } else {
282 // corrupt symlink is not executable
283 return false;
284 }
285
286 if ( uid == geteuid() ) {
287 e = ( ( m & S_IXUSR ) != 0 ) ? true : false;
288 } else if ( ugdb->isInGroup( gid ) == true ) {
289 e = ( ( m & S_IXGRP ) != 0 ) ? true : false;
290 } else {
291 e = ( ( m & S_IXOTH ) != 0 ) ? true : false;
292 }
293 return e;
294 }
295 return false;
296 }
297
match(const char * pattern)298 bool FileEntry::match( const char* pattern )
299 {
300 if(fnmatch(pattern,name,0)==0) return true;
301 return false;
302 }
303
size() const304 loff_t FileEntry::size() const
305 {
306 return statbuf.size;
307 }
308
lastaccess() const309 time_t FileEntry::lastaccess() const
310 {
311 return statbuf.lastaccess;
312 }
313
lastmod() const314 time_t FileEntry::lastmod() const
315 {
316 return statbuf.lastmod;
317 }
318
lastchange() const319 time_t FileEntry::lastchange() const
320 {
321 return statbuf.lastchange;
322 }
323
mode() const324 mode_t FileEntry::mode() const
325 {
326 return statbuf.mode;
327 }
328
userid() const329 uid_t FileEntry::userid() const
330 {
331 return statbuf.userid;
332 }
333
groupid() const334 gid_t FileEntry::groupid() const
335 {
336 return statbuf.groupid;
337 }
338
inode() const339 ino_t FileEntry::inode() const
340 {
341 return statbuf.inode;
342 }
343
nlink() const344 nlink_t FileEntry::nlink() const
345 {
346 return statbuf.nlink;
347 }
348
blocks() const349 loff_t FileEntry::blocks() const
350 {
351 return statbuf.blocks;
352 }
353
dsize() const354 loff_t FileEntry::dsize() const
355 {
356 return dstatbuf.size;
357 }
358
dlastaccess() const359 time_t FileEntry::dlastaccess() const
360 {
361 return dstatbuf.lastaccess;
362 }
363
dlastmod() const364 time_t FileEntry::dlastmod() const
365 {
366 return dstatbuf.lastmod;
367 }
368
dlastchange() const369 time_t FileEntry::dlastchange() const
370 {
371 return dstatbuf.lastchange;
372 }
373
dmode() const374 mode_t FileEntry::dmode() const
375 {
376 return dstatbuf.mode;
377 }
378
duserid() const379 uid_t FileEntry::duserid() const
380 {
381 return dstatbuf.userid;
382 }
383
dgroupid() const384 gid_t FileEntry::dgroupid() const
385 {
386 return dstatbuf.groupid;
387 }
388
dinode() const389 ino_t FileEntry::dinode() const
390 {
391 return dstatbuf.inode;
392 }
393
dnlink() const394 nlink_t FileEntry::dnlink() const
395 {
396 return dstatbuf.nlink;
397 }
398
dblocks() const399 loff_t FileEntry::dblocks() const
400 {
401 return dstatbuf.blocks;
402 }
403
rdev() const404 dev_t FileEntry::rdev() const
405 {
406 return statbuf.rdev;
407 }
408
drdev() const409 dev_t FileEntry::drdev() const
410 {
411 return dstatbuf.rdev;
412 }
413
dev() const414 dev_t FileEntry::dev() const
415 {
416 return statbuf.dev;
417 }
418
ddev() const419 dev_t FileEntry::ddev() const
420 {
421 return dstatbuf.dev;
422 }
423
checkAccess(int m) const424 bool FileEntry::checkAccess( int m ) const
425 {
426 if ( fullname == NULL ) return false;
427 return ( worker_access( fullname, m ) == 0 ) ? true : false;
428 }
429
getContentStr(int pos,int len)430 char *FileEntry::getContentStr( int pos, int len )
431 {
432 char *resstr = NULL;
433 int mylen, i;
434
435 if ( pos < 0 ) return dupstring( "" );
436 if ( len < 1 ) return dupstring( "" );
437
438 if ( contentBuf.content == NULL ) readContentBuf();
439 if ( contentBuf.content != NULL ) {
440 mylen = a_min( len, contentBuf.size - pos );
441 if ( mylen > 0 ) {
442 resstr = (char*)_allocsafe( mylen + 1 );
443 for ( i = 0; i < mylen; i++ ) {
444 resstr[i] = contentBuf.content[i+pos];
445 }
446 resstr[i] = '\0';
447 }
448 }
449
450 return ( resstr != NULL ) ? resstr : dupstring( "" );
451 }
452
getContentNum(int pos,int len)453 int FileEntry::getContentNum( int pos, int len )
454 {
455 int mylen, i;
456 int res = -1;
457
458 if ( pos < 0 ) return -1;
459 if ( len < 1 ) return -1;
460
461 if ( contentBuf.content == NULL ) readContentBuf();
462 if ( contentBuf.content != NULL ) {
463 mylen = a_min( len, contentBuf.size - pos );
464 if ( mylen > 0 ) {
465 res = 0;
466 for ( i = 0; i < mylen; i++ ) {
467 res <<= 8;
468 res += (unsigned char)contentBuf.content[i+pos];
469 }
470 }
471 }
472
473 return res;
474 }
475
freeContentBuf()476 void FileEntry::freeContentBuf()
477 {
478 if ( contentBuf.content != NULL ) {
479 _freesafe( contentBuf.content );
480 contentBuf.content = NULL;
481 contentBuf.size = 0;
482 }
483 }
484
readContentBuf(int len)485 void FileEntry::readContentBuf( int len )
486 {
487 int reads, i;
488 unsigned char fbuffer[64];
489 PDatei *pfp;
490
491 if ( isReg() == false ) return;
492 if ( ( len < 1 ) || ( len > 64 ) ) return;
493 if ( contentBuf.content == NULL ) {
494 reads = -1;
495 pfp = new PDatei();
496 if ( pfp->open( fullname ) == 0 ) {
497 reads = pfp->read( fbuffer, len );
498 }
499 delete pfp;
500 if ( ( reads > 0 ) && ( reads <= len ) ) {
501 contentBuf.content = (char*)_allocsafe( len + 1 );
502 contentBuf.size = reads;
503 for ( i = 0; i < reads; i++ ) {
504 contentBuf.content[i] = (char)fbuffer[i];
505 }
506 for ( i = reads; i < ( len + 1 ); i++ ) {
507 contentBuf.content[i] = '\0';
508 }
509 }
510 }
511 }
512
freeOutputBuf()513 void FileEntry::freeOutputBuf()
514 {
515 if ( outputBuf != NULL ) {
516 delete outputBuf;
517 outputBuf = NULL;
518 }
519 }
520
findOutput(const char * tcommand)521 const char *FileEntry::findOutput( const char *tcommand )
522 {
523 if ( outputBuf == NULL ) {
524 outputBuf = new StringBuf();
525 } else {
526 return outputBuf->find( tcommand );
527 }
528 return NULL;
529 }
530
addOutput(const char * tcommand,const char * toutput,int value)531 void FileEntry::addOutput( const char *tcommand, const char *toutput, int value )
532 {
533 if ( outputBuf == NULL ) outputBuf = new StringBuf();
534
535 outputBuf->add( tcommand, toutput, value );
536 }
537
findReturnvalue(const char * tcommand,int * return_value)538 int FileEntry::findReturnvalue( const char *tcommand, int *return_value )
539 {
540 if ( outputBuf == NULL ) {
541 outputBuf = new StringBuf();
542 } else {
543 return outputBuf->findValue( tcommand, return_value );
544 }
545 return -1;
546 }
547
findOutputAndRV(const char * tcommand,const char ** return_output,int * return_value)548 int FileEntry::findOutputAndRV( const char *tcommand,
549 const char **return_output,
550 int *return_value )
551 {
552 if ( outputBuf == NULL ) {
553 outputBuf = new StringBuf();
554 } else {
555 return outputBuf->find( tcommand, return_output, return_value );
556 }
557 return -1;
558 }
559
isReg() const560 bool FileEntry::isReg() const
561 {
562 if ( isLink == false ) {
563 if ( isCorrupt == true ) return false;
564 if ( S_ISREG( statbuf.mode ) ) return true;
565 else return false;
566 }
567 if ( isCorrupt == true ) return false;
568 if ( S_ISREG( dstatbuf.mode ) ) return true;
569 return false;
570 }
571
setCustomColor(const FileEntryCustomColor & c)572 void FileEntry::setCustomColor( const FileEntryCustomColor &c )
573 {
574 m_colors.setCustomColor( c );
575 }
576
setCustomColors(const int fg[4],const int bg[4])577 void FileEntry::setCustomColors( const int fg[4], const int bg[4] )
578 {
579 m_colors.setCustomColors( fg, bg );
580 }
581
getCustomColor() const582 const FileEntryCustomColor &FileEntry::getCustomColor() const
583 {
584 return m_colors.getCustomColor();
585 }
586
getCustomColorSet() const587 int FileEntry::getCustomColorSet() const
588 {
589 return m_colors.getCustomColorSet();
590 }
591
clearCustomColor()592 void FileEntry::clearCustomColor()
593 {
594 m_colors.setCustomColorSet( 0 );
595 }
596
clearOverrideColor()597 void FileEntry::clearOverrideColor()
598 {
599 m_colors.setOverrideColorSet( 0 );
600 }
601
setColor(const FileEntryColor & c)602 void FileEntry::setColor( const FileEntryColor &c )
603 {
604 m_colors = c;
605 }
606
getColor() const607 const FileEntryColor &FileEntry::getColor() const
608 {
609 return m_colors;
610 }
611
setOverrideColor(int type,int fg,int bg)612 void FileEntry::setOverrideColor( int type, int fg, int bg )
613 {
614 m_colors.setOverrideColor( type, fg, bg );
615 }
616
617 /*
618 * Method to check for same destination file
619 * it currently only check the destination itself, not the possible
620 * destination of a symlink
621 */
isSameFile(const char * othername,bool follow_symlinks) const622 bool FileEntry::isSameFile( const char *othername, bool follow_symlinks ) const
623 {
624 worker_struct_stat buf;
625
626 if ( othername == NULL ) return false;
627 if ( worker_stat( othername, &buf ) != 0 ) return false;
628
629 if ( ( isLink == true ) && ( follow_symlinks == true ) && ( isCorrupt == false ) ) {
630 if ( ( dinode() == buf.st_ino ) && ( ddev() == buf.st_dev ) ) return true;
631 } else {
632 if ( ( inode() == buf.st_ino ) && ( dev() == buf.st_dev ) ) return true;
633 }
634 return false;
635 }
636
FileEntry(const FileEntry & other)637 FileEntry::FileEntry( const FileEntry &other )
638 {
639 fullname = ( other.fullname != NULL ) ? dupstring( other.fullname ) : NULL;
640 name = (other.name != NULL ) ? dupstring( other.name ) : NULL;
641 filetype = other.filetype;
642 use = other.use;
643 isHidden = other.isHidden;
644 reclistQueued = other.reclistQueued;
645
646 memcpy( &statbuf, &( other.statbuf ), sizeof( statbuf ) );
647 memcpy( &dstatbuf, &( other.dstatbuf ), sizeof( dstatbuf ) );
648
649 setColor( other.getColor() );
650
651 dirsize = other.dirsize;
652 select = other.select;
653 isLink = other.isLink;
654 isCorrupt = other.isCorrupt;
655
656 // not copied
657 contentBuf.content = NULL;
658 contentBuf.size = 0;
659
660 outputBuf = NULL;
661
662 _ID = other._ID;
663
664 if ( other.m_bookmark_info != NULL ) {
665 m_bookmark_info = new FEBookmarkInfo( *other.m_bookmark_info );
666 } else {
667 m_bookmark_info = NULL;
668 }
669
670 m_filetype_file_output = other.m_filetype_file_output;
671 m_mime_type = other.m_mime_type;
672 }
673
FileEntry(const NWC::FSEntry & other)674 FileEntry::FileEntry( const NWC::FSEntry &other )
675 {
676 fullname = dupstring( other.getFullname().c_str() );
677 name = dupstring( other.getBasename().c_str() );
678 filetype = nullptr;
679 use = true;
680 isHidden = other.isHiddenEntry();
681 isCorrupt = other.isBrokenLink();
682
683 reclistQueued = false;
684
685 memset( &statbuf, 0, sizeof( statbuf ) );
686 memset( &dstatbuf, 0, sizeof( dstatbuf ) );
687
688 statbuf.size = other.stat_size();
689 statbuf.lastaccess = other.stat_lastaccess();
690 statbuf.lastmod = other.stat_lastmod();
691 statbuf.lastchange = other.stat_lastchange();
692 statbuf.mode = other.stat_mode();
693 statbuf.userid = other.stat_userid();
694 statbuf.groupid = other.stat_groupid();
695 statbuf.inode = other.stat_inode();
696 statbuf.nlink = other.stat_nlink();
697 statbuf.blocks = other.stat_blocks();
698 statbuf.rdev = other.stat_rdev();
699 statbuf.dev = other.stat_dev();
700
701 dstatbuf.size = other.stat_dest_size();
702 dstatbuf.lastaccess = other.stat_dest_lastaccess();
703 dstatbuf.lastmod = other.stat_dest_lastmod();
704 dstatbuf.lastchange = other.stat_dest_lastchange();
705 dstatbuf.mode = other.stat_dest_mode();
706 dstatbuf.userid = other.stat_dest_userid();
707 dstatbuf.groupid = other.stat_dest_groupid();
708 dstatbuf.inode = other.stat_dest_inode();
709 dstatbuf.nlink = other.stat_dest_nlink();
710 dstatbuf.blocks = other.stat_dest_blocks();
711 dstatbuf.rdev = other.stat_dest_rdev();
712 dstatbuf.dev = other.stat_dest_dev();
713
714 dirsize = 0;
715 select = false;
716 isLink = other.isLink();
717
718 contentBuf.content = NULL;
719 contentBuf.size = 0;
720
721 outputBuf = NULL;
722
723 _ID = -1;
724
725 m_bookmark_info = NULL;
726 }
727
728 /*
729 * Method to test for equal fileentry
730 *
731 * Does same extented test to ensure that the fileentry
732 * is a duplicated version
733 */
equals(const FileEntry * fe) const734 bool FileEntry::equals( const FileEntry *fe ) const
735 {
736 if ( fe == NULL ) return false;
737 if ( fe == this ) return true;
738 return equals( *fe );
739 }
740
equals(const FileEntry & fe) const741 bool FileEntry::equals( const FileEntry &fe ) const
742 {
743 // require name
744 if ( ( fullname == NULL ) || ( fe.fullname == NULL ) ) return false;
745
746 // require same inode/device
747
748 //Currently disabled because AVFS can set 0
749 // if ( statbuf.inode == 0 ) return false;
750 if ( ( statbuf.inode != fe.statbuf.inode ) || ( statbuf.dev != fe.statbuf.dev ) ) return false;
751
752 // require same size
753 if ( statbuf.size != fe.statbuf.size ) return false;
754
755 // require same name
756 if ( strcmp( fullname, fe.fullname ) != 0 ) return false;
757
758 // finally require same times
759
760 // skip access time check since it might be changed by background file type check
761 // if ( statbuf.lastaccess != fe.statbuf.lastaccess ) return false;
762
763 if ( statbuf.lastmod != fe.statbuf.lastmod ) return false;
764 if ( statbuf.lastchange != fe.statbuf.lastchange ) return false;
765
766 return true;
767 }
768
getID() const769 int FileEntry::getID() const
770 {
771 return _ID;
772 }
773
setID(int ID)774 void FileEntry::setID( int ID )
775 {
776 _ID = ID;
777 }
778
setMatchingLabels(const std::list<std::string> & labels)779 void FileEntry::setMatchingLabels( const std::list<std::string> &labels )
780 {
781 if ( labels.empty() == true ) {
782 if ( m_bookmark_info != NULL ) {
783 delete m_bookmark_info;
784 m_bookmark_info = NULL;
785 }
786 } else {
787 if ( m_bookmark_info == NULL ) {
788 m_bookmark_info = new FEBookmarkInfo;
789 }
790 if ( m_bookmark_info->m_matching_labels != NULL ) delete m_bookmark_info->m_matching_labels;
791 m_bookmark_info->m_matching_labels = new std::list<std::string>( labels );
792 }
793 }
794
getMatchingLabels() const795 const std::list<std::string> &FileEntry::getMatchingLabels() const
796 {
797 if ( m_bookmark_info == NULL ) throw( 1 );
798 if ( m_bookmark_info->m_matching_labels == NULL ) throw( 1 );
799
800 return *m_bookmark_info->m_matching_labels;
801 }
802
clearMatchingLabels()803 void FileEntry::clearMatchingLabels()
804 {
805 if ( m_bookmark_info != NULL ) {
806 delete m_bookmark_info;
807 m_bookmark_info = NULL;
808 }
809 }
810
hasMatchingLabels() const811 bool FileEntry::hasMatchingLabels() const
812 {
813 if ( m_bookmark_info == NULL ) return false;
814 if ( m_bookmark_info->m_matching_labels == NULL ) return false;
815 if ( m_bookmark_info->m_matching_labels->empty() == true ) return false;
816
817 return true;
818 }
819
getBookmarkMatch() const820 FileEntry::bookmark_match_t FileEntry::getBookmarkMatch() const
821 {
822 if ( m_bookmark_info == NULL ) return FileEntry::NOT_IN_BOOKMARKS;
823 return m_bookmark_info->m_bookmark_match;
824 }
825
setBookmarkMatch(bookmark_match_t m)826 void FileEntry::setBookmarkMatch( bookmark_match_t m )
827 {
828 if ( m == NOT_IN_BOOKMARKS ) {
829 if ( m_bookmark_info != NULL ) {
830 m_bookmark_info->m_bookmark_match = m;
831 }
832 } else {
833 if ( m_bookmark_info == NULL ) {
834 m_bookmark_info = new FEBookmarkInfo;
835 }
836 m_bookmark_info->m_bookmark_match = m;
837 }
838 }
839
setFiletypeFileOutput(const std::string & output)840 void FileEntry::setFiletypeFileOutput( const std::string &output )
841 {
842 m_filetype_file_output = output;
843 }
844
getFiletypeFileOutput() const845 std::string FileEntry::getFiletypeFileOutput() const
846 {
847 return m_filetype_file_output;
848 }
849
setMimeType(const std::string & mimetype)850 void FileEntry::setMimeType( const std::string &mimetype )
851 {
852 m_mime_type = mimetype;
853 }
854
getMimeType() const855 std::string FileEntry::getMimeType() const
856 {
857 return m_mime_type;
858 }
859