Blame src/MirrorJob.h

Packit 8f70b4
/*
Packit 8f70b4
 * lftp - file transfer program
Packit 8f70b4
 *
Packit 8f70b4
 * Copyright (c) 1996-2017 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 MIRRORJOB_H
Packit 8f70b4
#define MIRRORJOB_H
Packit 8f70b4
Packit 8f70b4
#include "FileAccess.h"
Packit 8f70b4
#include "FileSet.h"
Packit 8f70b4
#include "Job.h"
Packit 8f70b4
#include "PatternSet.h"
Packit 8f70b4
#include "misc.h"
Packit 8f70b4
Packit 8f70b4
class MirrorJob : public Job
Packit 8f70b4
{
Packit 8f70b4
public:
Packit 8f70b4
   enum recursion_mode_t {
Packit 8f70b4
      RECURSION_ALWAYS,
Packit 8f70b4
      RECURSION_NEVER,
Packit 8f70b4
      RECURSION_MISSING,
Packit 8f70b4
      RECURSION_NEWER,
Packit 8f70b4
   };
Packit 8f70b4
Packit 8f70b4
private:
Packit 8f70b4
   enum state_t
Packit 8f70b4
   {
Packit 8f70b4
      INITIAL_STATE,
Packit 8f70b4
      MAKE_TARGET_DIR,
Packit 8f70b4
      CHANGING_DIR_SOURCE,
Packit 8f70b4
      CHANGING_DIR_TARGET,
Packit 8f70b4
      GETTING_LIST_INFO,
Packit 8f70b4
      WAITING_FOR_TRANSFER,
Packit 8f70b4
      TARGET_REMOVE_OLD,
Packit 8f70b4
      TARGET_REMOVE_OLD_FIRST,
Packit 8f70b4
      TARGET_CHMOD,
Packit 8f70b4
      TARGET_MKDIR,
Packit 8f70b4
      SOURCE_REMOVING_SAME,
Packit 8f70b4
      FINISHING,
Packit 8f70b4
      LAST_EXEC,
Packit 8f70b4
      DONE
Packit 8f70b4
   };
Packit 8f70b4
   state_t state;
Packit 8f70b4
Packit 8f70b4
   FileAccessRef source_session;
Packit 8f70b4
   FileAccessRef target_session;
Packit 8f70b4
   bool target_is_local;
Packit 8f70b4
   bool source_is_local;
Packit 8f70b4
Packit 8f70b4
   long long bytes_transferred;
Packit 8f70b4
   long long bytes_to_transfer;
Packit 8f70b4
Packit 8f70b4
   Ref<FileSet> target_set;
Packit 8f70b4
   Ref<FileSet> target_set_excluded;
Packit 8f70b4
   Ref<FileSet> source_set;
Packit 8f70b4
   Ref<FileSet> target_set_recursive;
Packit 8f70b4
   Ref<FileSet> source_set_recursive;
Packit 8f70b4
Packit 8f70b4
   Ref<FileSet> to_transfer;
Packit 8f70b4
   Ref<FileSet> to_mkdir;
Packit 8f70b4
   Ref<FileSet> same;
Packit 8f70b4
   Ref<FileSet> to_rm;
Packit 8f70b4
   Ref<FileSet> to_rm_mismatched;
Packit 8f70b4
   Ref<FileSet> old_files_set;
Packit 8f70b4
   Ref<FileSet> new_files_set;
Packit 8f70b4
   Ref<FileSet> to_rm_src;
Packit 8f70b4
   void InitSets(); // deduce above sets from source_set and target_set
Packit 8f70b4
   bool only_dirs;  // to_transfer (or to_mkdir) contains directories only
Packit 8f70b4
Packit 8f70b4
   void RemoveSourceLater(const FileInfo *fi) {
Packit 8f70b4
      if(!remove_source_files)
Packit 8f70b4
	 return;
Packit 8f70b4
      if(!to_rm_src)
Packit 8f70b4
	 to_rm_src=new FileSet();
Packit 8f70b4
      to_rm_src->Add(new FileInfo(*fi));
Packit 8f70b4
   }
Packit 8f70b4
Packit 8f70b4
   void AddBytesTransferred(long long b) {
Packit 8f70b4
      bytes_transferred+=b;
Packit 8f70b4
      if(parent_mirror)
Packit 8f70b4
	 parent_mirror->AddBytesTransferred(b);
Packit 8f70b4
   }
Packit 8f70b4
   void AddBytesToTransfer(long long b) {
Packit 8f70b4
      bytes_to_transfer+=b;
Packit 8f70b4
      if(parent_mirror)
Packit 8f70b4
	 parent_mirror->AddBytesToTransfer(b);
Packit 8f70b4
   }
Packit 8f70b4
Packit 8f70b4
   void	 HandleFile(FileInfo *);
Packit 8f70b4
Packit 8f70b4
   bool create_target_dir;
Packit 8f70b4
   bool	no_target_dir;	   // target directory does not exist (for script_only)
Packit 8f70b4
   bool remove_this_source_dir;
Packit 8f70b4
Packit 8f70b4
   SMTaskRef<ListInfo> source_list_info;
Packit 8f70b4
   SMTaskRef<ListInfo> target_list_info;
Packit 8f70b4
Packit 8f70b4
   xstring_c source_dir;
Packit 8f70b4
   xstring_c source_relative_dir;
Packit 8f70b4
   xstring_c target_dir;
Packit 8f70b4
   xstring_c target_relative_dir;
Packit 8f70b4
Packit 8f70b4
   struct Statistics
Packit 8f70b4
   {
Packit 8f70b4
      int tot_files,new_files,mod_files,del_files;
Packit 8f70b4
      int dirs,del_dirs;
Packit 8f70b4
      int tot_symlinks,new_symlinks,mod_symlinks,del_symlinks;
Packit 8f70b4
      int error_count;
Packit 8f70b4
      long long bytes;
Packit 8f70b4
      double time;
Packit 8f70b4
      Statistics();
Packit 8f70b4
      void Reset();
Packit 8f70b4
      void Add(const Statistics &);
Packit 8f70b4
      bool HaveSomethingDone(unsigned mirror_flags);
Packit 8f70b4
   };
Packit 8f70b4
   Statistics stats;
Packit 8f70b4
Packit 8f70b4
   double transfer_time_elapsed;
Packit 8f70b4
   TimeDate transfer_start_ts;
Packit 8f70b4
Packit 8f70b4
   /* root_transfer_count is the global counter in the root mirror,
Packit 8f70b4
    * and weight of a non-root mirror in global transfer_count otherwise. */
