Changeset 2663


Ignore:
Timestamp:
08/03/2010 22:00:55 (2 years ago)
Author:
chris
Message:

Merge [2604] [2612] [2613] [2614] [2618] [2633] [2634] [2635] [2636]
from trunk into 0.11rc7. Fix updating of changed file attributes
(creation time) on Windows, fixes #64 in 0.11rc7.

Location:
box/RELEASE/0.11rc7
Files:
11 edited
1 copied

Legend:

Unmodified
Added
Removed
  • box/RELEASE/0.11rc7/bin/bbackupd/BackupClientDirectoryRecord.cpp

    r2594 r2663  
    614614                // Explict decryption 
    615615                BackupClientFileAttributes storeAttr(storeAttrEnc); 
     616                 
    616617                // Compare the attributes 
    617                 if(attr.Compare(storeAttr, true, true /* ignore both modification times */)) 
     618                if(attr.Compare(storeAttr, true, 
     619                        true /* ignore both modification times */)) 
    618620                { 
    619621                        // No update necessary 
     
    10491051                                try 
    10501052                                { 
     1053                                        rNotifier.NotifyFileUploadingAttributes( 
     1054                                                this, filename); 
     1055                                         
    10511056                                        // Update store 
    10521057                                        BackupClientFileAttributes attr; 
  • box/RELEASE/0.11rc7/bin/bbackupd/BackupDaemon.h

    r2413 r2663  
    445445                }  
    446446        } 
     447        virtual void NotifyFileUploadingAttributes( 
     448                const BackupClientDirectoryRecord* pDirRecord, 
     449                const std::string& rLocalPath)  
     450        { 
     451                if (mLogAllFileAccess) 
     452                { 
     453                        BOX_NOTICE("Uploading new file attributes: " <<  
     454                                rLocalPath); 
     455                }  
     456        } 
    447457        virtual void NotifyFileUploaded( 
    448458                const BackupClientDirectoryRecord* pDirRecord, 
  • box/RELEASE/0.11rc7/bin/bbackupd/BackupDaemonInterface.h

    r2414 r2663  
    124124                const BackupClientDirectoryRecord* pDirRecord, 
    125125                const std::string& rLocalPath) = 0; 
     126        virtual void NotifyFileUploadingAttributes( 
     127                const BackupClientDirectoryRecord* pDirRecord, 
     128                const std::string& rLocalPath) = 0; 
    126129        virtual void NotifyFileUploaded( 
    127130                const BackupClientDirectoryRecord* pDirRecord, 
  • box/RELEASE/0.11rc7/bin/bbackupquery/BackupQueries.cpp

    r2661 r2663  
    213213                { "quit", "" }, 
    214214                { "exit", "" }, 
    215                 { "list", "rodIFtTsh", }, 
     215                { "list", "rodIFtTash", }, 
    216216                { "pwd",  "" }, 
    217217                { "cd",   "od" }, 
     
    398398        #define LIST_OPTION_TIMES_LOCAL         't' 
    399399        #define LIST_OPTION_TIMES_UTC           'T' 
     400        #define LIST_OPTION_TIMES_ATTRIBS       'a' 
    400401        #define LIST_OPTION_SIZEINBLOCKS        's' 
    401402        #define LIST_OPTION_DISPLAY_HASH        'h' 
     
    436437} 
    437438 
     439static std::string GetTimeString(BackupStoreDirectory::Entry& en, 
     440        bool useLocalTime, bool showAttrModificationTimes) 
     441{ 
     442        std::ostringstream out; 
     443        box_time_t originalTime, newAttributesTime; 
     444 
     445        // there is no attribute modification time in the directory 
     446        // entry, unfortunately, so we can't display it. 
     447        originalTime = en.GetModificationTime(); 
     448        out << BoxTimeToISO8601String(originalTime, useLocalTime); 
     449 
     450        if(en.HasAttributes()) 
     451        { 
     452                const StreamableMemBlock &storeAttr(en.GetAttributes()); 
     453                BackupClientFileAttributes attr(storeAttr); 
     454                 
     455                box_time_t NewModificationTime, NewAttrModificationTime; 
     456                attr.GetModificationTimes(&NewModificationTime, 
     457                        &NewAttrModificationTime); 
     458                 
     459                if (showAttrModificationTimes) 
     460                { 
     461                        newAttributesTime = NewAttrModificationTime; 
     462                } 
     463                else 
     464                { 
     465                        newAttributesTime = NewModificationTime; 
     466                } 
     467                 
     468                if (newAttributesTime == originalTime) 
     469                { 
     470                        out << "*"; 
     471                } 
     472                else 
     473                { 
     474                        out << "~" << BoxTimeToISO8601String(newAttributesTime, 
     475                                useLocalTime); 
     476                } 
     477        } 
     478        else 
     479        { 
     480                out << " "; 
     481        } 
     482         
     483        return out.str(); 
     484} 
    438485 
    439486// -------------------------------------------------------------------------- 
     
    535582                { 
    536583                        // Show UTC times... 
    537                         std::string time = BoxTimeToISO8601String( 
    538                                 en->GetModificationTime(), false); 
    539                         printf("%s ", time.c_str()); 
     584                        printf("%s ", GetTimeString(*en, false, 
     585                                opts[LIST_OPTION_TIMES_ATTRIBS]).c_str()); 
    540586                } 
    541587 
     
    543589                { 
    544590                        // Show local times... 
    545                         std::string time = BoxTimeToISO8601String( 
    546                                 en->GetModificationTime(), true); 
    547                         printf("%s ", time.c_str()); 
     591                        printf("%s ", GetTimeString(*en, true, 
     592                                opts[LIST_OPTION_TIMES_ATTRIBS]).c_str()); 
    548593                } 
    549594                 
  • box/RELEASE/0.11rc7/bin/bbackupquery/bbackupquery.cpp

    r2493 r2663  
    6161void PrintUsageAndExit() 
    6262{ 
    63         printf("Usage: bbackupquery [-q] [-w] " 
     63        printf("Usage: bbackupquery [-q*|v*|V|W<level>] [-w] " 
    6464#ifdef WIN32 
    6565        "[-u] " 
     
    124124 
    125125#ifdef WIN32 
    126         const char* validOpts = "qvwuc:l:o:O:W:"; 
     126        const char* validOpts = "qvVwuc:l:o:O:W:"; 
    127127        bool unicodeConsole = false; 
    128128#else 
    129         const char* validOpts = "qvwc:l:o:O:W:"; 
     129        const char* validOpts = "qvVwc:l:o:O:W:"; 
    130130#endif 
    131131 
     
    139139                switch(c) 
    140140                { 
    141                         case 'q': 
     141                case 'q': 
    142142                        { 
    143143                                if(masterLevel == Log::NOTHING) 
     
    152152                        break; 
    153153 
    154                         case 'v': 
     154                case 'v': 
    155155                        { 
    156156                                if(masterLevel == Log::EVERYTHING) 
     
    162162                                } 
    163163                                masterLevel++; 
     164                        } 
     165                        break; 
     166 
     167                case 'V': 
     168                        { 
     169                                masterLevel = Log::EVERYTHING; 
    164170                        } 
    165171                        break; 
  • box/RELEASE/0.11rc7/lib/backupclient/BackupClientFileAttributes.cpp

    r2493 r2663  
    7979{ 
    8080        int32_t uid, gid, mode; 
     81        #ifdef WIN32 
     82        int64_t fileCreationTime; 
     83        #endif 
    8184} attributeHashData; 
    8285 
     
    222225// Function 
    223226//              Name:    BackupClientFileAttributes::Compare(const BackupClientFileAttributes &, bool) 
    224 //              Purpose: Compare, optionally ignoring the attribute modification time and/or modification time, and some data which is 
    225 //                               irrelevant in practise (eg file generation number) 
     227//              Purpose: Compare, optionally ignoring the attribute 
     228//                       modification time and/or modification time, and some 
     229//                       data which is irrelevant in practise (eg file 
     230//                       generation number) 
    226231//              Created: 10/12/03 
    227232// 
    228233// -------------------------------------------------------------------------- 
    229 bool BackupClientFileAttributes::Compare(const BackupClientFileAttributes &rAttr, bool IgnoreAttrModTime, bool IgnoreModTime) const 
     234bool BackupClientFileAttributes::Compare(const BackupClientFileAttributes &rAttr, 
     235        bool IgnoreAttrModTime, bool IgnoreModTime) const 
    230236{ 
    231237        EnsureClearAvailable(); 
     
    235241        if(mpClearAttributes->GetSize() != rAttr.mpClearAttributes->GetSize()) 
    236242        { 
     243                BOX_TRACE("Attribute Compare: Attributes objects are " 
     244                        "different sizes, cannot compare them: local " << 
     245                        mpClearAttributes->GetSize() << " bytes, remote " << 
     246                        rAttr.mpClearAttributes->GetSize() << " bytes"); 
    237247                return false; 
    238248        } 
     
    242252        attr_StreamFormat *a1 = (attr_StreamFormat*)mpClearAttributes->GetBuffer(); 
    243253        attr_StreamFormat *a2 = (attr_StreamFormat*)rAttr.mpClearAttributes->GetBuffer(); 
    244          
    245         if(a1->AttributeType != a2->AttributeType 
    246                 || a1->UID != a2->UID 
    247                 || a1->GID != a2->GID 
    248                 || a1->UserDefinedFlags != a2->UserDefinedFlags 
    249                 || a1->Mode != a2->Mode) 
    250         { 
    251                 return false; 
    252         } 
    253          
     254 
     255        #define COMPARE(attribute, message) \ 
     256        if (a1->attribute != a2->attribute) \ 
     257        { \ 
     258                BOX_TRACE("Attribute Compare: " << message << " differ: " \ 
     259                        "local "  << ntoh(a1->attribute) << ", " \ 
     260                        "remote " << ntoh(a2->attribute)); \ 
     261                return false; \ 
     262        } 
     263        COMPARE(AttributeType, "Attribute types"); 
     264        COMPARE(UID, "UIDs"); 
     265        COMPARE(GID, "GIDs"); 
     266        COMPARE(UserDefinedFlags, "User-defined flags"); 
     267        COMPARE(Mode, "Modes"); 
     268 
    254269        if(!IgnoreModTime) 
    255270        { 
    256                 int t1 = a1->ModificationTime / 1000000; 
    257                 int t2 = a2->ModificationTime / 1000000; 
    258                 if(t1 != t2) 
    259                 { 
     271                uint64_t t1 = box_ntoh64(a1->ModificationTime); 
     272                uint64_t t2 = box_ntoh64(a2->ModificationTime); 
     273                time_t s1 = BoxTimeToSeconds(t1); 
     274                time_t s2 = BoxTimeToSeconds(t2); 
     275                if(s1 != s2) 
     276                { 
     277                        BOX_TRACE("Attribute Compare: File modification " 
     278                                "times differ: local " << 
     279                                FormatTime(t1, true) << " (" << s1 << "), " 
     280                                "remote " << 
     281                                FormatTime(t2, true) << " (" << s2 << ")"); 
    260282                        return false; 
    261283                } 
    262284        } 
    263  
     285         
    264286        if(!IgnoreAttrModTime) 
    265287        { 
    266                 int t1 = a1->AttrModificationTime / 1000000; 
    267                 int t2 = a2->AttrModificationTime / 1000000; 
    268                 if(t1 != t2) 
    269                 { 
     288                uint64_t t1 = box_ntoh64(a1->AttrModificationTime); 
     289                uint64_t t2 = box_ntoh64(a2->AttrModificationTime); 
     290                time_t s1 = BoxTimeToSeconds(t1); 
     291                time_t s2 = BoxTimeToSeconds(t2); 
     292                if(s1 != s2) 
     293                { 
     294                        BOX_TRACE("Attribute Compare: Attribute modification " 
     295                                "times differ: local " << 
     296                                FormatTime(t1, true) << " (" << s1 << "), " 
     297                                "remote " << 
     298                                FormatTime(t2, true) << " (" << s2 << ")"); 
    270299                        return false; 
    271300                } 
     
    277306        { 
    278307                // Symlink strings don't match. This also compares xattrs 
    279                 if(::memcmp(a1 + 1, a2 + 1, size - sizeof(attr_StreamFormat)) != 0) 
    280                 { 
     308                int datalen = size - sizeof(attr_StreamFormat); 
     309 
     310                if(::memcmp(a1 + 1, a2 + 1, datalen) != 0) 
     311                { 
     312                        std::string s1((char *)(a1 + 1), datalen); 
     313                        std::string s2((char *)(a2 + 1), datalen); 
     314                        BOX_TRACE("Attribute Compare: Symbolic link target " 
     315                                "or extended attributes differ: " 
     316                                "local "  << PrintEscapedBinaryData(s1) << ", " 
     317                                "remote " << PrintEscapedBinaryData(s2)); 
    281318                        return false; 
    282319                } 
     
    604641} 
    605642 
     643// -------------------------------------------------------------------------- 
     644// 
     645// Function 
     646//              Name:    BackupClientFileAttributes::GetModificationTimes() 
     647//              Purpose: Returns the modification time embedded in the 
     648//                       attributes. 
     649//              Created: 2010/02/24 
     650// 
     651// -------------------------------------------------------------------------- 
     652void BackupClientFileAttributes::GetModificationTimes( 
     653        box_time_t *pModificationTime, 
     654        box_time_t *pAttrModificationTime) const 
     655{ 
     656        // Got something loaded 
     657        if(GetSize() <= 0) 
     658        { 
     659                THROW_EXCEPTION(BackupStoreException, AttributesNotLoaded); 
     660        } 
     661         
     662        // Make sure there are clear attributes to use 
     663        EnsureClearAvailable(); 
     664        ASSERT(mpClearAttributes != 0); 
     665 
     666        // Check if the decrypted attributes are small enough, and the type of attributes stored 
     667        if(mpClearAttributes->GetSize() < (int)sizeof(int32_t)) 
     668        { 
     669                THROW_EXCEPTION(BackupStoreException, AttributesNotUnderstood); 
     670        } 
     671        int32_t *type = (int32_t*)mpClearAttributes->GetBuffer(); 
     672        ASSERT(type != 0); 
     673        if(ntohl(*type) != ATTRIBUTETYPE_GENERIC_UNIX) 
     674        { 
     675                // Don't know what to do with these 
     676                THROW_EXCEPTION(BackupStoreException, AttributesNotUnderstood); 
     677        } 
     678         
     679        // Check there is enough space for an attributes block 
     680        if(mpClearAttributes->GetSize() < (int)sizeof(attr_StreamFormat)) 
     681        { 
     682                // Too small 
     683                THROW_EXCEPTION(BackupStoreException, AttributesNotLoaded); 
     684        } 
     685 
     686        // Get pointer to structure 
     687        attr_StreamFormat *pattr = (attr_StreamFormat*)mpClearAttributes->GetBuffer(); 
     688 
     689        if(pModificationTime) 
     690        { 
     691                *pModificationTime = box_ntoh64(pattr->ModificationTime); 
     692        } 
     693         
     694        if(pAttrModificationTime) 
     695        { 
     696                *pAttrModificationTime = box_ntoh64(pattr->AttrModificationTime); 
     697        } 
     698} 
    606699 
    607700// -------------------------------------------------------------------------- 
     
    10331126// 
    10341127// Function 
    1035 //              Name:    BackupClientFileAttributes::GenerateAttributeHash(struct stat &, const std::string &, const std::string &) 
    1036 //              Purpose: Generate a 64 bit hash from the attributes, used to detect changes. 
    1037 //                               Include filename in the hash, so that it changes from one file to another, 
    1038 //                               so don't reveal identical attributes. 
     1128//              Name:    BackupClientFileAttributes::GenerateAttributeHash( 
     1129//                       struct stat &, const std::string &, 
     1130//                       const std::string &) 
     1131//              Purpose: Generate a 64 bit hash from the attributes, used to 
     1132//                       detect changes. Include filename in the hash, so 
     1133//                       that it changes from one file to another, so don't 
     1134//                       reveal identical attributes. 
    10391135//              Created: 25/4/04 
    10401136// 
    10411137// -------------------------------------------------------------------------- 
    1042 uint64_t BackupClientFileAttributes::GenerateAttributeHash(EMU_STRUCT_STAT &st, const std::string &filename, const std::string &leafname) 
     1138uint64_t BackupClientFileAttributes::GenerateAttributeHash(EMU_STRUCT_STAT &st, 
     1139        const std::string &filename, const std::string &leafname) 
    10431140{ 
    10441141        if(sAttributeHashSecretLength == 0) 
     
    10551152        hashData.mode = htonl(st.st_mode); 
    10561153 
     1154        #ifdef WIN32 
     1155        // On Windows, the "file attribute modification time" is the 
     1156        // file creation time, and we want to back this up, restore 
     1157        // it and compare it. 
     1158        // 
     1159        // On other platforms, it's not very important and can't 
     1160        // reliably be set to anything other than the current time. 
     1161        hashData.fileCreationTime = box_hton64(st.st_ctime); 
     1162        #endif 
     1163 
    10571164        StreamableMemBlock xattr; 
    10581165        FillExtendedAttr(xattr, filename.c_str()); 
     
    10631170        digest.Add(xattr.GetBuffer(), xattr.GetSize()); 
    10641171        digest.Add(leafname.c_str(), leafname.size()); 
    1065         digest.Add(sAttributeHashSecret, sAttributeHashSecretLength); 
     1172        digest.Add(sAttributeHashSecret, sAttributeHashSecretLength);    
    10661173        digest.Finish(); 
    10671174         
  • box/RELEASE/0.11rc7/lib/backupclient/BackupClientFileAttributes.h

    r2460 r2663  
    4848        void WriteAttributes(const char *Filename,  
    4949                bool MakeUserWritable = false) const; 
    50  
     50        void GetModificationTimes(box_time_t *pModificationTime, 
     51                box_time_t *pAttrModificationTime) const; 
     52         
    5153        bool IsSymLink() const; 
    5254 
  • box/RELEASE/0.11rc7/lib/common/Box.h

    r2662 r2663  
    164164#endif 
    165165 
     166// overloaded auto-conversion functions 
     167inline uint64_t hton(uint64_t in) { return box_hton64(in); } 
     168inline uint32_t hton(uint32_t in) { return htonl(in); } 
     169inline uint16_t hton(uint16_t in) { return htons(in); } 
     170inline uint8_t  hton(uint8_t in)  { return in; } 
     171inline int64_t  hton(int64_t in)  { return box_hton64(in); } 
     172inline int32_t  hton(int32_t in)  { return htonl(in); } 
     173inline int16_t  hton(int16_t in)  { return htons(in); } 
     174inline int8_t   hton(int8_t in)   { return in; } 
     175inline uint64_t ntoh(uint64_t in) { return box_ntoh64(in); } 
     176inline uint32_t ntoh(uint32_t in) { return ntohl(in); } 
     177inline uint16_t ntoh(uint16_t in) { return ntohs(in); } 
     178inline uint8_t  ntoh(uint8_t in)  { return in; } 
     179inline int64_t  ntoh(int64_t in)  { return box_ntoh64(in); } 
     180inline int32_t  ntoh(int32_t in)  { return ntohl(in); } 
     181inline int16_t  ntoh(int16_t in)  { return ntohs(in); } 
     182inline int8_t   ntoh(int8_t in)   { return in; } 
     183 
    166184#endif // BOX__H 
    167185 
  • box/RELEASE/0.11rc7/lib/common/FileModificationTime.h

    r2460 r2663  
    1515#include "BoxTime.h" 
    1616 
    17 inline box_time_t FileModificationTime(EMU_STRUCT_STAT &st) 
    18 { 
    19 #ifndef HAVE_STRUCT_STAT_ST_MTIMESPEC 
    20         box_time_t datamodified = ((int64_t)st.st_mtime) * (MICRO_SEC_IN_SEC_LL); 
    21 #else 
    22         box_time_t datamodified = (((int64_t)st.st_mtimespec.tv_nsec) / NANO_SEC_IN_USEC_LL) 
    23                         + (((int64_t)st.st_mtimespec.tv_sec) * (MICRO_SEC_IN_SEC_LL)); 
    24 #endif 
    25          
    26         return datamodified; 
    27 } 
    28  
    29 inline box_time_t FileAttrModificationTime(EMU_STRUCT_STAT &st) 
    30 { 
    31         box_time_t statusmodified = 
    32 #ifdef HAVE_STRUCT_STAT_ST_MTIMESPEC 
    33                 (((int64_t)st.st_ctimespec.tv_nsec) / (NANO_SEC_IN_USEC_LL)) + 
    34                 (((int64_t)st.st_ctimespec.tv_sec)  * (MICRO_SEC_IN_SEC_LL)); 
    35 #elif defined HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC 
    36                 (((int64_t)st.st_ctim.tv_nsec) / (NANO_SEC_IN_USEC_LL)) + 
    37                 (((int64_t)st.st_ctim.tv_sec)  * (MICRO_SEC_IN_SEC_LL)); 
    38 #elif defined HAVE_STRUCT_STAT_ST_ATIMENSEC 
    39                 (((int64_t)st.st_ctimensec) / (NANO_SEC_IN_USEC_LL)) + 
    40                 (((int64_t)st.st_ctime)     * (MICRO_SEC_IN_SEC_LL)); 
    41 #else // no nanoseconds anywhere 
    42                 (((int64_t)st.st_ctime) * (MICRO_SEC_IN_SEC_LL)); 
    43 #endif 
    44          
    45         return statusmodified; 
    46 } 
    47  
    48 inline box_time_t FileModificationTimeMaxModAndAttr(EMU_STRUCT_STAT &st) 
    49 { 
    50 #ifndef HAVE_STRUCT_STAT_ST_MTIMESPEC 
    51         box_time_t datamodified = ((int64_t)st.st_mtime) * (MICRO_SEC_IN_SEC_LL); 
    52         box_time_t statusmodified = ((int64_t)st.st_ctime) * (MICRO_SEC_IN_SEC_LL); 
    53 #else 
    54         box_time_t datamodified = (((int64_t)st.st_mtimespec.tv_nsec) / NANO_SEC_IN_USEC_LL) 
    55                         + (((int64_t)st.st_mtimespec.tv_sec) * (MICRO_SEC_IN_SEC_LL)); 
    56         box_time_t statusmodified = (((int64_t)st.st_ctimespec.tv_nsec) / NANO_SEC_IN_USEC_LL) 
    57                         + (((int64_t)st.st_ctimespec.tv_sec) * (MICRO_SEC_IN_SEC_LL)); 
    58 #endif 
    59          
    60         return (datamodified > statusmodified)?datamodified:statusmodified; 
    61 } 
     17box_time_t FileModificationTime(EMU_STRUCT_STAT &st); 
     18box_time_t FileAttrModificationTime(EMU_STRUCT_STAT &st); 
     19box_time_t FileModificationTimeMaxModAndAttr(EMU_STRUCT_STAT &st); 
    6220 
    6321#endif // FILEMODIFICATIONTIME__H 
  • box/RELEASE/0.11rc7/lib/common/Logging.cpp

    r2546 r2663  
    496496        return true; 
    497497} 
     498 
     499std::string PrintEscapedBinaryData(const std::string& rInput) 
     500{ 
     501        std::ostringstream output; 
     502 
     503        for (size_t i = 0; i < rInput.length(); i++) 
     504        { 
     505                if (isprint(rInput[i])) 
     506                { 
     507                        output << rInput[i]; 
     508                } 
     509                else 
     510                { 
     511                        output << "\\x" << std::hex << std::setw(2) << 
     512                                std::setfill('0') << (int) rInput[i] << 
     513                                std::dec; 
     514                } 
     515        } 
     516 
     517        return output.str(); 
     518} 
  • box/RELEASE/0.11rc7/lib/common/Logging.h

    r2544 r2663  
    1818 
    1919#include "FileStream.h" 
    20  
    21 /* 
    22 #define BOX_LOG(level, stuff) \ 
    23 { \ 
    24     if(Log::sMaxLoggingLevelForAnyOutput >= level) \ 
    25         std::ostringstream line; \ 
    26         line << stuff; \ 
    27         Log::Write(level, __FILE__, __LINE__, line.str()); \ 
    28     } \ 
    29 } 
    30 */ 
    3120 
    3221#define BOX_LOG(level, stuff) \ 
     
    5342        { BOX_LOG(Log::TRACE, stuff) } 
    5443 
     44#define BOX_SYS_ERROR(stuff) \ 
     45        stuff << ": " << std::strerror(errno) << " (" << errno << ")" 
     46 
    5547#define BOX_LOG_SYS_WARNING(stuff) \ 
    56         BOX_WARNING(stuff << ": " << std::strerror(errno) << " (" << errno << ")") 
     48        BOX_WARNING(BOX_SYS_ERROR(stuff)) 
    5749#define BOX_LOG_SYS_ERROR(stuff) \ 
    58         BOX_ERROR(stuff << ": " << std::strerror(errno) << " (" << errno << ")") 
     50        BOX_ERROR(BOX_SYS_ERROR(stuff)) 
    5951#define BOX_LOG_SYS_FATAL(stuff) \ 
    60         BOX_FATAL(stuff << ": " << std::strerror(errno) << " (" << errno << ")") 
     52        BOX_FATAL(BOX_SYS_ERROR(stuff)) 
     53 
     54#define LOG_AND_THROW_ERROR(message, filename, exception, subtype) \ 
     55        BOX_LOG_SYS_ERROR(message << ": " << filename); \ 
     56        THROW_EXCEPTION_MESSAGE(exception, subtype, \ 
     57                BOX_SYS_ERROR(message << ": " << filename)); 
    6158 
    6259inline std::string GetNativeErrorMessage() 
     
    340337}; 
    341338 
     339std::string PrintEscapedBinaryData(const std::string& rInput); 
     340 
    342341#endif // LOGGING__H 
Note: See TracChangeset for help on using the changeset viewer.