1 /* 2 * lftp - file transfer program 3 * 4 * Copyright (c) 1996-2016 by Alexander V. Lukyanov (lav@yars.free.net) 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef FILESET_H 21 #define FILESET_H 22 23 #include <sys/types.h> 24 #include "xarray.h" 25 26 #undef TYPE 27 28 class TimeInterval; 29 class Range; 30 31 #define NO_SIZE ((off_t)-1L) 32 #define NO_SIZE_YET ((off_t)-2L) 33 #define NO_DATE ((time_t)-1L) 34 #define NO_DATE_YET ((time_t)-2L) 35 36 struct FileTimestamp 37 { 38 time_t ts; 39 int ts_prec; FileTimestampFileTimestamp40 FileTimestamp() : ts(NO_DATE_YET), ts_prec(0) {} setFileTimestamp41 void set(time_t ts1,int ts1_prec) { ts=ts1; ts_prec=ts1_prec; } is_setFileTimestamp42 bool is_set() { return ts!=NO_DATE && ts!=NO_DATE_YET; } time_tFileTimestamp43 operator time_t() const { return ts; } 44 time_t operator=(time_t t) { set(t,0); return t; } 45 }; 46 47 class FileInfo 48 { def(unsigned m)49 void def(unsigned m) { defined|=m; need&=~m; } 50 public: 51 xstring name; 52 xstring longname; 53 xstring_c symlink; 54 xstring_c uri; 55 mode_t mode; 56 FileTimestamp date; 57 off_t size; 58 xstring data; 59 const char *user, *group; 60 int nlinks; 61 62 enum type 63 { 64 UNKNOWN=0, 65 DIRECTORY, 66 SYMLINK, 67 NORMAL, 68 REDIRECT, 69 }; 70 type filetype; 71 72 enum defined_bits 73 { 74 NAME=001,MODE=002,DATE=004,TYPE=010,SYMLINK_DEF=020, 75 SIZE=0100,USER=0200,GROUP=0400,NLINKS=01000, 76 77 IGNORE_SIZE_IF_OLDER=02000, // for ignore mask 78 IGNORE_DATE_IF_OLDER=04000, // for ignore mask 79 80 ALL_INFO=NAME|MODE|DATE|TYPE|SYMLINK_DEF|SIZE|USER|GROUP|NLINKS 81 }; 82 unsigned defined; 83 unsigned need; 84 85 int rank; 86 87 void Init(); FileInfo()88 FileInfo() { Init(); } 89 FileInfo(const FileInfo &fi); FileInfo(const char * n)90 FileInfo(const char *n) { Init(); SetName(n); } FileInfo(const xstring & n)91 FileInfo(const xstring& n) { Init(); SetName(n); } 92 ~FileInfo(); 93 SetName(const char * n)94 void SetName(const char *n) { name.set(n); def(NAME); } SetName(const xstring & n)95 void SetName(const xstring& n) { name.set(n); def(NAME); } 96 void SetUser(const char *n); 97 void SetGroup(const char *n); 98 void LocalFile(const char *name, bool follow_symlinks); 99 static FileInfo *parse_ls_line(const char *line,int line_len,const char *tz); parse_ls_line(const char * line,const char * tz)100 static FileInfo *parse_ls_line(const char *line,const char *tz) { return parse_ls_line(line,strlen(line),tz); } 101 SetMode(mode_t m)102 void SetMode(mode_t m) { mode=m; def(MODE); } SetDate(time_t t,int prec)103 void SetDate(time_t t,int prec) { date.set(t,prec); def(DATE); } SetType(type t)104 void SetType(type t) { filetype=t; def(TYPE); } SetSymlink(const char * s)105 void SetSymlink(const char *s) { symlink.set(s); filetype=SYMLINK; def(TYPE|SYMLINK_DEF); } SetRedirect(const char * s)106 void SetRedirect(const char *s) { symlink.set(s); filetype=REDIRECT; def(TYPE|SYMLINK_DEF); } GetRedirect()107 const char *GetRedirect() const { return symlink; } SetSize(off_t s)108 void SetSize(off_t s) { size=s; def(SIZE); } SetNlink(int n)109 void SetNlink(int n) { nlinks=n; def(NLINKS); } 110 111 void Merge(const FileInfo&); 112 void MergeInfo(const FileInfo& f,unsigned mask); 113 114 bool SameAs(const FileInfo *,int ignore) const; 115 bool OlderThan(time_t t) const; 116 bool NewerThan(time_t t) const; 117 bool NotOlderThan(time_t t) const; 118 bool NotNewerThan(time_t t) const; 119 bool SizeOutside(const Range *r) const; TypeIs(type t)120 bool TypeIs(type t) const { return (defined&TYPE) && filetype==t; } 121 SetAssociatedData(const void * d,int len)122 void SetAssociatedData(const void *d,int len) { data.nset((const char*)d,len); } GetAssociatedData()123 const void *GetAssociatedData() const { return data; } 124 SetRank(int r)125 void SetRank(int r) { rank=r; } GetRank()126 int GetRank() const { return rank; } 127 void MakeLongName(); SetLongName(const char * s)128 void SetLongName(const char *s) { longname.set(s); } GetLongName()129 const char *GetLongName() { if(!longname) MakeLongName(); return longname; } 130 131 operator const char *() const { return name; } 132 Has(unsigned m)133 bool Has(unsigned m) const { return defined&m; } HasAny(unsigned m)134 bool HasAny(unsigned m) const { return defined&m; } HasAll(unsigned m)135 bool HasAll(unsigned m) const { return (defined&m)==m; } 136 Need(unsigned m)137 void Need(unsigned m) { need|=m; } NoNeed(unsigned m)138 void NoNeed(unsigned m) { need&=~m; } 139 }; 140 141 class PatternSet; 142 143 class FileSet 144 { 145 public: 146 enum sort_e { BYNAME, BYSIZE, DIRSFIRST, BYRANK, BYDATE, BYNAME_FLAT }; 147 148 private: 149 RefArray<FileInfo> files; 150 151 /* indexes when sort != NAME: */ 152 xarray<int> sorted; 153 sort_e sort_mode; 154 155 int ind; 156 157 void Sub(int); 158 FileInfo *Borrow(int); 159 160 void add_before(int pos,FileInfo *fi); 161 void assert_sorted() const; 162 163 public: 164 FileSet(); 165 FileSet(const FileSet *s); 166 ~FileSet(); 167 168 void Empty(); 169 get_fnum()170 int get_fnum() const { return files.count(); } count()171 int count() const { return files.count(); } curr_index()172 int curr_index() const { return ind; } curr_pct()173 int curr_pct() const { return count()==0 ? 100 : ind*100/count(); } 174 175 void Add(FileInfo *); 176 void Merge(const FileSet *); 177 void Merge_insert(const FileSet *set); 178 void SubtractSame(const FileSet *,int ignore); 179 void SubtractAny(const FileSet *); 180 void SubtractTimeCmp(bool (FileInfo::*cmp)(time_t) const,time_t); SubtractOlderThan(time_t t)181 void SubtractOlderThan(time_t t) { SubtractTimeCmp(&FileInfo::OlderThan,t); } SubtractNewerThan(time_t t)182 void SubtractNewerThan(time_t t) { SubtractTimeCmp(&FileInfo::NewerThan,t); } SubtractNotOlderThan(time_t t)183 void SubtractNotOlderThan(time_t t) { SubtractTimeCmp(&FileInfo::NotOlderThan,t); } SubtractNotNewerThan(time_t t)184 void SubtractNotNewerThan(time_t t) { SubtractTimeCmp(&FileInfo::NotNewerThan,t); } 185 void SubtractSizeOutside(const Range *r); 186 void SubtractDirs(); 187 void SubtractNotDirs(); 188 void SubtractNotIn(const FileSet *); 189 void SubtractSameType(const FileSet *); 190 void SubtractDirs(const FileSet *); 191 void SubtractNotOlderDirs(const FileSet *); 192 void SubtractCurr(); 193 bool SubtractByName(const char *name); 194 void Sort(sort_e newsort, bool casefold=false, bool reverse=false); 195 void Unsort(); 196 void SortByPatternList(const char *list_c); 197 void ReverseSort(); 198 void UnsortFlat(); 199 200 void Exclude(const char *prefix,const PatternSet *x,FileSet *fsx=0); 201 void ExcludeDots(); 202 void ExcludeCompound(); 203 void ExcludeUnaccessible(const char *user=0); 204 rewind()205 void rewind() { ind=0; } 206 FileInfo *curr(); 207 FileInfo *next(); borrow_curr()208 FileInfo *borrow_curr() { return Borrow(ind--); } 209 210 void LocalRemove(const char *dir); 211 void LocalUtime(const char *dir,bool only_dirs=false,bool flat=false); 212 void LocalChmod(const char *dir,mode_t mask=0,bool flat=false); 213 void LocalChown(const char *dir,bool flat=false); 214 215 void Count(int *d,int *f,int *s,int *o) const; 216 void CountBytes(long long *b) const; 217 218 int FindGEIndByName(const char *name) const; 219 FileInfo *FindByName(const char *name) const; 220 SetSize(const char * name,off_t size)221 void SetSize(const char *name,off_t size) 222 { 223 FileInfo *f=FindByName(name); 224 if(f) 225 f->SetSize(size); 226 } SetDate(const char * name,time_t date,int prec)227 void SetDate(const char *name,time_t date,int prec) 228 { 229 FileInfo *f=FindByName(name); 230 if(f) 231 f->SetDate(date,prec); 232 } 233 234 /* add a path to all files */ 235 void PrependPath(const char *path); 236 237 /* get all defined_bits used by this fileset */ 238 int Have() const; 239 240 FileInfo * operator[](int i) const; 241 242 size_t EstimateMemory() const; 243 void Dump(const char *tag) const; 244 }; 245 246 #endif // FILESET_H 247