Packit 8f70b4
   int	 root_transfer_count;
Packit 8f70b4
Packit 8f70b4
   unsigned flags;
Packit 8f70b4
   recursion_mode_t recursion_mode;
Packit 8f70b4
   int	 max_error_count;
Packit 8f70b4
Packit 8f70b4
   Ref<PatternSet> top_exclude;
Packit 8f70b4
   Ref<PatternSet> my_exclude;
Packit 8f70b4
   const PatternSet *exclude;
Packit 8f70b4
Packit 8f70b4
   bool	 create_remote_dir;
Packit 8f70b4
Packit 8f70b4
   void	 Report(const char *fmt,...) PRINTF_LIKE(2,3);
Packit 8f70b4
   void	 va_Report(const char *fmt,va_list v);
Packit 8f70b4
   int	 verbose_report;
Packit 8f70b4
   MirrorJob *parent_mirror;
Packit 8f70b4
   MirrorJob *root_mirror;
Packit 8f70b4
Packit 8f70b4
   time_t newer_than;
Packit 8f70b4
   time_t older_than;
Packit 8f70b4
   Ref<Range> my_size_range;
Packit 8f70b4
   const Range *size_range;
Packit 8f70b4
Packit 8f70b4
   xstring_c script_name;
Packit 8f70b4
   FILE *script;
