|
Packit |
8f70b4 |
/*
|
|
Packit |
8f70b4 |
* lftp - file transfer program
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* Copyright (c) 1996-2016 by Alexander V. Lukyanov (lav@yars.free.net)
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is free software; you can redistribute it and/or modify
|
|
Packit |
8f70b4 |
* it under the terms of the GNU General Public License as published by
|
|
Packit |
8f70b4 |
* the Free Software Foundation; either version 3 of the License, or
|
|
Packit |
8f70b4 |
* (at your option) any later version.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
8f70b4 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
8f70b4 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
8f70b4 |
* GNU General Public License for more details.
|
|
Packit |
8f70b4 |
*
|
|
Packit |
8f70b4 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
8f70b4 |
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
8f70b4 |
*/
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#ifndef FILESET_H
|
|
Packit |
8f70b4 |
#define FILESET_H
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#include <sys/types.h>
|
|
Packit |
8f70b4 |
#include "xarray.h"
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#undef TYPE
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
class TimeInterval;
|
|
Packit |
8f70b4 |
class Range;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#define NO_SIZE ((off_t)-1L)
|
|
Packit |
8f70b4 |
#define NO_SIZE_YET ((off_t)-2L)
|
|
Packit |
8f70b4 |
#define NO_DATE ((time_t)-1L)
|
|
Packit |
8f70b4 |
#define NO_DATE_YET ((time_t)-2L)
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
struct FileTimestamp
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
time_t ts;
|
|
Packit |
8f70b4 |
int ts_prec;
|
|
Packit |
8f70b4 |
FileTimestamp() : ts(NO_DATE_YET), ts_prec(0) {}
|
|
Packit |
8f70b4 |
void set(time_t ts1,int ts1_prec) { ts=ts1; ts_prec=ts1_prec; }
|
|
Packit |
8f70b4 |
bool is_set() { return ts!=NO_DATE && ts!=NO_DATE_YET; }
|
|
Packit |
8f70b4 |
operator time_t() const { return ts; }
|
|
Packit |
8f70b4 |
time_t operator=(time_t t) { set(t,0); return t; }
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
class FileInfo
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
void def(unsigned m) { defined|=m; need&=~m; }
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
xstring name;
|
|
Packit |
8f70b4 |
xstring longname;
|
|
Packit |
8f70b4 |
xstring_c symlink;
|
|
Packit |
8f70b4 |
xstring_c uri;
|
|
Packit |
8f70b4 |
mode_t mode;
|
|
Packit |
8f70b4 |
FileTimestamp date;
|
|
Packit |
8f70b4 |
off_t size;
|
|
Packit |
8f70b4 |
xstring data;
|
|
Packit |
8f70b4 |
const char *user, *group;
|
|
Packit |
8f70b4 |
int nlinks;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
enum type
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
UNKNOWN=0,
|
|
Packit |
8f70b4 |
DIRECTORY,
|
|
Packit |
8f70b4 |
SYMLINK,
|
|
Packit |
8f70b4 |
NORMAL,
|
|
Packit |
8f70b4 |
REDIRECT,
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
type filetype;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
enum defined_bits
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
NAME=001,MODE=002,DATE=004,TYPE=010,SYMLINK_DEF=020,
|
|
Packit |
8f70b4 |
SIZE=0100,USER=0200,GROUP=0400,NLINKS=01000,
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
IGNORE_SIZE_IF_OLDER=02000, // for ignore mask
|
|
Packit |
8f70b4 |
IGNORE_DATE_IF_OLDER=04000, // for ignore mask
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
ALL_INFO=NAME|MODE|DATE|TYPE|SYMLINK_DEF|SIZE|USER|GROUP|NLINKS
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
unsigned defined;
|
|
Packit |
8f70b4 |
unsigned need;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int rank;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Init();
|
|
Packit |
8f70b4 |
FileInfo() { Init(); }
|
|
Packit |
8f70b4 |
FileInfo(const FileInfo &fi);
|
|
Packit |
8f70b4 |
FileInfo(const char *n) { Init(); SetName(n); }
|
|
Packit |
8f70b4 |
FileInfo(const xstring& n) { Init(); SetName(n); }
|
|
Packit |
8f70b4 |
~FileInfo();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SetName(const char *n) { name.set(n); def(NAME); }
|
|
Packit |
8f70b4 |
void SetName(const xstring& n) { name.set(n); def(NAME); }
|
|
Packit |
8f70b4 |
void SetUser(const char *n);
|
|
Packit |
8f70b4 |
void SetGroup(const char *n);
|
|
Packit |
8f70b4 |
void LocalFile(const char *name, bool follow_symlinks);
|
|
Packit |
8f70b4 |
static FileInfo *parse_ls_line(const char *line,int line_len,const char *tz);
|
|
Packit |
8f70b4 |
static FileInfo *parse_ls_line(const char *line,const char *tz) { return parse_ls_line(line,strlen(line),tz); }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SetMode(mode_t m) { mode=m; def(MODE); }
|
|
Packit |
8f70b4 |
void SetDate(time_t t,int prec) { date.set(t,prec); def(DATE); }
|
|
Packit |
8f70b4 |
void SetType(type t) { filetype=t; def(TYPE); }
|
|
Packit |
8f70b4 |
void SetSymlink(const char *s) { symlink.set(s); filetype=SYMLINK; def(TYPE|SYMLINK_DEF); }
|
|
Packit |
8f70b4 |
void SetRedirect(const char *s) { symlink.set(s); filetype=REDIRECT; def(TYPE|SYMLINK_DEF); }
|
|
Packit |
8f70b4 |
const char *GetRedirect() const { return symlink; }
|
|
Packit |
8f70b4 |
void SetSize(off_t s) { size=s; def(SIZE); }
|
|
Packit |
8f70b4 |
void SetNlink(int n) { nlinks=n; def(NLINKS); }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Merge(const FileInfo&);
|
|
Packit |
8f70b4 |
void MergeInfo(const FileInfo& f,unsigned mask);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool SameAs(const FileInfo *,int ignore) const;
|
|
Packit |
8f70b4 |
bool OlderThan(time_t t) const;
|
|
Packit |
8f70b4 |
bool NewerThan(time_t t) const;
|
|
Packit |
8f70b4 |
bool NotOlderThan(time_t t) const;
|
|
Packit |
8f70b4 |
bool NotNewerThan(time_t t) const;
|
|
Packit |
8f70b4 |
bool SizeOutside(const Range *r) const;
|
|
Packit |
8f70b4 |
bool TypeIs(type t) const { return (defined&TYPE) && filetype==t; }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SetAssociatedData(const void *d,int len) { data.nset((const char*)d,len); }
|
|
Packit |
8f70b4 |
const void *GetAssociatedData() const { return data; }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SetRank(int r) { rank=r; }
|
|
Packit |
8f70b4 |
int GetRank() const { return rank; }
|
|
Packit |
8f70b4 |
void MakeLongName();
|
|
Packit |
8f70b4 |
void SetLongName(const char *s) { longname.set(s); }
|
|
Packit |
8f70b4 |
const char *GetLongName() { if(!longname) MakeLongName(); return longname; }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
operator const char *() const { return name; }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
bool Has(unsigned m) const { return defined&m; }
|
|
Packit |
8f70b4 |
bool HasAny(unsigned m) const { return defined&m; }
|
|
Packit |
8f70b4 |
bool HasAll(unsigned m) const { return (defined&m)==m; }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Need(unsigned m) { need|=m; }
|
|
Packit |
8f70b4 |
void NoNeed(unsigned m) { need&=~m; }
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
class PatternSet;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
class FileSet
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
enum sort_e { BYNAME, BYSIZE, DIRSFIRST, BYRANK, BYDATE, BYNAME_FLAT };
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
private:
|
|
Packit |
8f70b4 |
RefArray<FileInfo> files;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
/* indexes when sort != NAME: */
|
|
Packit |
8f70b4 |
xarray<int> sorted;
|
|
Packit |
8f70b4 |
sort_e sort_mode;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int ind;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Sub(int);
|
|
Packit |
8f70b4 |
FileInfo *Borrow(int);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void add_before(int pos,FileInfo *fi);
|
|
Packit |
8f70b4 |
void assert_sorted() const;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
public:
|
|
Packit |
8f70b4 |
FileSet();
|
|
Packit |
8f70b4 |
FileSet(const FileSet *s);
|
|
Packit |
8f70b4 |
~FileSet();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Empty();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int get_fnum() const { return files.count(); }
|
|
Packit |
8f70b4 |
int count() const { return files.count(); }
|
|
Packit |
8f70b4 |
int curr_index() const { return ind; }
|
|
Packit |
8f70b4 |
int curr_pct() const { return count()==0 ? 100 : ind*100/count(); }
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Add(FileInfo *);
|
|
Packit |
8f70b4 |
void Merge(const FileSet *);
|
|
Packit |
8f70b4 |
void Merge_insert(const FileSet *set);
|
|
Packit |
8f70b4 |
void SubtractSame(const FileSet *,int ignore);
|
|
Packit |
8f70b4 |
void SubtractAny(const FileSet *);
|
|
Packit |
8f70b4 |
void SubtractTimeCmp(bool (FileInfo::*cmp)(time_t) const,time_t);
|
|
Packit |
8f70b4 |
void SubtractOlderThan(time_t t) { SubtractTimeCmp(&FileInfo::OlderThan,t); }
|
|
Packit |
8f70b4 |
void SubtractNewerThan(time_t t) { SubtractTimeCmp(&FileInfo::NewerThan,t); }
|
|
Packit |
8f70b4 |
void SubtractNotOlderThan(time_t t) { SubtractTimeCmp(&FileInfo::NotOlderThan,t); }
|
|
Packit |
8f70b4 |
void SubtractNotNewerThan(time_t t) { SubtractTimeCmp(&FileInfo::NotNewerThan,t); }
|
|
Packit |
8f70b4 |
void SubtractSizeOutside(const Range *r);
|
|
Packit |
8f70b4 |
void SubtractDirs();
|
|
Packit |
8f70b4 |
void SubtractNotDirs();
|
|
Packit |
8f70b4 |
void SubtractNotIn(const FileSet *);
|
|
Packit |
8f70b4 |
void SubtractSameType(const FileSet *);
|
|
Packit |
8f70b4 |
void SubtractDirs(const FileSet *);
|
|
Packit |
8f70b4 |
void SubtractNotOlderDirs(const FileSet *);
|
|
Packit |
8f70b4 |
void SubtractCurr();
|
|
Packit |
8f70b4 |
void Sort(sort_e newsort, bool casefold=false, bool reverse=false);
|
|
Packit |
8f70b4 |
void Unsort();
|
|
Packit |
8f70b4 |
void SortByPatternList(const char *list_c);
|
|
Packit |
8f70b4 |
void ReverseSort();
|
|
Packit |
8f70b4 |
void UnsortFlat();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Exclude(const char *prefix,const PatternSet *x,FileSet *fsx=0);
|
|
Packit |
8f70b4 |
void ExcludeDots();
|
|
Packit |
8f70b4 |
void ExcludeCompound();
|
|
Packit |
8f70b4 |
void ExcludeUnaccessible(const char *user=0);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void rewind() { ind=0; }
|
|
Packit |
8f70b4 |
FileInfo *curr();
|
|
Packit |
8f70b4 |
FileInfo *next();
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void LocalRemove(const char *dir);
|
|
Packit |
8f70b4 |
void LocalUtime(const char *dir,bool only_dirs=false,bool flat=false);
|
|
Packit |
8f70b4 |
void LocalChmod(const char *dir,mode_t mask=0,bool flat=false);
|
|
Packit |
8f70b4 |
void LocalChown(const char *dir,bool flat=false);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void Count(int *d,int *f,int *s,int *o) const;
|
|
Packit |
8f70b4 |
void CountBytes(long long *b) const;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
int FindGEIndByName(const char *name) const;
|
|
Packit |
8f70b4 |
FileInfo *FindByName(const char *name) const;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
void SetSize(const char *name,off_t size)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
FileInfo *f=FindByName(name);
|
|
Packit |
8f70b4 |
if(f)
|
|
Packit |
8f70b4 |
f->SetSize(size);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
void SetDate(const char *name,time_t date,int prec)
|
|
Packit |
8f70b4 |
{
|
|
Packit |
8f70b4 |
FileInfo *f=FindByName(name);
|
|
Packit |
8f70b4 |
if(f)
|
|
Packit |
8f70b4 |
f->SetDate(date,prec);
|
|
Packit |
8f70b4 |
}
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
/* add a path to all files */
|
|
Packit |
8f70b4 |
void PrependPath(const char *path);
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
/* get all defined_bits used by this fileset */
|
|
Packit |
8f70b4 |
int Have() const;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
FileInfo * operator[](int i) const;
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
size_t EstimateMemory() const;
|
|
Packit |
8f70b4 |
void Dump(const char *tag) const;
|
|
Packit |
8f70b4 |
};
|
|
Packit |
8f70b4 |
|
|
Packit |
8f70b4 |
#endif // FILESET_H
|