source: box/trunk/bin/bbackupquery/BackupQueries.h @ 3103

Revision 3103, 11.8 KB checked in by chris, 4 weeks ago (diff)

Change BackupQueries? List() to use C++ streams for output.

  • Property svn:eol-style set to native
Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    BackupQueries.h
5//              Purpose: Perform various queries on the backup store server.
6//              Created: 2003/10/10
7//
8// --------------------------------------------------------------------------
9
10#ifndef BACKUPQUERIES__H
11#define BACKUPQUERIES__H
12
13#include <iostream>
14#include <string>
15#include <vector>
16
17#include "BoxTime.h"
18#include "BoxBackupCompareParams.h"
19#include "BackupStoreDirectory.h"
20
21class BackupProtocolClient;
22class Configuration;
23class ExcludeList;
24
25typedef enum
26{
27        Command_Unknown = 0,
28        Command_Quit,
29        Command_List,
30        Command_pwd,
31        Command_cd,
32        Command_lcd,
33        Command_sh,
34        Command_GetObject,
35        Command_Get,
36        Command_Compare,
37        Command_Restore,
38        Command_Help,
39        Command_Usage,
40        Command_Undelete,
41        Command_Delete,
42}
43CommandType;
44
45struct QueryCommandSpecification;
46
47// --------------------------------------------------------------------------
48//
49// Class
50//              Name:    BackupQueries
51//              Purpose: Perform various queries on the backup store server.
52//              Created: 2003/10/10
53//
54// --------------------------------------------------------------------------
55class BackupQueries
56{
57public:
58        BackupQueries(BackupProtocolClient &rConnection,
59                const Configuration &rConfiguration,
60                bool readWrite);
61        ~BackupQueries();
62private:
63        BackupQueries(const BackupQueries &);
64public:
65        struct ParsedCommand
66        {
67                std::vector<std::string> mCmdElements;
68                std::string mOptions;
69                std::string mCompleteCommand;
70                bool mInOptions, mFailed;
71                QueryCommandSpecification* pSpec;
72                // mArgCount is the same as mCmdElements.size() for a complete
73                // command, but if the command line ends in a space,
74                // e.g. during readline parsing, it can be one greater,
75                // to indicate that we should complete the next item instead.
76                size_t mArgCount;
77                ParsedCommand(const std::string& Command,
78                        bool isFromCommandLine);
79        };
80
81        void DoCommand(ParsedCommand& rCommand);
82
83        // Ready to stop?
84        bool Stop() {return mQuitNow;}
85       
86        // Return code?
87        int GetReturnCode() {return mReturnCode;}
88
89        void List(int64_t DirID, const std::string &rListRoot, const bool *opts,
90                bool FirstLevel, std::ostream &out = std::cout);
91        void CommandList(const std::vector<std::string> &args, const bool *opts);
92
93private:
94        // Commands
95        void CommandChangeDir(const std::vector<std::string> &args, const bool *opts);
96        void CommandChangeLocalDir(const std::vector<std::string> &args);
97        void CommandGetObject(const std::vector<std::string> &args, const bool *opts);
98        void CommandGet(std::vector<std::string> args, const bool *opts);
99        void CommandCompare(const std::vector<std::string> &args, const bool *opts);
100        void CommandRestore(const std::vector<std::string> &args, const bool *opts);
101        void CommandUndelete(const std::vector<std::string> &args, const bool *opts);
102        void CommandDelete(const std::vector<std::string> &args,
103                const bool *opts);
104        void CommandUsage(const bool *opts);
105        void CommandUsageDisplayEntry(const char *Name, int64_t Size,
106                int64_t HardLimit, int32_t BlockSize, bool MachineReadable);
107        void CommandHelp(const std::vector<std::string> &args);
108
109public:
110        class CompareParams : public BoxBackupCompareParams
111        {
112        public:
113                CompareParams(bool QuickCompare, bool IgnoreExcludes,
114                        bool IgnoreAttributes, box_time_t LatestFileUploadTime);
115               
116                bool mQuietCompare;
117                int mDifferences;
118                int mDifferencesExplainedByModTime;
119                int mUncheckedFiles;
120                int mExcludedDirs;
121                int mExcludedFiles;
122
123                std::string ConvertForConsole(const std::string& rUtf8String)
124                {
125                #ifdef WIN32
126                        std::string output;
127                       
128                        if(!ConvertUtf8ToConsole(rUtf8String.c_str(), output))
129                        {
130                                BOX_WARNING("Character set conversion failed "
131                                        "on string: " << rUtf8String);
132                                return rUtf8String;
133                        }
134                       
135                        return output;
136                #else
137                        return rUtf8String;
138                #endif
139                }
140
141                virtual void NotifyLocalDirMissing(const std::string& rLocalPath,
142                        const std::string& rRemotePath)
143                {
144                        BOX_WARNING("Local directory '" <<
145                                ConvertForConsole(rLocalPath) << "' "
146                                "does not exist, but remote directory does.");
147                        mDifferences ++;
148                }
149               
150                virtual void NotifyLocalDirAccessFailed(
151                        const std::string& rLocalPath,
152                        const std::string& rRemotePath)
153                {
154                        BOX_LOG_SYS_WARNING("Failed to access local directory "
155                                "'" << ConvertForConsole(rLocalPath) << "'");
156                        mUncheckedFiles ++;
157                }
158
159                virtual void NotifyStoreDirMissingAttributes(
160                        const std::string& rLocalPath,
161                        const std::string& rRemotePath)
162                {
163                        BOX_WARNING("Store directory '" <<
164                                ConvertForConsole(rRemotePath) << "' "
165                                "doesn't have attributes.");
166                }
167
168                virtual void NotifyRemoteFileMissing(
169                        const std::string& rLocalPath,
170                        const std::string& rRemotePath,
171                        bool modifiedAfterLastSync)
172                {
173                        BOX_WARNING("Local file '" <<
174                                ConvertForConsole(rLocalPath) << "' " 
175                                "exists, but remote file '" <<
176                                ConvertForConsole(rRemotePath) << "' "
177                                "does not.");
178                        mDifferences ++;
179                       
180                        if(modifiedAfterLastSync)
181                        {
182                                mDifferencesExplainedByModTime ++;
183                                BOX_INFO("(the file above was modified after "
184                                        "the last sync time -- might be "
185                                        "reason for difference)");
186                        }
187                }
188
189                virtual void NotifyLocalFileMissing(
190                        const std::string& rLocalPath,
191                        const std::string& rRemotePath)
192                {
193                        BOX_WARNING("Remote file '" <<
194                                ConvertForConsole(rRemotePath) << "' " 
195                                "exists, but local file '" <<
196                                ConvertForConsole(rLocalPath) << "' does not.");
197                        mDifferences ++;
198                }
199
200                virtual void NotifyExcludedFileNotDeleted(
201                        const std::string& rLocalPath,
202                        const std::string& rRemotePath)
203                {
204                        BOX_WARNING("Local file '" <<
205                                ConvertForConsole(rLocalPath) << "' " 
206                                "is excluded, but remote file '" <<
207                                ConvertForConsole(rRemotePath) << "' "
208                                "still exists.");
209                        mDifferences ++;
210                }
211               
212                virtual void NotifyDownloadFailed(const std::string& rLocalPath,
213                        const std::string& rRemotePath, int64_t NumBytes,
214                        BoxException& rException)
215                {
216                        BOX_ERROR("Failed to download remote file '" <<
217                                ConvertForConsole(rRemotePath) << "': " <<
218                                rException.what() << " (" <<
219                                rException.GetType() << "/" <<
220                                rException.GetSubType() << ")");
221                        mUncheckedFiles ++;
222                }
223
224                virtual void NotifyDownloadFailed(const std::string& rLocalPath,
225                        const std::string& rRemotePath, int64_t NumBytes,
226                        std::exception& rException)
227                {
228                        BOX_ERROR("Failed to download remote file '" <<
229                                ConvertForConsole(rRemotePath) << "': " <<
230                                rException.what());
231                        mUncheckedFiles ++;
232                }
233
234                virtual void NotifyDownloadFailed(const std::string& rLocalPath,
235                        const std::string& rRemotePath, int64_t NumBytes)
236                {
237                        BOX_ERROR("Failed to download remote file '" <<
238                                ConvertForConsole(rRemotePath));
239                        mUncheckedFiles ++;
240                }
241
242                virtual void NotifyLocalFileReadFailed(const std::string& rLocalPath,
243                        const std::string& rRemotePath, int64_t NumBytes,
244                        std::exception& rException)
245                {
246                        BOX_ERROR("Failed to read local file '" <<
247                                ConvertForConsole(rLocalPath) << "': " <<
248                                rException.what());
249                        mUncheckedFiles ++;
250                }
251
252                virtual void NotifyLocalFileReadFailed(const std::string& rLocalPath,
253                        const std::string& rRemotePath, int64_t NumBytes)
254                {
255                        BOX_ERROR("Failed to read local file '" <<
256                                ConvertForConsole(rLocalPath));
257                        mUncheckedFiles ++;
258                }
259
260                virtual void NotifyExcludedFile(const std::string& rLocalPath,
261                        const std::string& rRemotePath)
262                {
263                        mExcludedFiles ++;
264                }
265
266                virtual void NotifyExcludedDir(const std::string& rLocalPath,
267                        const std::string& rRemotePath)
268                {
269                        mExcludedDirs ++;
270                }
271
272                virtual void NotifyDirComparing(const std::string& rLocalPath,
273                        const std::string& rRemotePath)
274                {
275                }
276
277                virtual void NotifyDirCompared(
278                        const std::string& rLocalPath,
279                        const std::string& rRemotePath,
280                        bool HasDifferentAttributes,
281                        bool modifiedAfterLastSync)
282                {
283                        if(HasDifferentAttributes)
284                        {
285                                BOX_WARNING("Local directory '" <<
286                                        ConvertForConsole(rLocalPath) << "' "
287                                        "has different attributes to "
288                                        "store directory '" <<
289                                        ConvertForConsole(rRemotePath) << "'.");
290                                mDifferences ++;
291                               
292                                if(modifiedAfterLastSync)
293                                {
294                                        mDifferencesExplainedByModTime ++;
295                                        BOX_INFO("(the directory above was "
296                                                "modified after the last sync "
297                                                "time -- might be reason for "
298                                                "difference)");
299                                }
300                        }
301                }
302
303                virtual void NotifyFileComparing(const std::string& rLocalPath,
304                        const std::string& rRemotePath)
305                {
306                }
307               
308                virtual void NotifyFileCompared(const std::string& rLocalPath,
309                        const std::string& rRemotePath, int64_t NumBytes,
310                        bool HasDifferentAttributes, bool HasDifferentContents,
311                        bool ModifiedAfterLastSync, bool NewAttributesApplied)
312                {
313                        int NewDifferences = 0;
314                       
315                        if(HasDifferentAttributes)
316                        {
317                                BOX_WARNING("Local file '" <<
318                                        ConvertForConsole(rLocalPath) << "' "
319                                        "has different attributes to "
320                                        "store file '" <<
321                                        ConvertForConsole(rRemotePath) << "'.");
322                                NewDifferences ++;
323                        }
324
325                        if(HasDifferentContents)
326                        {
327                                BOX_WARNING("Local file '" <<
328                                        ConvertForConsole(rLocalPath) << "' "
329                                        "has different contents to "
330                                        "store file '" <<
331                                        ConvertForConsole(rRemotePath) << "'.");
332                                NewDifferences ++;
333                        }
334                       
335                        if(HasDifferentAttributes || HasDifferentContents)
336                        {
337                                if(ModifiedAfterLastSync)
338                                {
339                                        mDifferencesExplainedByModTime +=
340                                                NewDifferences;
341                                        BOX_INFO("(the file above was modified "
342                                                "after the last sync time -- "
343                                                "might be reason for difference)");
344                                }
345                                else if(NewAttributesApplied)
346                                {
347                                        BOX_INFO("(the file above has had new "
348                                                "attributes applied)\n");
349                                }
350                        }
351                       
352                        mDifferences += NewDifferences;
353                }
354        };
355        void CompareLocation(const std::string &rLocation,
356                BoxBackupCompareParams &rParams);
357        void Compare(const std::string &rStoreDir,
358                const std::string &rLocalDir, BoxBackupCompareParams &rParams);
359        void Compare(int64_t DirID, const std::string &rStoreDir,
360                const std::string &rLocalDir, BoxBackupCompareParams &rParams);
361        void CompareOneFile(int64_t DirID, BackupStoreDirectory::Entry *pEntry,
362                const std::string& rLocalPath, const std::string& rStorePath,
363                BoxBackupCompareParams &rParams);
364
365public:
366
367        class ReturnCode
368        {
369                public:
370                typedef enum {
371                        Command_OK = 0,
372                        Compare_Same = 1,
373                        Compare_Different,
374                        Compare_Error,
375                        Command_Error,
376                } Type;
377        };
378
379        // Were private, but needed by completion functions:
380        int64_t GetCurrentDirectoryID();
381        int64_t FindDirectoryObjectID(const std::string &rDirName,
382                bool AllowOldVersion = false, bool AllowDeletedDirs = false,
383                std::vector<std::pair<std::string, int64_t> > *pStack = 0);
384
385private:
386
387        // Utility functions
388        int64_t FindFileID(const std::string& rNameOrIdString,
389                const bool *opts, int64_t *pDirIdOut,
390                std::string* pFileNameOut, int16_t flagsInclude,
391                int16_t flagsExclude, int16_t* pFlagsOut);
392        std::string GetCurrentDirectoryName();
393        void SetReturnCode(int code) {mReturnCode = code;}
394
395private:
396        bool mReadWrite;
397        BackupProtocolClient &mrConnection;
398        const Configuration &mrConfiguration;
399        bool mQuitNow;
400        std::vector<std::pair<std::string, int64_t> > mDirStack;
401        bool mRunningAsRoot;
402        bool mWarnedAboutOwnerAttributes;
403        int mReturnCode;
404};
405
406typedef std::vector<std::string> (*CompletionHandler)
407        (BackupQueries::ParsedCommand& rCommand, const std::string& prefix,
408        BackupProtocolClient& rProtocol, const Configuration& rConfig,
409        BackupQueries& rQueries);
410
411std::vector<std::string> CompleteCommand(BackupQueries::ParsedCommand& rCommand,
412        const std::string& prefix, BackupProtocolClient& rProtocol,
413        const Configuration& rConfig, BackupQueries& rQueries);
414std::vector<std::string> CompleteOptions(BackupQueries::ParsedCommand& rCommand,
415        const std::string& prefix, BackupProtocolClient& rProtocol,
416        const Configuration& rConfig, BackupQueries& rQueries);
417
418#define MAX_COMPLETION_HANDLERS 4
419
420struct QueryCommandSpecification
421{
422        const char* name;
423        const char* opts;
424        CommandType type;
425        CompletionHandler complete[MAX_COMPLETION_HANDLERS];
426};
427
428// Data about commands
429extern QueryCommandSpecification commands[];
430
431extern const char *alias[];
432extern const int aliasIs[];
433
434#define LIST_OPTION_ALLOWOLD            'o'
435#define LIST_OPTION_ALLOWDELETED        'd'
436
437#endif // BACKUPQUERIES__H
438
Note: See TracBrowser for help on using the repository browser.