Packit 8f70b4
   bool script_only;
Packit 8f70b4
   bool script_needs_closing;
Packit 8f70b4
   bool use_cache;
Packit 8f70b4
   bool remove_source_files;
Packit 8f70b4
   bool remove_source_dirs;
Packit 8f70b4
   bool skip_noaccess;
Packit 8f70b4
Packit 8f70b4
   int parallel;
Packit 8f70b4
   int pget_n;
Packit 8f70b4
   int pget_minchunk;
Packit 8f70b4
Packit 8f70b4
   xstring_c on_change;
Packit 8f70b4
Packit 8f70b4
   mode_t get_mode_mask();
Packit 8f70b4
Packit 8f70b4
   int source_redirections;
Packit 8f70b4
   int target_redirections;
Packit 8f70b4
Packit 8f70b4
   void HandleChdir(FileAccessRef& session, int &redirections);
Packit 8f70b4
   void HandleListInfoCreation(const FileAccessRef& session,SMTaskRef<ListInfo>& list_info,
Packit 8f70b4
	    const char *relative_dir);
Packit 8f70b4
   void HandleListInfo(SMTaskRef<ListInfo>& list_info,Ref<FileSet>& set,Ref<FileSet> *fsx=0);
Packit 8f70b4
Packit 8f70b4
   void MirrorStarted();
Packit 8f70b4
   void MirrorFinished();
Packit 8f70b4
   void TransferStarted(class CopyJob *cp);
Packit 8f70b4
   void JobStarted(Job *j);
Packit 8f70b4
   void TransferFinished(Job *j);
Packit 8f70b4
   void JobFinished(Job *j);
Packit 8f70b4
Packit 8f70b4
   off_t GetBytesCount();
Packit 8f70b4
   double GetTimeSpent();
Packit 8f70b4
Packit 8f70b4
public:
Packit 8f70b4
   enum
Packit 8f70b4
   {
Packit 8f70b4
      ALLOW_SUID=1<<0,
Packit 8f70b4
      DELETE=1<<1,
Packit 8f70b4
      NO_RECURSION=1<<2,
Packit 8f70b4
      ONLY_NEWER=1<<3,
Packit 8f70b4
      NO_PERMS=1<<4,
Packit 8f70b4
      CONTINUE=1<<5,
Packit 8f70b4
      REPORT_NOT_DELETED=1<<6,
Packit 8f70b4
      RETR_SYMLINKS=1<<7,
Packit 8f70b4
      NO_UMASK=1<<8,
Packit 8f70b4
      ALLOW_CHOWN=1<<9,
Packit 8f70b4
      IGNORE_TIME=1<<10,
Packit 8f70b4
      REMOVE_FIRST=1<<11,
Packit 8f70b4
      IGNORE_SIZE=1<<12,
Packit 8f70b4
      NO_SYMLINKS=1<<13,
Packit 8f70b4
      LOOP=1<<14,
Packit 8f70b4
      ONLY_EXISTING=1<<15,
Packit 8f70b4
      NO_EMPTY_DIRS=1<<16,
Packit 8f70b4
      DEPTH_FIRST=1<<17,
Packit 8f70b4
      ASCII=1<<18,
Packit 8f70b4
      SCAN_ALL_FIRST=1<<19,
Packit 8f70b4
      OVERWRITE=1<<20,
Packit 8f70b4
      UPLOAD_OLDER=1<<21,
Packit 8f70b4
      TRANSFER_ALL=1<<22,
Packit 8f70b4
      TARGET_FLAT=1<<23,
Packit 8f70b4
      DELETE_EXCLUDED=1<<24,
Packit 8f70b4
   };
Packit 8f70b4
   void SetFlags(unsigned f,bool v)
Packit 8f70b4
   {
Packit 8f70b4
      if(v)
Packit 8f70b4
	 flags|=f;
Packit 8f70b4
      else
Packit 8f70b4
	 flags&=~f;
Packit 8f70b4
   }
Packit 8f70b4
   bool FlagsSet(unsigned f)   const { return (flags&f)==f; }
Packit 8f70b4
   bool FlagSet(unsigned f)    const { return (flags&f); }
Packit 8f70b4
   bool AnyFlagSet(unsigned f) const { return (flags&f); }
Packit 8f70b4
Packit 8f70b4
   MirrorJob(MirrorJob *parent,FileAccess *f,FileAccess *target,
Packit 8f70b4
      const char *new_source_dir,const char *new_target_dir);
Packit 8f70b4
   ~MirrorJob();
Packit 8f70b4
Packit 8f70b4
   int	 Do();
Packit 8f70b4
   int	 Done() { return state==DONE; }
Packit 8f70b4
   void	 ShowRunStatus(const SMTaskRef<StatusLine>&);
Packit 8f70b4
   xstring& FormatStatus(xstring&,int v,const char *);
Packit 8f70b4
   xstring& FormatShortStatus(xstring&);
Packit 8f70b4
   void	 SayFinal() { PrintStatus(0,""); }
Packit 8f70b4
   int	 ExitCode() { return stats.error_count!=0; }
Packit 8f70b4
Packit 8f70b4
   void	 SetExclude(PatternSet *x) { my_exclude=x; exclude=my_exclude; }
Packit 8f70b4
   void	 SetExclude(const PatternSet *x) { exclude=x; }
Packit 8f70b4
   void	 SetSizeRange(Range *r) { my_size_range=r; size_range=my_size_range; }
Packit 8f70b4
   void	 SetSizeRange(const Range *r) { size_range=r; }
Packit 8f70b4
   void	 SetTopExclude(PatternSet *x) { top_exclude=x; }
Packit 8f70b4
Packit 8f70b4
   void	 SetVerbose(int v) { verbose_report=v; }
Packit 8f70b4
Packit 8f70b4
   void	 CreateRemoteDir() { create_remote_dir=true; }
Packit 8f70b4
Packit 8f70b4
   void	 SetNewerThan(const char *file);
Packit 8f70b4
   void	 SetOlderThan(const char *file);
Packit 8f70b4
Packit 8f70b4
   void  UseCache(bool u) { use_cache=u; }
Packit 8f70b4
   void	 RemoveSourceFiles() { remove_source_files=true; }
Packit 8f70b4
   void	 RemoveSourceDirs() { remove_source_files=remove_source_dirs=true; }
Packit 8f70b4
   void	 SkipNoAccess() { skip_noaccess=true; }
Packit 8f70b4
Packit 8f70b4
   void  SetParallel(int p) { parallel=p; }
Packit 8f70b4
   void  SetPGet(int n) { pget_n=n; }
Packit 8f70b4
Packit 8f70b4
   void Fg();
Packit 8f70b4
   void Bg();
Packit 8f70b4
Packit 8f70b4
   const char *SetRecursionMode(const char *r);
Packit 8f70b4
   const char *SetScriptFile(const char *n);
Packit 8f70b4
   void	 ScriptOnly(bool yes=true)
Packit 8f70b4
      {
Packit 8f70b4
	 script_only=yes;
Packit 8f70b4
      }
Packit 8f70b4
   void SetMaxErrorCount(int ec) { max_error_count=ec; }
Packit 8f70b4
   void SetOnChange(const char *oc);
Packit 8f70b4
   static const char *AddPattern(Ref<PatternSet>& exclude,char opt,const char *optarg);
Packit 8f70b4
   static const char *AddPatternsFrom(Ref<PatternSet>& exclude,char opt,const char *file);
Packit 8f70b4
};
Packit 8f70b4
Packit 8f70b4
#endif//MIRRORJOB_H