Changeset 710
- Timestamp:
- 28/07/2006 00:18:35 (6 years ago)
- Location:
- box/chris/merge
- Files:
-
- 3 deleted
- 57 edited
- 1 copied
-
bin/bbackupctl/bbackupctl.cpp (modified) (5 diffs)
-
bin/bbackupd/BackupClientContext.cpp (modified) (1 diff)
-
bin/bbackupd/BackupClientDirectoryRecord.cpp (modified) (2 diffs)
-
bin/bbackupd/BackupDaemon.cpp (modified) (20 diffs)
-
bin/bbackupd/BackupDaemon.h (modified) (2 diffs)
-
bin/bbackupd/Win32BackupService.cpp (modified) (2 diffs)
-
bin/bbackupd/Win32BackupService.h (modified) (1 diff)
-
bin/bbackupd/Win32ServiceFunctions.cpp (modified) (10 diffs)
-
bin/bbackupd/Win32ServiceFunctions.h (modified) (1 diff)
-
bin/bbackupd/bbackupd.cpp (modified) (4 diffs)
-
bin/bbackupquery/BackupQueries.cpp (modified) (23 diffs)
-
bin/bbackupquery/BackupQueries.h (modified) (1 diff)
-
bin/bbackupquery/documentation.txt (modified) (1 diff)
-
bin/bbstored/BBStoreDHousekeeping.cpp (modified) (5 diffs)
-
bin/bbstored/BackupCommands.cpp (modified) (6 diffs)
-
bin/bbstored/BackupContext.cpp (modified) (4 diffs)
-
bin/bbstored/BackupStoreDaemon.cpp (modified) (6 diffs)
-
bin/bbstored/BackupStoreDaemon.h (modified) (4 diffs)
-
bin/bbstored/HousekeepStoreAccount.cpp (modified) (7 diffs)
-
configure.ac (modified) (6 diffs)
-
docs/backup/win32_build_on_linux_using_mingw.txt (modified) (3 diffs)
-
infrastructure/BoxPlatform.pm.in (modified) (4 diffs)
-
infrastructure/buildenv-testmain-template.cpp (modified) (2 diffs)
-
infrastructure/makebuildenv.pl.in (modified) (21 diffs)
-
infrastructure/msvc/2003/boxbackup.ncb (deleted)
-
infrastructure/msvc/2003/boxbackup.suo (deleted)
-
lib/backupclient/BackupClientFileAttributes.cpp (modified) (2 diffs)
-
lib/backupclient/BackupStoreFile.cpp (modified) (1 diff)
-
lib/backupclient/BackupStoreObjectDump.cpp (modified) (1 diff)
-
lib/backupstore/BackupStoreAccounts.cpp (modified) (1 diff)
-
lib/backupstore/BackupStoreCheck.cpp (modified) (2 diffs)
-
lib/common/BoxPlatform.h (modified) (2 diffs)
-
lib/common/FdGetLine.h (modified) (1 diff)
-
lib/common/Guards.h (modified) (1 diff)
-
lib/common/UnixUser.cpp (modified) (4 diffs)
-
lib/common/makeexception.pl.in (modified) (3 diffs)
-
lib/raidfile/RaidFileRead.cpp (modified) (8 diffs)
-
lib/raidfile/RaidFileWrite.cpp (modified) (10 diffs)
-
lib/server/Daemon.cpp (modified) (11 diffs)
-
lib/server/ServerStream.h (modified) (5 diffs)
-
lib/server/SocketStream.cpp (modified) (13 diffs)
-
lib/server/SocketStream.h (modified) (1 diff)
-
lib/server/SocketStreamTLS.cpp (modified) (2 diffs)
-
lib/server/makeprotocol.pl.in (modified) (4 diffs)
-
runtest.pl.in (modified) (6 diffs)
-
test/backupdiff/testbackupdiff.cpp (modified) (10 diffs)
-
test/backupstore/testbackupstore.cpp (modified) (26 diffs)
-
test/backupstorefix/testfiles/testbackupstorefix.pl.in (modified) (2 diffs)
-
test/backupstorepatch/testbackupstorepatch.cpp (modified) (6 diffs)
-
test/basicserver/TestCommands.cpp (modified) (1 diff)
-
test/basicserver/testbasicserver.cpp (modified) (15 diffs)
-
test/bbackupd/testbbackupd.cpp (modified) (1 diff)
-
test/bbackupd/testfiles/bbackupd.conf (deleted)
-
test/bbackupd/testfiles/bbackupd.conf.in (copied) (copied from box/trunk/test/bbackupd/testfiles/bbackupd.conf)
-
test/bbackupd/testfiles/extcheck1.pl.in (modified) (2 diffs)
-
test/bbackupd/testfiles/extcheck2.pl.in (modified) (2 diffs)
-
test/common/testcommon.cpp (modified) (2 diffs)
-
test/raidfile/intercept.cpp (modified) (1 diff)
-
test/raidfile/testraidfile.cpp (modified) (24 diffs)
-
test/win32/testlibwin32.cpp (modified) (8 diffs)
-
win32.bat (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
box/chris/merge/bin/bbackupctl/bbackupctl.cpp
r456 r710 33 33 printf("Usage: bbackupctl [-q] [-c config_file] <command>\n" 34 34 "Commands are:\n" 35 " sync -- start a sync ronisationrun now\n"36 " force-sync -- force the start of a sync ronisation run, "35 " sync -- start a synchronisation (backup) run now\n" 36 " force-sync -- force the start of a synchronisation run, " 37 37 "even if SyncAllowScript says no\n" 38 38 " reload -- reload daemon configuration\n" 39 39 " terminate -- terminate daemon now\n" 40 40 " wait-for-sync -- wait until the next sync starts, then exit\n" 41 " wait-for-end -- wait until the next sync finishes, then exit\n" 42 " sync-and-wait -- start sync, wait until it finishes, then exit\n" 41 43 ); 42 44 exit(1); … … 108 110 if(!conf.KeyExists("CommandSocket")) 109 111 { 110 printf("Daemon isn't using a control socket, could not execute command.\nAdd a CommandSocket declaration to the bbackupd.conf file.\n"); 112 printf("Daemon isn't using a control socket, " 113 "could not execute command.\n" 114 "Add a CommandSocket declaration to the " 115 "bbackupd.conf file.\n"); 111 116 return 1; 112 117 } … … 189 194 if(!quiet) 190 195 { 191 printf("Daemon configuration summary:\n" \ 192 " AutomaticBackup = %s\n" \ 193 " UpdateStoreInterval = %d seconds\n" \ 194 " MinimumFileAge = %d seconds\n" \ 195 " MaxUploadWait = %d seconds\n", 196 autoBackup?"true":"false", updateStoreInterval, minimumFileAge, maxUploadWait); 196 printf("Daemon configuration summary:\n" 197 " AutomaticBackup = %s\n" 198 " UpdateStoreInterval = %d seconds\n" 199 " MinimumFileAge = %d seconds\n" 200 " MaxUploadWait = %d seconds\n", 201 autoBackup?"true":"false", updateStoreInterval, 202 minimumFileAge, maxUploadWait); 203 } 204 205 std::string stateLine; 206 if(!getLine.GetLine(stateLine) || getLine.IsEOF()) 207 { 208 #if defined WIN32 && ! defined NDEBUG 209 syslog(LOG_ERR, "Failed to receive state line from daemon"); 210 #else 211 printf("Failed to receive state line from daemon\n"); 212 #endif 213 return 1; 214 } 215 216 // Decode it 217 int currentState; 218 if(::sscanf(stateLine.c_str(), "state %d", ¤tState) != 1) 219 { 220 printf("State line didn't decode\n"); 221 return 1; 197 222 } 198 223 199 224 // Is the command the "wait for sync to start" command? 200 225 bool areWaitingForSync = false; 201 if(::strcmp(argv[0], "wait-for-sync") == 0) 202 { 203 // Check that it's not in non-automatic mode, because then it'll never start 226 bool areWaitingForSyncEnd = false; 227 228 if(::strcmp(argv[0], "wait-for-sync") == 0 || 229 ::strcmp(argv[0], "wait-for-end") == 0) 230 { 231 // Check that it's not in non-automatic mode, 232 // because then it'll never start 204 233 if(!autoBackup) 205 234 { 206 printf("ERROR: Daemon is not in automatic mode -- sync will never start!\n"); 235 printf("ERROR: Daemon is not in automatic mode -- " 236 "sync will never start!\n"); 207 237 return 1; 208 238 } 209 239 210 // Yes... set the flag so we know what we're waiting for a sync to start 211 areWaitingForSync = true; 240 // Yes... set the flag so we know that 241 // we're waiting for a sync to start/end 242 if(::strcmp(argv[0], "wait-for-sync") == 0) 243 { 244 areWaitingForSync = true; 245 } 246 else if (::strcmp(argv[0], "wait-for-end") == 0) 247 { 248 areWaitingForSyncEnd = true; 249 } 250 } 251 else if (::strcmp(argv[0], "sync-and-wait") == 0) 252 { 253 // send a sync command 254 std::string cmd("force-sync\n"); 255 connection.Write(cmd.c_str(), cmd.size()); 256 connection.WriteAllBuffered(); 257 areWaitingForSyncEnd = true; 258 259 if (currentState != 0) 260 { 261 printf("Waiting for current sync/error state " 262 "to finish...\n"); 263 } 212 264 } 213 265 else … … 221 273 // Read the response 222 274 std::string line; 275 bool syncIsRunning = false; 276 223 277 while(!getLine.IsEOF() && getLine.GetLine(line)) 224 278 { … … 235 289 } 236 290 } 291 else if(areWaitingForSyncEnd) 292 { 293 if(line == "start-sync") 294 { 295 if (!quiet) printf("Sync started...\n"); 296 syncIsRunning = true; 297 } 298 else if(line == "finish-sync" && syncIsRunning) 299 { 300 if (!quiet) printf("Sync finished.\n"); 301 // Send a quit command to finish nicely 302 connection.Write("quit\n", 5); 303 304 // And we're done 305 break; 306 } 307 else if(line == "finish-sync") 308 { 309 if (!quiet) printf("Previous sync finished.\n"); 310 } 311 // daemon must still be busy 312 } 237 313 else 238 314 { -
box/chris/merge/bin/bbackupd/BackupClientContext.cpp
r456 r710 177 177 mStorageLimitExceeded = true; 178 178 // Log 179 ::syslog(LOG_ INFO, "Exceeded storage limits on server -- not uploading changes to files");179 ::syslog(LOG_WARNING, "Exceeded storage limits on server -- not uploading changes to files"); 180 180 } 181 181 } -
box/chris/merge/bin/bbackupd/BackupClientDirectoryRecord.cpp
r456 r710 646 646 // 647 647 // Condition for upload: 648 // modific tion time within sync period648 // modification time within sync period 649 649 // if it's been seen before but not uploaded, is the time from this first sight longer than the MaxUploadWait 650 650 // and if we know about it from a directory listing, that it hasn't got the same upload time as on the store 651 if( 652 ( 653 // Check the file modified within the acceptable time period we're checking 654 // If the file isn't on the server, the acceptable time starts at zero. 655 // Check pDirOnStore and en, because if we didn't download a directory listing, 656 // pDirOnStore will be zero, but we know it's on the server. 657 ( ((pDirOnStore != 0 && en == 0) || (modTime >= rParams.mSyncPeriodStart)) && modTime < rParams.mSyncPeriodEnd) 658 659 // However, just in case things are continually modified, we check the first seen time. 660 // The two compares of syncPeriodEnd and pendingFirstSeenTime are because the values are unsigned. 661 || (pendingFirstSeenTime != 0 && 662 (rParams.mSyncPeriodEnd > pendingFirstSeenTime) 663 && ((rParams.mSyncPeriodEnd - pendingFirstSeenTime) > rParams.mMaxUploadWait)) 664 665 // Then make sure that if files are added with a time less than the sync period start 666 // (which can easily happen on file server), it gets uploaded. The directory contents checksum 667 // will pick up the fact it has been added, so the store listing will be available when this happens. 668 || ((modTime <= rParams.mSyncPeriodStart) && (en != 0) && (en->GetModificationTime() != modTime)) 669 670 // And just to catch really badly off clocks in the future for file server clients, 671 // just upload the file if it's madly in the future. 672 || (modTime > rParams.mUploadAfterThisTimeInTheFuture) 673 ) 674 // But even then, only upload it if the mod time locally is different to that on the server. 675 && (en == 0 || en->GetModificationTime() != modTime)) 651 652 bool doUpload = false; 653 654 // Only upload a file if the mod time locally is 655 // different to that on the server. 656 657 if (en == 0 || en->GetModificationTime() != modTime) 658 { 659 // Check the file modified within the acceptable time period we're checking 660 // If the file isn't on the server, the acceptable time starts at zero. 661 // Check pDirOnStore and en, because if we didn't download a directory listing, 662 // pDirOnStore will be zero, but we know it's on the server. 663 if (modTime < rParams.mSyncPeriodEnd) 664 { 665 if (pDirOnStore != 0 && en == 0) 666 { 667 doUpload = true; 668 } 669 else if (modTime >= rParams.mSyncPeriodStart) 670 { 671 doUpload = true; 672 } 673 } 674 675 // However, just in case things are continually 676 // modified, we check the first seen time. 677 // The two compares of syncPeriodEnd and 678 // pendingFirstSeenTime are because the values 679 // are unsigned. 680 681 if (!doUpload && 682 pendingFirstSeenTime != 0 && 683 rParams.mSyncPeriodEnd > pendingFirstSeenTime && 684 (rParams.mSyncPeriodEnd - pendingFirstSeenTime) 685 > rParams.mMaxUploadWait) 686 { 687 doUpload = true; 688 } 689 690 // Then make sure that if files are added with a 691 // time less than the sync period start 692 // (which can easily happen on file server), it 693 // gets uploaded. The directory contents checksum 694 // will pick up the fact it has been added, so the 695 // store listing will be available when this happens. 696 697 if (!doUpload && 698 modTime <= rParams.mSyncPeriodStart && 699 en != 0 && 700 en->GetModificationTime() != modTime) 701 { 702 doUpload = true; 703 } 704 705 // And just to catch really badly off clocks in 706 // the future for file server clients, 707 // just upload the file if it's madly in the future. 708 709 if (!doUpload && modTime > 710 rParams.mUploadAfterThisTimeInTheFuture) 711 { 712 doUpload = true; 713 } 714 } 715 716 if (doUpload) 676 717 { 677 718 // Make sure we're connected -- must connect here so we know whether … … 1023 1064 mSubDirectories.erase(e); 1024 1065 delete rec; 1025 TRACE2("Deleted directory record for %s/%s\n", rLocalPath.c_str(), dirname.GetClearFilename().c_str()); 1066 TRACE2("Deleted directory record for " 1067 "%s" DIRECTORY_SEPARATOR "%s\n", 1068 rLocalPath.c_str(), 1069 dirname.GetClearFilename().c_str()); 1026 1070 } 1027 1071 } -
box/chris/merge/bin/bbackupd/BackupDaemon.cpp
r547 r710 126 126 127 127 #ifdef WIN32 128 // Create the event object to signal from main thread to worker 129 // when new messages are queued to be sent to the command socket. 130 mhMessageToSendEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 131 if (mhMessageToSendEvent == INVALID_HANDLE_VALUE) 132 { 133 syslog(LOG_ERR, "Failed to create event object: error %d", 134 GetLastError); 135 exit(1); 136 } 137 138 // Create the event object to signal from worker to main thread 139 // when a command has been received on the command socket. 140 mhCommandReceivedEvent = CreateEvent(NULL, TRUE, FALSE, NULL); 141 if (mhCommandReceivedEvent == INVALID_HANDLE_VALUE) 142 { 143 syslog(LOG_ERR, "Failed to create event object: error %d", 144 GetLastError); 145 exit(1); 146 } 147 148 // Create the critical section to protect the message queue 149 InitializeCriticalSection(&mMessageQueueLock); 150 128 151 // Create a thread to handle the named pipe 129 152 HANDLE hThread; … … 264 287 { 265 288 mpCommandSocketInfo = new CommandSocketInfo; 266 this->mReceivedCommandConn = false;289 WinNamedPipeStream& rSocket(mpCommandSocketInfo->mListeningSocket); 267 290 268 291 // loop until the parent process exits 269 while ( TRUE)292 while (!IsTerminateWanted()) 270 293 { 271 294 try 272 295 { 273 mpCommandSocketInfo->mListeningSocket.Accept( 274 BOX_NAMED_PIPE_NAME); 296 rSocket.Accept(BOX_NAMED_PIPE_NAME); 297 } 298 catch (BoxException &e) 299 { 300 ::syslog(LOG_ERR, "Failed to open command socket: %s", 301 e.what()); 302 SetTerminateWanted(); 303 break; // this is fatal 304 } 305 catch (...) 306 { 307 ::syslog(LOG_ERR, "Failed to open command socket: " 308 "unknown error"); 309 SetTerminateWanted(); 310 break; // this is fatal 311 } 312 313 try 314 { 315 // Errors here do not kill the thread, 316 // only the current connection. 275 317 276 318 // This next section comes from Ben's original function … … 290 332 mState); 291 333 292 mpCommandSocketInfo->mListeningSocket.Write(summary, summarySize); 293 mpCommandSocketInfo->mListeningSocket.Write("ping\n", 5); 294 295 IOStreamGetLine readLine(mpCommandSocketInfo->mListeningSocket); 334 rSocket.Write(summary, summarySize); 335 rSocket.Write("ping\n", 5); 336 337 // old queued messages are not useful 338 EnterCriticalSection(&mMessageQueueLock); 339 mMessageList.clear(); 340 ResetEvent(mhMessageToSendEvent); 341 LeaveCriticalSection(&mMessageQueueLock); 342 343 IOStreamGetLine readLine(rSocket); 296 344 std::string command; 297 345 298 while (mpCommandSocketInfo->mListeningSocket.IsConnected() && 299 readLine.GetLine(command) ) 300 { 301 TRACE1("Receiving command '%s' over " 302 "command socket\n", command.c_str()); 346 while (rSocket.IsConnected() && !IsTerminateWanted()) 347 { 348 HANDLE handles[2]; 349 handles[0] = mhMessageToSendEvent; 350 handles[1] = rSocket.GetReadableEvent(); 351 352 DWORD result = WaitForMultipleObjects( 353 sizeof(handles)/sizeof(*handles), 354 handles, FALSE, 1000); 355 356 if (result == 0) 357 { 358 ResetEvent(mhMessageToSendEvent); 359 360 EnterCriticalSection(&mMessageQueueLock); 361 try 362 { 363 while (mMessageList.size() > 0) 364 { 365 std::string message = *(mMessageList.begin()); 366 mMessageList.erase(mMessageList.begin()); 367 printf("Sending '%s' to waiting client... ", message.c_str()); 368 message += "\n"; 369 rSocket.Write(message.c_str(), 370 message.length()); 371 372 printf("done.\n"); 373 } 374 } 375 catch (...) 376 { 377 LeaveCriticalSection(&mMessageQueueLock); 378 throw; 379 } 380 LeaveCriticalSection(&mMessageQueueLock); 381 continue; 382 } 383 else if (result == WAIT_TIMEOUT) 384 { 385 continue; 386 } 387 else if (result != 1) 388 { 389 ::syslog(LOG_ERR, "WaitForMultipleObjects returned invalid result %d", result); 390 continue; 391 } 392 393 if (!readLine.GetLine(command)) 394 { 395 ::syslog(LOG_ERR, "Failed to read line"); 396 continue; 397 } 398 399 printf("Received command '%s' from client\n", command.c_str()); 303 400 304 401 bool sendOK = false; … … 339 436 sendOK = true; 340 437 } 438 else 439 { 440 ::syslog(LOG_ERR, "Received unknown command '%s' from client", command.c_str()); 441 sendResponse = true; 442 sendOK = false; 443 } 341 444 342 445 // Send a response back? … … 344 447 { 345 448 const char* response = sendOK ? "ok\n" : "error\n"; 346 mpCommandSocketInfo->mListeningSocket.Write(449 rSocket.Write( 347 450 response, strlen(response)); 348 451 } … … 353 456 } 354 457 355 this->mReceivedCommandConn = true;356 } 357 358 mpCommandSocketInfo->mListeningSocket.Close();458 // this->mReceivedCommandConn = true; 459 } 460 461 rSocket.Close(); 359 462 } 360 463 catch (BoxException &e) … … 505 608 // haven't contacted the store yet 506 609 507 bool de serialised = DeserializeStoreObjectInfo(clientStoreMarker,508 lastSyncTime, nextSyncTime);610 bool deleteStoreObjectInfoFile = DeserializeStoreObjectInfo( 611 clientStoreMarker, lastSyncTime, nextSyncTime); 509 612 510 613 // -------------------------------------------------------------------------------------------- … … 612 715 // so that we don't try to reload it after a 613 716 // partially completed backup 614 if(deserialised && !DeleteStoreObjectInfo()) 717 if(deleteStoreObjectInfoFile && 718 !DeleteStoreObjectInfo()) 615 719 { 616 720 ::syslog(LOG_ERR, "Failed to delete the " … … 622 726 continue; 623 727 } 728 729 // In case the backup throws an exception, 730 // we should not try to delete the store info 731 // object file again. 732 deleteStoreObjectInfoFile = false; 624 733 625 734 // Do sync … … 730 839 // -------------------------------------------------------------------------------------------- 731 840 732 // We had a successful backup, save the store info 733 SerializeStoreObjectInfo(clientStoreMarker, lastSyncTime, nextSyncTime); 841 // We had a successful backup, save the store 842 // info. If we save successfully, we must 843 // delete the file next time we start a backup 844 845 deleteStoreObjectInfoFile = 846 SerializeStoreObjectInfo( 847 clientStoreMarker, 848 lastSyncTime, nextSyncTime); 734 849 735 850 // -------------------------------------------------------------------------------------------- … … 903 1018 { 904 1019 #ifdef WIN32 905 // Really could use some interprocess protection, mutex etc 906 // any side effect should be too bad???? :) 907 DWORD timeout = (DWORD)BoxTimeToMilliSeconds(RequiredDelay); 908 909 while ( this->mReceivedCommandConn == false ) 910 { 911 Sleep(1); 912 913 if ( timeout == 0 ) 914 { 915 DoSyncFlagOut = false; 916 SyncIsForcedOut = false; 917 return; 918 } 919 timeout--; 920 } 921 this->mReceivedCommandConn = false; 922 DoSyncFlagOut = this->mDoSyncFlagOut; 923 SyncIsForcedOut = this->mSyncIsForcedOut; 1020 DWORD requiredDelayMs = BoxTimeToMilliSeconds(RequiredDelay); 1021 1022 DWORD result = WaitForSingleObject(mhCommandReceivedEvent, 1023 (DWORD)requiredDelayMs); 1024 1025 if (result == WAIT_OBJECT_0) 1026 { 1027 DoSyncFlagOut = this->mDoSyncFlagOut; 1028 SyncIsForcedOut = this->mSyncIsForcedOut; 1029 ResetEvent(mhCommandReceivedEvent); 1030 } 1031 else if (result == WAIT_TIMEOUT) 1032 { 1033 DoSyncFlagOut = false; 1034 SyncIsForcedOut = false; 1035 } 1036 else 1037 { 1038 ::syslog(LOG_ERR, "Unexpected result from " 1039 "WaitForSingleObject: error %d", GetLastError()); 1040 } 924 1041 925 1042 return; … … 954 1071 #ifdef PLATFORM_CANNOT_FIND_PEER_UID_OF_UNIX_SOCKET 955 1072 bool uidOK = true; 956 ::syslog(LOG_WARNING, "On this platform, no security check can be made on the cred ientials of peers connecting to the command socket. (bbackupctl)");1073 ::syslog(LOG_WARNING, "On this platform, no security check can be made on the credentials of peers connecting to the command socket. (bbackupctl)"); 957 1074 #else 958 1075 // Security check -- does the process connecting to this socket have … … 1024 1141 && mpCommandSocketInfo->mpGetLine->GetLine(command, false /* no preprocessing */, timeout)) 1025 1142 { 1026 TRACE1("Receiving command '%s' over command socket\n", command.c_str()); 1027 1143 TRACE1("Receiving command '%s' over command socket\n", 1144 command.c_str()); 1145 1146 #ifdef WIN32 1147 SetEvent(mhCommandReceivedEvent); 1148 #endif 1149 1028 1150 bool sendOK = false; 1029 1151 bool sendResponse = true; … … 1138 1260 void BackupDaemon::SendSyncStartOrFinish(bool SendStart) 1139 1261 { 1140 // The bbackupctl program can't rely on a state change, because it may never 1141 // change if the server doesn't need to be contacted. 1142 1143 #ifdef __MINGW32__ 1144 #warning race condition: what happens if socket is closed? 1145 #endif 1262 // The bbackupctl program can't rely on a state change, because it 1263 // may never change if the server doesn't need to be contacted. 1146 1264 1147 1265 if (mpCommandSocketInfo != NULL && … … 1153 1271 ) 1154 1272 { 1155 const char* message = SendStart ? "start-sync\n" : "finish-sync\n";1273 std::string message = SendStart ? "start-sync" : "finish-sync"; 1156 1274 try 1157 1275 { 1158 1276 #ifdef WIN32 1159 mpCommandSocketInfo->mListeningSocket.Write(message, 1160 (int)strlen(message)); 1277 EnterCriticalSection(&mMessageQueueLock); 1278 mMessageList.push_back(message); 1279 SetEvent(mhMessageToSendEvent); 1280 LeaveCriticalSection(&mMessageQueueLock); 1161 1281 #else 1162 mpCommandSocketInfo->mpConnectedSocket->Write(message, 1163 strlen(message)); 1282 message += "\n"; 1283 mpCommandSocketInfo->mpConnectedSocket->Write( 1284 message.c_str(), message.size()); 1164 1285 #endif 1165 1286 } … … 1757 1878 1758 1879 char newState[64]; 1759 char newStateSize = sprintf(newState, "state %d\n", State); 1880 sprintf(newState, "state %d", State); 1881 std::string message = newState; 1760 1882 1761 1883 #ifdef WIN32 1762 #ifndef _MSC_VER 1763 #warning FIX ME: race condition 1764 #endif 1765 1766 // what happens if the socket is closed by the other thread before 1767 // we can write to it? Null pointer deref at best. 1768 if (mpCommandSocketInfo && 1769 mpCommandSocketInfo->mListeningSocket.IsConnected()) 1770 { 1771 try 1772 { 1773 mpCommandSocketInfo->mListeningSocket.Write(newState, newStateSize); 1774 } 1775 catch(...) 1776 { 1777 CloseCommandConnection(); 1778 } 1779 } 1884 EnterCriticalSection(&mMessageQueueLock); 1885 mMessageList.push_back(newState); 1886 SetEvent(mhMessageToSendEvent); 1887 LeaveCriticalSection(&mMessageQueueLock); 1780 1888 #else 1781 if(mpCommandSocketInfo != 0 && mpCommandSocketInfo->mpConnectedSocket.get() != 0) 1782 { 1783 // Something connected to the command socket, tell it about the new state 1784 try 1785 { 1786 mpCommandSocketInfo->mpConnectedSocket->Write(newState, newStateSize); 1787 } 1788 catch(...) 1789 { 1790 CloseCommandConnection(); 1791 } 1889 message += "\n"; 1890 1891 if(mpCommandSocketInfo == 0) 1892 { 1893 return; 1894 } 1895 1896 if (mpCommandSocketInfo->mpConnectedSocket.get() == 0) 1897 { 1898 return; 1899 } 1900 1901 // Something connected to the command socket, tell it about the new state 1902 try 1903 { 1904 mpCommandSocketInfo->mpConnectedSocket->Write(message.c_str(), 1905 message.length()); 1906 } 1907 catch(...) 1908 { 1909 CloseCommandConnection(); 1792 1910 } 1793 1911 #endif … … 2174 2292 static const int STOREOBJECTINFO_VERSION = 1; 2175 2293 2176 voidBackupDaemon::SerializeStoreObjectInfo(int64_t aClientStoreMarker, box_time_t theLastSyncTime, box_time_t theNextSyncTime) const2294 bool BackupDaemon::SerializeStoreObjectInfo(int64_t aClientStoreMarker, box_time_t theLastSyncTime, box_time_t theNextSyncTime) const 2177 2295 { 2178 2296 if(!GetConfiguration().KeyExists("StoreObjectInfoFile")) 2179 2297 { 2180 return ;2298 return false; 2181 2299 } 2182 2300 … … 2186 2304 if (StoreObjectInfoFile.size() <= 0) 2187 2305 { 2188 return; 2189 } 2306 return false; 2307 } 2308 2309 bool created = false; 2190 2310 2191 2311 try … … 2193 2313 FileStream aFile(StoreObjectInfoFile.c_str(), 2194 2314 O_WRONLY | O_CREAT | O_TRUNC); 2315 created = true; 2316 2195 2317 Archive anArchive(aFile, 0); 2196 2318 … … 2237 2359 StoreObjectInfoFile.c_str()); 2238 2360 } 2361 2362 return created; 2239 2363 } 2240 2364 -
box/chris/merge/bin/bbackupd/BackupDaemon.h
r456 r710 47 47 48 48 private: 49 // methods below do partial (specialized) serialization of client state only 50 void SerializeStoreObjectInfo(int64_t aClientStoreMarker, box_time_t theLastSyncTime, box_time_t theNextSyncTime) const; 51 bool DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, box_time_t & theLastSyncTime, box_time_t & theNextSyncTime); 49 // methods below do partial (specialized) serialization of 50 // client state only 51 bool SerializeStoreObjectInfo(int64_t aClientStoreMarker, 52 box_time_t theLastSyncTime, box_time_t theNextSyncTime) const; 53 bool DeserializeStoreObjectInfo(int64_t & aClientStoreMarker, 54 box_time_t & theLastSyncTime, box_time_t & theNextSyncTime); 52 55 bool DeleteStoreObjectInfo() const; 53 56 BackupDaemon(const BackupDaemon &); … … 183 186 184 187 private: 185 bool mDoSyncFlagOut, mSyncIsForcedOut, mReceivedCommandConn; 188 bool mDoSyncFlagOut, mSyncIsForcedOut; 189 HANDLE mhMessageToSendEvent, mhCommandReceivedEvent; 190 CRITICAL_SECTION mMessageQueueLock; 191 std::vector<std::string> mMessageList; 186 192 #endif 187 193 }; -
box/chris/merge/bin/bbackupd/Win32BackupService.cpp
r217 r710 13 13 #include "Win32BackupService.h" 14 14 15 Win32BackupService gDaemonService;15 Win32BackupService* gpDaemonService = NULL; 16 16 extern HANDLE gStopServiceEvent; 17 17 18 18 unsigned int WINAPI RunService(LPVOID lpParameter) 19 19 { 20 DWORD retVal = g DaemonService.WinService();21 SetEvent( gStopServiceEvent);20 DWORD retVal = gpDaemonService->WinService((const char*) lpParameter); 21 SetEvent(gStopServiceEvent); 22 22 return retVal; 23 23 } … … 25 25 void TerminateService(void) 26 26 { 27 g DaemonService.SetTerminateWanted();27 gpDaemonService->SetTerminateWanted(); 28 28 } 29 29 30 DWORD Win32BackupService::WinService( void)30 DWORD Win32BackupService::WinService(const char* pConfigFileName) 31 31 { 32 int argc = 2; 33 //first off get the path name for the default 34 char buf[MAX_PATH]; 32 char exepath[MAX_PATH]; 33 GetModuleFileName(NULL, exepath, sizeof(exepath)); 34 35 std::string configfile; 35 36 36 GetModuleFileName(NULL, buf, sizeof(buf)); 37 std::string buffer(buf); 38 std::string conf( "-c"); 39 std::string cfile(buffer.substr(0,(buffer.find("bbackupd.exe"))) 40 + "bbackupd.conf"); 37 if (pConfigFileName != NULL) 38 { 39 configfile = pConfigFileName; 40 } 41 else 42 { 43 // make the default config file name, 44 // based on the program path 45 configfile = exepath; 46 configfile = configfile.substr(0, 47 configfile.rfind(DIRECTORY_SEPARATOR_ASCHAR)); 48 configfile += DIRECTORY_SEPARATOR "bbackupd.conf"; 49 } 41 50 42 const char *argv[] = {conf.c_str(), cfile.c_str()}; 51 const char *argv[] = {exepath, "-c", configfile.c_str()}; 52 int argc = sizeof(argv) / sizeof(*argv); 53 DWORD ret; 43 54 44 55 MAINHELPER_START 56 ret = this->Main(BOX_FILE_BBACKUPD_DEFAULT_CONFIG, argc, argv); 57 MAINHELPER_END 45 58 46 return this->Main(BOX_FILE_BBACKUPD_DEFAULT_CONFIG, argc, argv); 47 48 MAINHELPER_END 59 return ret; 49 60 } 50 61 -
box/chris/merge/bin/bbackupd/Win32BackupService.h
r217 r710 13 13 { 14 14 public: 15 DWORD WinService( void);15 DWORD WinService(const char* pConfigFileName); 16 16 }; 17 17 -
box/chris/merge/bin/bbackupd/Win32ServiceFunctions.cpp
r456 r710 94 94 // service cannot start if there is an eror. 95 95 96 static char* spConfigFileName; 97 96 98 VOID ServiceMain(DWORD argc, LPTSTR *argv) 97 99 { 98 // initialise service status99 gServiceStatus.dwServiceType = SERVICE_WIN32;100 gServiceStatus.dwCurrentState = SERVICE_STOPPED;101 gServiceStatus.dwControlsAccepted = 0;102 gServiceStatus.dwWin32ExitCode = NO_ERROR;103 gServiceStatus.dwServiceSpecificExitCode = NO_ERROR;104 gServiceStatus.dwCheckPoint = 0;105 gServiceStatus.dwWaitHint = 0;106 107 gServiceStatusHandle = RegisterServiceCtrlHandler(gServiceName,108 ServiceControlHandler);109 110 if (gServiceStatusHandle)111 {112 // service is starting113 gServiceStatus.dwCurrentState = SERVICE_START_PENDING;114 SetServiceStatus(gServiceStatusHandle, &gServiceStatus);115 116 // do initialisation here117 gStopServiceEvent = CreateEvent( 0, TRUE, FALSE, 0);100 // initialise service status 101 gServiceStatus.dwServiceType = SERVICE_WIN32; 102 gServiceStatus.dwCurrentState = SERVICE_STOPPED; 103 gServiceStatus.dwControlsAccepted = 0; 104 gServiceStatus.dwWin32ExitCode = NO_ERROR; 105 gServiceStatus.dwServiceSpecificExitCode = NO_ERROR; 106 gServiceStatus.dwCheckPoint = 0; 107 gServiceStatus.dwWaitHint = 0; 108 109 gServiceStatusHandle = RegisterServiceCtrlHandler(gServiceName, 110 ServiceControlHandler); 111 112 if (gServiceStatusHandle) 113 { 114 // service is starting 115 gServiceStatus.dwCurrentState = SERVICE_START_PENDING; 116 SetServiceStatus(gServiceStatusHandle, &gServiceStatus); 117 118 // do initialisation here 119 gStopServiceEvent = CreateEvent(0, TRUE, FALSE, 0); 118 120 if (!gStopServiceEvent) 119 121 { … … 130 132 0, 131 133 RunService, 132 0,134 spConfigFileName, 133 135 CREATE_SUSPENDED, 134 136 NULL); … … 139 141 // we are now running so tell the SCM 140 142 gServiceStatus.dwControlsAccepted |= 141 (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN);143 (SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN); 142 144 gServiceStatus.dwCurrentState = SERVICE_RUNNING; 143 145 SetServiceStatus(gServiceStatusHandle, &gServiceStatus); … … 157 159 gServiceStatus.dwCurrentState = SERVICE_STOPPED; 158 160 SetServiceStatus(gServiceStatusHandle, &gServiceStatus); 159 } 160 } 161 162 void OurService(void) 163 { 161 } 162 } 163 164 void OurService(char* pConfigFileName) 165 { 166 spConfigFileName = pConfigFileName; 167 164 168 SERVICE_TABLE_ENTRY serviceTable[] = 165 169 { … … 180 184 } 181 185 182 void InstallService(void) 183 { 184 SC_HANDLE newService, scm; 185 186 scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE); 186 int InstallService(const char* pConfigFileName) 187 { 188 if (pConfigFileName != NULL) 189 { 190 struct stat st; 191 192 if (emu_stat(pConfigFileName, &st) != 0) 193 { 194 syslog(LOG_ERR, "Failed to open configuration file: " 195 "%s: %s", pConfigFileName, strerror(errno)); 196 return 1; 197 } 198 199 if (! st.st_mode & S_IFREG) 200 { 201 202 syslog(LOG_ERR, "Failed to open configuration file: " 203 "%s: not a file", pConfigFileName); 204 return 1; 205 } 206 } 207 208 SC_HANDLE scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE); 187 209 188 210 if (!scm) … … 190 212 syslog(LOG_ERR, "Failed to open service control manager: " 191 213 "error %d", GetLastError()); 192 return ;214 return 1; 193 215 } 194 216 … … 197 219 cmd[sizeof(cmd)-1] = 0; 198 220 199 char cmd_args[MAX_PATH]; 200 _snprintf(cmd_args, sizeof(cmd_args)-1, "%s --service", cmd); 201 cmd_args[sizeof(cmd_args)-1] = 0; 202 203 newService = CreateService( 221 std::string cmdWithArgs(cmd); 222 cmdWithArgs += " --service"; 223 224 if (pConfigFileName != NULL) 225 { 226 cmdWithArgs += " \""; 227 cmdWithArgs += pConfigFileName; 228 cmdWithArgs += "\""; 229 } 230 231 SC_HANDLE newService = CreateService( 204 232 scm, 205 233 SERVICE_NAME, … … 209 237 SERVICE_AUTO_START, 210 238 SERVICE_ERROR_NORMAL, 211 cmd _args,239 cmdWithArgs.c_str(), 212 240 0,0,0,0,0); 213 241 242 DWORD err = GetLastError(); 243 CloseServiceHandle(scm); 244 214 245 if (!newService) 215 246 { 216 ::syslog(LOG_ERR, "Failed to create Box Backup service: " 217 "error %d", GetLastError()); 218 return; 247 if (err == ERROR_SERVICE_EXISTS) 248 { 249 ::syslog(LOG_ERR, "Failed to create Box Backup " 250 "service: it already exists"); 251 } 252 else if (err == ERROR_SERVICE_MARKED_FOR_DELETE) 253 { 254 ::syslog(LOG_ERR, "Failed to create Box Backup " 255 "service: it is waiting to be deleted"); 256 } 257 else if (err == ERROR_DUPLICATE_SERVICE_NAME) 258 { 259 ::syslog(LOG_ERR, "Failed to create Box Backup " 260 "service: a service with this name " 261 "already exists"); 262 } 263 else 264 { 265 ::syslog(LOG_ERR, "Failed to create Box Backup " 266 "service: error %d", err); 267 } 268 return 1; 219 269 } 220 270 … … 232 282 233 283 CloseServiceHandle(newService); 234 CloseServiceHandle(scm); 235 } 236 237 void RemoveService(void) 238 { 239 SC_HANDLE service, scm; 240 SERVICE_STATUS status; 241 242 scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE); 284 285 return 0; 286 } 287 288 int RemoveService(void) 289 { 290 SC_HANDLE scm = OpenSCManager(0,0,SC_MANAGER_CREATE_SERVICE); 243 291 244 292 if (!scm) … … 246 294 syslog(LOG_ERR, "Failed to open service control manager: " 247 295 "error %d", GetLastError()); 248 return; 249 } 250 251 service = OpenService(scm, SERVICE_NAME, SERVICE_ALL_ACCESS|DELETE); 252 ControlService(service, SERVICE_CONTROL_STOP, &status); 296 return 1; 297 } 298 299 SC_HANDLE service = OpenService(scm, SERVICE_NAME, 300 SERVICE_ALL_ACCESS|DELETE); 301 DWORD err = GetLastError(); 302 CloseServiceHandle(scm); 253 303 254 304 if (!service) 255 305 { 256 syslog(LOG_ERR, "Failed to open Box Backup service: " 257 "error %d", GetLastError()); 258 return; 259 } 260 261 if (DeleteService(service)) 306 if (err == ERROR_SERVICE_DOES_NOT_EXIST || 307 err == ERROR_IO_PENDING) 308 // hello microsoft? anyone home? 309 { 310 syslog(LOG_ERR, "Failed to open Box Backup service: " 311 "not installed or not found"); 312 } 313 else 314 { 315 syslog(LOG_ERR, "Failed to open Box Backup service: " 316 "error %d", err); 317 } 318 return 1; 319 } 320 321 SERVICE_STATUS status; 322 if (!ControlService(service, SERVICE_CONTROL_STOP, &status)) 323 { 324 err = GetLastError(); 325 if (err != ERROR_SERVICE_NOT_ACTIVE) 326 { 327 syslog(LOG_WARNING, "Failed to stop Box Backup " 328 "service: error %d", err); 329 } 330 } 331 332 BOOL deleted = DeleteService(service); 333 err = GetLastError(); 334 CloseServiceHandle(service); 335 336 if (deleted) 262 337 { 263 338 syslog(LOG_INFO, "Box Backup service deleted"); 339 return 0; 340 } 341 else if (err == ERROR_SERVICE_MARKED_FOR_DELETE) 342 { 343 syslog(LOG_ERR, "Failed to remove Box Backup service: " 344 "it is already being deleted"); 264 345 } 265 346 else 266 347 { 267 348 syslog(LOG_ERR, "Failed to remove Box Backup service: " 268 "error %d", GetLastError()); 269 } 270 271 CloseServiceHandle(service); 272 CloseServiceHandle(scm); 349 "error %d", err); 350 } 351 352 return 1; 273 353 } 274 354 -
box/chris/merge/bin/bbackupd/Win32ServiceFunctions.h
r217 r710 13 13 #define WIN32SERVICEFUNCTIONS_H 14 14 15 voidRemoveService(void);16 void InstallService(void);17 void OurService( void);15 int RemoveService(void); 16 int InstallService(const char* pConfigFilePath); 17 void OurService(char* pConfigFileName); 18 18 19 19 #endif -
box/chris/merge/bin/bbackupd/bbackupd.cpp
r456 r710 20 20 #include "Win32BackupService.h" 21 21 22 extern Win32BackupService gDaemonService;22 extern Win32BackupService* gpDaemonService; 23 23 #endif 24 24 … … 29 29 #ifdef WIN32 30 30 31 ::openlog("Box Backup (bbackupd)", 0, 0);31 ::openlog("Box Backup (bbackupd)", LOG_PID, LOG_LOCAL6); 32 32 33 33 if(argc == 2 && … … 41 41 if(argc == 2 && ::strcmp(argv[1], "-r") == 0) 42 42 { 43 RemoveService(); 44 return 0; 43 return RemoveService(); 45 44 } 46 if( argc == 2&& ::strcmp(argv[1], "-i") == 0)45 if((argc == 2 || argc == 3) && ::strcmp(argv[1], "-i") == 0) 47 46 { 48 InstallService(); 49 return 0; 47 const char* config = NULL; 48 if (argc == 3) 49 { 50 config = argv[2]; 51 } 52 return InstallService(config); 50 53 } 51 54 52 55 bool runAsWin32Service = false; 53 if (argc == 2 && ::strcmp(argv[1], "--service") == 0)56 if (argc >= 2 && ::strcmp(argv[1], "--service") == 0) 54 57 { 55 58 runAsWin32Service = true; 56 59 } 57 58 // Under win32 we must initialise the Winsock library59 // before using sockets60 61 WSADATA info;62 60 63 if (WSAStartup(0x0101, &info) == SOCKET_ERROR) 64 { 65 // box backup will not run without sockets 66 ::syslog(LOG_ERR, "Failed to initialise Windows Sockets"); 67 THROW_EXCEPTION(BackupStoreException, Internal) 68 } 61 gpDaemonService = new Win32BackupService(); 69 62 70 63 EnableBackupRights(); … … 74 67 if (runAsWin32Service) 75 68 { 76 syslog(LOG_INFO,"Starting Box Backup Service"); 77 OurService(); 69 syslog(LOG_INFO, "Box Backup service starting"); 70 71 char* config = NULL; 72 if (argc >= 3) 73 { 74 config = strdup(argv[2]); 75 } 76 77 OurService(config); 78 79 if (config) 80 { 81 free(config); 82 } 83 84 syslog(LOG_INFO, "Box Backup service shut down"); 78 85 } 79 86 else 80 87 { 81 ExitCode = g DaemonService.Main(88 ExitCode = gpDaemonService->Main( 82 89 BOX_FILE_BBACKUPD_DEFAULT_CONFIG, argc, argv); 83 90 } 84 91 85 // Clean up our sockets 86 WSACleanup(); 92 ::closelog(); 87 93 88 ::closelog();94 delete gpDaemonService; 89 95 90 96 return ExitCode; -
box/chris/merge/bin/bbackupquery/BackupQueries.cpp
r626 r710 71 71 mReturnCode(0) // default return code 72 72 { 73 #ifdef WIN32 74 mRunningAsRoot = TRUE; 75 #else 73 76 mRunningAsRoot = (::geteuid() == 0); 77 #endif 74 78 } 75 79 … … 85 89 { 86 90 } 91 92 typedef struct cmd_info 93 { 94 const char* name; 95 const char* opts; 96 } cmd_info_t; 87 97 88 98 // -------------------------------------------------------------------------- … … 163 173 164 174 // Data about commands 165 static const char *commandNames[] = {"quit", "exit", "list", "pwd", "cd", "lcd", "sh", "getobject", "get", "compare", "restore", "help", "usage", "undelete", 0}; 166 static const char *validOptions[] = {"", "", "rodIFtsh", "", "od", "", "", "", "i", "alcqE", "dri", "", "", "", 0}; 175 static cmd_info_t commands[] = 176 { 177 { "quit", "" }, 178 { "exit", "" }, 179 { "list", "rodIFtTsh", }, 180 { "pwd", "" }, 181 { "cd", "od" }, 182 { "lcd", "" }, 183 { "sh", "" }, 184 { "getobject", "" }, 185 { "get", "i" }, 186 { "compare", "alcqAE" }, 187 { "restore", "dri" }, 188 { "help", "" }, 189 { "usage", "" }, 190 { "undelete", "" }, 191 { NULL, NULL } 192 }; 167 193 #define COMMAND_Quit 0 168 194 #define COMMAND_Exit 1 … … 184 210 // Work out which command it is... 185 211 int cmd = 0; 186 while(command Names[cmd] != 0 && ::strcmp(cmdElements[0].c_str(), commandNames[cmd]) != 0)212 while(commands[cmd].name != 0 && ::strcmp(cmdElements[0].c_str(), commands[cmd].name) != 0) 187 213 { 188 214 cmd++; 189 215 } 190 if(command Names[cmd]== 0)216 if(commands[cmd].name == 0) 191 217 { 192 218 // Check for aliases … … 223 249 { 224 250 // Valid option? 225 if(::strchr(validOptions[cmd], *c) == NULL) 226 { 227 printf("Invalid option '%c' for command %s\n", *c, commandNames[cmd]); 251 if(::strchr(commands[cmd].opts, *c) == NULL) 252 { 253 printf("Invalid option '%c' for command %s\n", 254 *c, commands[cmd].name); 228 255 return; 229 256 } … … 320 347 #define LIST_OPTION_ALLOWDELETED 'd' 321 348 #define LIST_OPTION_NOOBJECTID 'I' 322 #define LIST_OPTION_NOFLAGS 'F' 323 #define LIST_OPTION_TIMES 't' 349 #define LIST_OPTION_NOFLAGS 'F' 350 #define LIST_OPTION_TIMES_LOCAL 't' 351 #define LIST_OPTION_TIMES_UTC 'T' 324 352 #define LIST_OPTION_SIZEINBLOCKS 's' 325 353 #define LIST_OPTION_DISPLAY_HASH 'h' … … 363 391 // 364 392 // Function 365 // Name: BackupQueries:: CommandList2(int64_t, const std::string &, const bool *)393 // Name: BackupQueries::List(int64_t, const std::string &, const bool *, bool) 366 394 // Purpose: Do the actual listing of directories and files 367 395 // Created: 2003/10/10 … … 438 466 } 439 467 440 if(opts[LIST_OPTION_TIMES ])441 { 442 // Show times...468 if(opts[LIST_OPTION_TIMES_LOCAL]) 469 { 470 // Show local times... 443 471 std::string time = BoxTimeToISO8601String( 444 472 en->GetModificationTime()); … … 845 873 846 874 // Find object ID somehow 847 int64_t id; 875 int64_t fileId; 876 int64_t dirId = GetCurrentDirectoryID(); 848 877 std::string localName; 878 849 879 // BLOCK 850 880 { 881 #ifdef WIN32 882 std::string fileName; 883 if(!ConvertConsoleToUtf8(args[0].c_str(), fileName)) 884 return; 885 #else 886 std::string fileName(args[0]); 887 #endif 888 889 if(!opts['i']) 890 { 891 // does this remote filename include a path? 892 std::string::size_type index = fileName.rfind('/'); 893 if(index != std::string::npos) 894 { 895 std::string dirName(fileName.substr(0, index)); 896 fileName = fileName.substr(index + 1); 897 898 dirId = FindDirectoryObjectID(dirName); 899 if(dirId == 0) 900 { 901 printf("Directory '%s' not found\n", 902 dirName.c_str()); 903 return; 904 } 905 } 906 } 907 908 BackupStoreFilenameClear fn(fileName); 909 851 910 // Need to look it up in the current directory 852 911 mrConnection.QueryListDirectory( 853 GetCurrentDirectoryID(),912 dirId, 854 913 BackupProtocolClientListDirectory::Flags_File, // just files 855 914 (opts['i'])?(BackupProtocolClientListDirectory::Flags_EXCLUDE_NOTHING):(BackupProtocolClientListDirectory::Flags_OldVersion | BackupProtocolClientListDirectory::Flags_Deleted), // only current versions … … 864 923 { 865 924 // Specified as ID. 866 id = ::strtoll(args[0].c_str(), 0, 16); 867 if(id == std::numeric_limits<long long>::min() || id == std::numeric_limits<long long>::max() || id == 0) 925 fileId = ::strtoll(args[0].c_str(), 0, 16); 926 if(fileId == std::numeric_limits<long long>::min() || 927 fileId == std::numeric_limits<long long>::max() || 928 fileId == 0) 868 929 { 869 930 printf("Not a valid object ID (specified in hex)\n"); … … 872 933 873 934 // Check that the item is actually in the directory 874 if(dir.FindEntryByID(id) == 0) 875 { 876 printf("ID '%08llx' not found in current directory on store.\n(You can only download objects by ID from the current directory.)\n", id); 935 if(dir.FindEntryByID(fileId) == 0) 936 { 937 printf("ID '%08llx' not found in current " 938 "directory on store.\n" 939 "(You can only download objects by ID " 940 "from the current directory.)\n", 941 fileId); 877 942 return; 878 943 } … … 885 950 // Specified by name, find the object in the directory to get the ID 886 951 BackupStoreDirectory::Iterator i(dir); 887 #ifdef WIN32888 std::string fileName;889 if(!ConvertConsoleToUtf8(args[0].c_str(), fileName))890 return;891 BackupStoreFilenameClear fn(fileName);892 #else893 BackupStoreFilenameClear fn(args[0]);894 #endif895 952 BackupStoreDirectory::Entry *en = i.FindMatchingClearName(fn); 896 953 897 954 if(en == 0) 898 955 { 899 printf("Filename '%s' not found in current directory on store.\n(Subdirectories in path not searched.)\n", args[0].c_str()); 956 printf("Filename '%s' not found in current " 957 "directory on store.\n" 958 "(Subdirectories in path not " 959 "searched.)\n", args[0].c_str()); 900 960 return; 901 961 } 902 962 903 id = en->GetObjectID();963 fileId = en->GetObjectID(); 904 964 905 // Local name is the last argument, which is either the looked up filename, or 906 // a filename specified by the user. 965 // Local name is the last argument, which is either 966 // the looked up filename, or a filename specified 967 // by the user. 907 968 localName = args[args.size() - 1]; 908 969 } … … 921 982 { 922 983 // Request object 923 mrConnection.QueryGetFile( GetCurrentDirectoryID(), id);984 mrConnection.QueryGetFile(dirId, fileId); 924 985 925 986 // Stream containing encoded file … … 930 991 931 992 // Done. 932 printf("Object ID %08llx fetched sucessfully.\n", id);993 printf("Object ID %08llx fetched sucessfully.\n", fileId); 933 994 } 934 995 catch(...) … … 951 1012 : mQuickCompare(false), 952 1013 mIgnoreExcludes(false), 1014 mIgnoreAttributes(false), 953 1015 mDifferences(0), 954 1016 mDifferencesExplainedByModTime(0), 1017 mUncheckedFiles(0), 955 1018 mExcludedDirs(0), 956 1019 mExcludedFiles(0), … … 1013 1076 params.mQuickCompare = opts['q']; 1014 1077 params.mIgnoreExcludes = opts['E']; 1078 params.mIgnoreAttributes = opts['A']; 1015 1079 1016 1080 // Try and work out the time before which all files should be on the server … … 1075 1139 } 1076 1140 1077 printf("\n[ %d (of %d) differences probably due to file modifications after the last upload ]\nDifferences: %d (%d dirs excluded, %d files excluded)\n", 1078 params.mDifferencesExplainedByModTime, params.mDifferences, params.mDifferences, params.mExcludedDirs, params.mExcludedFiles); 1141 printf("\n[ %d (of %d) differences probably due to file " 1142 "modifications after the last upload ]\n" 1143 "Differences: %d (%d dirs excluded, %d files excluded, " 1144 "%d files not checked)\n", 1145 params.mDifferencesExplainedByModTime, params.mDifferences, 1146 params.mDifferences, params.mExcludedDirs, 1147 params.mExcludedFiles, params.mUncheckedFiles); 1079 1148 1080 1149 // Set return code? 1081 1150 if(opts['c']) 1082 1151 { 1083 SetReturnCode((params.mDifferences == 0)?COMPARE_RETURN_SAME:COMPARE_RETURN_DIFFERENT); 1152 if (params.mUncheckedFiles != 0) 1153 { 1154 SetReturnCode(COMPARE_RETURN_ERROR); 1155 } 1156 else if (params.mDifferences != 0) 1157 { 1158 SetReturnCode(COMPARE_RETURN_DIFFERENT); 1159 } 1160 else 1161 { 1162 SetReturnCode(COMPARE_RETURN_SAME); 1163 } 1084 1164 } 1085 1165 } … … 1215 1295 localDirDisplay.c_str(), 1216 1296 storeDirDisplay.c_str()); 1297 rParams.mDifferences ++; 1217 1298 } 1218 1299 else … … 1220 1301 printf("ERROR: stat on local dir '%s'\n", 1221 1302 localDirDisplay.c_str()); 1303 rParams.mUncheckedFiles ++; 1222 1304 } 1223 1305 return; … … 1269 1351 printf("ERROR: opendir on local dir '%s'\n", 1270 1352 localDirDisplay.c_str()); 1353 rParams.mUncheckedFiles ++; 1271 1354 return; 1272 1355 } … … 1456 1539 1457 1540 // Compare attributes 1541 box_time_t fileModTime = 0; 1458 1542 BackupClientFileAttributes localAttr; 1459 box_time_t fileModTime = 0;1460 1543 localAttr.ReadAttributes(localPath.c_str(), false /* don't zero mod times */, &fileModTime); 1461 1544 modifiedAfterLastSync = (fileModTime > rParams.mLatestFileUploadTime); 1462 if(!localAttr.Compare(fileOnServerStream->GetAttributes(), 1545 if(!rParams.mIgnoreAttributes && 1546 !localAttr.Compare(fileOnServerStream->GetAttributes(), 1463 1547 true /* ignore attr mod time */, 1464 1548 fileOnServerStream->IsSymLink() /* ignore modification time if it's a symlink */)) … … 1555 1639 e.GetSubType(), 1556 1640 storePathDisplay.c_str()); 1641 rParams.mUncheckedFiles ++; 1557 1642 } 1558 1643 catch(...) 1559 { 1644 { 1560 1645 printf("ERROR: (unknown) during file fetch and comparison for '%s'\n", storePathDisplay.c_str()); 1646 rParams.mUncheckedFiles ++; 1561 1647 } 1562 1648 … … 1794 1880 break; 1795 1881 1882 #ifdef WIN32 1883 case Restore_TargetPathNotFound: 1884 printf("The target directory path does not exist.\n" 1885 "To restore to a directory whose parent " 1886 "does not exist, create the parent first.\n"); 1887 break; 1888 #endif 1889 1796 1890 default: 1797 1891 printf("ERROR: Unknown restore result.\n"); -
box/chris/merge/bin/bbackupquery/BackupQueries.h
r217 r710 69 69 bool mQuickCompare; 70 70 bool mIgnoreExcludes; 71 bool mIgnoreAttributes; 71 72 int mDifferences; 72 73 int mDifferencesExplainedByModTime; 74 int mUncheckedFiles; 73 75 int mExcludedDirs; 74 76 int mExcludedFiles; -
box/chris/merge/bin/bbackupquery/documentation.txt
r217 r710 105 105 -q -- quick compare. Only checks file contents against checksums, 106 106 doesn't do a full download 107 -A -- ignore attribute differences 107 108 -E -- ignore exclusion settings 108 109 -
box/chris/merge/bin/bbstored/BBStoreDHousekeeping.cpp
r250 r710 11 11 12 12 #include <stdio.h> 13 14 #ifdef HAVE_SYSLOG_H 13 15 #include <syslog.h> 16 #endif 14 17 15 18 #include "BackupStoreDaemon.h" … … 30 33 // 31 34 // -------------------------------------------------------------------------- 35 void BackupStoreDaemon::HousekeepingInit() 36 { 37 38 mLastHousekeepingRun = 0; 39 } 40 41 #ifndef WIN32 32 42 void BackupStoreDaemon::HousekeepingProcess() 33 43 { 44 HousekeepingInit(); 45 34 46 // Get the time between housekeeping runs 35 47 const Configuration &rconfig(GetConfiguration()); 36 48 int64_t housekeepingInterval = SecondsToBoxTime(rconfig.GetKeyValueInt("TimeBetweenHousekeeping")); 37 38 int64_t lastHousekeepingRun = 0;39 49 40 50 while(!StopRun()) 41 51 { 42 // Time now 52 RunHousekeepingIfNeeded(); 53 54 // Calculate how long should wait before doing the next housekeeping run 43 55 int64_t timeNow = GetCurrentBoxTime(); 44 // Do housekeeping if the time interval has elapsed since the last check 45 if((timeNow - lastHousekeepingRun) >= housekeepingInterval) 46 { 47 // Store the time 48 lastHousekeepingRun = timeNow; 49 ::syslog(LOG_INFO, "Starting housekeeping"); 50 51 // Get the list of accounts 52 std::vector<int32_t> accounts; 53 if(mpAccountDatabase) 54 { 55 mpAccountDatabase->GetAllAccountIDs(accounts); 56 } 57 58 SetProcessTitle("housekeeping, active"); 59 60 // Check them all 61 for(std::vector<int32_t>::const_iterator i = accounts.begin(); i != accounts.end(); ++i) 62 { 63 try 64 { 65 if(mpAccounts) 66 { 67 // Get the account root 68 std::string rootDir; 69 int discSet = 0; 70 mpAccounts->GetAccountRoot(*i, rootDir, discSet); 71 72 // Do housekeeping on this account 73 HousekeepStoreAccount housekeeping(*i, rootDir, discSet, *this); 74 housekeeping.DoHousekeeping(); 75 } 76 } 77 catch(BoxException &e) 78 { 79 ::syslog(LOG_ERR, "while housekeeping account %08X, exception %s (%d/%d) -- aborting housekeeping run for this account", 80 *i, e.what(), e.GetType(), e.GetSubType()); 81 } 82 catch(std::exception &e) 83 { 84 ::syslog(LOG_ERR, "while housekeeping account %08X, exception %s -- aborting housekeeping run for this account", 85 *i, e.what()); 86 } 87 catch(...) 88 { 89 ::syslog(LOG_ERR, "while housekeeping account %08X, unknown exception -- aborting housekeeping run for this account", 90 *i); 91 } 92 93 // Check to see if there's any message pending 94 CheckForInterProcessMsg(0 /* no account */); 95 96 // Stop early? 97 if(StopRun()) 98 { 99 break; 100 } 101 } 102 103 ::syslog(LOG_INFO, "Finished housekeeping"); 104 } 105 106 // Placed here for accuracy, if StopRun() is true, for example. 107 SetProcessTitle("housekeeping, idle"); 108 109 // Calculate how long should wait before doing the next housekeeping run 110 timeNow = GetCurrentBoxTime(); 111 time_t secondsToGo = BoxTimeToSeconds((lastHousekeepingRun + housekeepingInterval) - timeNow); 56 time_t secondsToGo = BoxTimeToSeconds((mLastHousekeepingRun + housekeepingInterval) - timeNow); 112 57 if(secondsToGo < 1) secondsToGo = 1; 113 58 if(secondsToGo > 60) secondsToGo = 60; … … 118 63 } 119 64 } 120 65 #endif 66 67 void BackupStoreDaemon::RunHousekeepingIfNeeded() 68 { 69 // Get the time between housekeeping runs 70 const Configuration &rconfig(GetConfiguration()); 71 int64_t housekeepingInterval = SecondsToBoxTime(rconfig.GetKeyValueInt("TimeBetweenHousekeeping")); 72 73 // Time now 74 int64_t timeNow = GetCurrentBoxTime(); 75 // Do housekeeping if the time interval has elapsed since the last check 76 if((timeNow - mLastHousekeepingRun) < housekeepingInterval) 77 { 78 return; 79 } 80 81 // Store the time 82 mLastHousekeepingRun = timeNow; 83 ::syslog(LOG_INFO, "Starting housekeeping"); 84 85 // Get the list of accounts 86 std::vector<int32_t> accounts; 87 if(mpAccountDatabase) 88 { 89 mpAccountDatabase->GetAllAccountIDs(accounts); 90 } 91 92 SetProcessTitle("housekeeping, active"); 93 94 // Check them all 95 for(std::vector<int32_t>::const_iterator i = accounts.begin(); i != accounts.end(); ++i) 96 { 97 try 98 { 99 if(mpAccounts) 100 { 101 // Get the account root 102 std::string rootDir; 103 int discSet = 0; 104 mpAccounts->GetAccountRoot(*i, rootDir, discSet); 105 106 // Do housekeeping on this account 107 HousekeepStoreAccount housekeeping(*i, rootDir, discSet, *this); 108 housekeeping.DoHousekeeping(); 109 } 110 } 111 catch(BoxException &e) 112 { 113 ::syslog(LOG_ERR, "while housekeeping account %08X, exception %s (%d/%d) -- aborting housekeeping run for this account", 114 *i, e.what(), e.GetType(), e.GetSubType()); 115 } 116 catch(std::exception &e) 117 { 118 ::syslog(LOG_ERR, "while housekeeping account %08X, exception %s -- aborting housekeeping run for this account", 119 *i, e.what()); 120 } 121 catch(...) 122 { 123 ::syslog(LOG_ERR, "while housekeeping account %08X, unknown exception -- aborting housekeeping run for this account", 124 *i); 125 } 126 127 #ifndef WIN32 128 // Check to see if there's any message pending 129 CheckForInterProcessMsg(0 /* no account */); 130 #endif 131 132 // Stop early? 133 if(StopRun()) 134 { 135 break; 136 } 137 } 138 139 ::syslog(LOG_INFO, "Finished housekeeping"); 140 141 // Placed here for accuracy, if StopRun() is true, for example. 142 SetProcessTitle("housekeeping, idle"); 143 } 144 145 #ifdef WIN32 146 void BackupStoreDaemon::OnIdle() 147 { 148 if (!mHousekeepingInited) 149 { 150 HousekeepingInit(); 151 mHousekeepingInited = true; 152 } 153 154 RunHousekeepingIfNeeded(); 155 } 156 #endif 121 157 122 158 // -------------------------------------------------------------------------- … … 129 165 // 130 166 // -------------------------------------------------------------------------- 167 #ifndef WIN32 131 168 bool BackupStoreDaemon::CheckForInterProcessMsg(int AccountNum, int MaximumWaitTime) 132 169 { … … 172 209 return false; 173 210 } 174 175 211 #endif 212 213 -
box/chris/merge/bin/bbstored/BackupCommands.cpp
r341 r710 10 10 #include "Box.h" 11 11 12 #ifdef HAVE_SYSLOG_H 12 13 #include <syslog.h> 14 #endif 15 16 #include <set> 17 #include <sstream> 13 18 14 19 #include "autogen_BackupProtocolServer.h" … … 328 333 329 334 // Choose a temporary filename for the result of the combination 330 std::string tempFn(RaidFileController::DiscSetPathToFileSystemPath(rContext.GetStoreDiscSet(), rContext.GetStoreRoot() + ".recombinetemp", 331 p + 16 /* rotate which disc it's on */)); 335 #ifdef WIN32 336 std::ostringstream fs(rContext.GetStoreRoot()); 337 fs << ".recombinetemp."; 338 fs << p; 339 std::string tempFn(fs.str()); 340 tempFn = RaidFileController::DiscSetPathToFileSystemPath(rContext.GetStoreDiscSet(), tempFn, p + 16); 341 #else 342 std::string tempFn(RaidFileController::DiscSetPathToFileSystemPath(rContext.GetStoreDiscSet(), rContext.GetStoreRoot() + ".recombinetemp", p + 16 /* rotate which disc it's on */)); 343 #endif 332 344 333 345 // Open the temporary file … … 337 349 { 338 350 // Write nastily to allow this to work with gcc 2.x 351 #ifdef WIN32 352 combined.reset(new FileStream( 353 tempFn.c_str(), 354 O_RDWR | O_CREAT | O_EXCL | 355 O_BINARY | O_TRUNC)); 356 #else 339 357 std::auto_ptr<IOStream> t(new FileStream(tempFn.c_str(), O_RDWR | O_CREAT | O_EXCL)); 340 358 combined = t; 359 #endif 341 360 } 361 #ifndef WIN32 342 362 // Unlink immediately as it's a temporary file 343 363 if(::unlink(tempFn.c_str()) != 0) … … 345 365 THROW_EXCEPTION(CommonException, OSFileError); 346 366 } 367 #endif 347 368 } 348 369 catch(...) … … 360 381 361 382 // Then shuffle round for the next go 383 #ifdef WIN32 384 if (from.get()) from->Close(); 385 #endif 362 386 from = combined; 363 387 } … … 397 421 } 398 422 399 // Object will be deleted when the stream is deleted, so can release the object auto_ptr here to 400 // avoid premature deletiong 423 // Object will be deleted when the stream is deleted, 424 // so can release the object auto_ptr here to avoid 425 // premature deletion 401 426 object.release(); 402 427 } -
box/chris/merge/bin/bbstored/BackupContext.cpp
r217 r710 133 133 bool gotLock = mWriteLock.TryAndGetLock(writeLockFile.c_str(), 0600 /* restrictive file permissions */); 134 134 135 #ifndef WIN32 135 136 if(!gotLock) 136 137 { … … 151 152 } while(!gotLock && tries > 0); 152 153 } 154 #endif 153 155 154 156 if(gotLock) … … 454 456 { 455 457 // Open it twice 458 #ifdef WIN32 459 FileStream diff(tempFn.c_str(), 460 O_RDWR | O_CREAT | O_BINARY); 461 FileStream diff2(tempFn.c_str(), 462 O_RDWR | O_BINARY); 463 #else 456 464 FileStream diff(tempFn.c_str(), O_RDWR | O_CREAT | O_EXCL); 457 465 FileStream diff2(tempFn.c_str(), O_RDONLY); 458 // Unlink it immediately, so it definately goes away 466 467 // Unlink it immediately, so it definitely goes away 459 468 if(::unlink(tempFn.c_str()) != 0) 460 469 { 461 470 THROW_EXCEPTION(CommonException, OSFileError); 462 471 } 472 #endif 463 473 464 474 // Stream the incoming diff to this temporary file … … 509 519 throw; 510 520 } 521 522 #ifdef WIN32 523 // we can't delete the file while it's open, above 524 if(::unlink(tempFn.c_str()) != 0) 525 { 526 THROW_EXCEPTION(CommonException, OSFileError); 527 } 528 #endif 511 529 } 512 530 -
box/chris/merge/bin/bbstored/BackupStoreDaemon.cpp
r457 r710 12 12 #include <stdlib.h> 13 13 #include <stdio.h> 14 #include <signal.h> 15 16 #ifdef HAVE_SYSLOG_H 14 17 #include <syslog.h> 15 # include <signal.h>18 #endif 16 19 17 20 #include "BackupContext.h" … … 40 43 mHaveForkedHousekeeping(false), 41 44 mIsHousekeepingProcess(false), 45 #ifdef WIN32 46 mHousekeepingInited(false) 47 #else 42 48 mInterProcessComms(mInterProcessCommsSocket) 49 #endif 43 50 { 44 51 } … … 157 164 mExtendedLogging = config.GetKeyValueBool("ExtendedLogging"); 158 165 166 #ifndef WIN32 159 167 // Fork off housekeeping daemon -- must only do this the first time Run() is called 160 168 if(!mHaveForkedHousekeeping) … … 220 228 else 221 229 { 230 #endif // !WIN32 222 231 // In server process -- use the base class to do the magic 223 232 ServerTLS<BOX_PORT_BBSTORED>::Run(); 224 233 234 #ifndef WIN32 225 235 // Why did it stop? Tell the housekeeping process to do the same 226 236 if(IsReloadConfigWanted()) … … 233 243 } 234 244 } 245 #endif 235 246 } 236 247 … … 298 309 ::syslog(LOG_INFO, "Connection statistics for %s: " 299 310 "IN=%lld OUT=%lld TOTAL=%lld\n", commonName, 300 s.GetBytesRead(), s.GetBytesWritten(), 301 s.GetBytesRead() + s.GetBytesWritten()); 302 } 311 (long long)s.GetBytesRead(), 312 (long long)s.GetBytesWritten(), 313 (long long)s.GetBytesRead() + 314 (long long)s.GetBytesWritten()); 315 } -
box/chris/merge/bin/bbstored/BackupStoreDaemon.h
r457 r710 39 39 public: 40 40 41 #ifndef WIN32 41 42 // For BackupContext to comminicate with housekeeping process 42 43 void SendMessageToHousekeepingProcess(const void *Msg, int MsgLen) … … 44 45 mInterProcessCommsSocket.Write(Msg, MsgLen); 45 46 } 47 #endif 46 48 47 49 protected: … … 58 60 const ConfigurationVerify *GetConfigVerify() const; 59 61 62 #ifndef WIN32 60 63 // Housekeeping functions 61 64 void HousekeepingProcess(); 62 65 bool CheckForInterProcessMsg(int AccountNum = 0, int MaximumWaitTime = 0); 66 #endif 63 67 64 68 void LogConnectionStats(const char *commonName, const SocketStreamTLS &s); … … 71 75 bool mIsHousekeepingProcess; 72 76 77 #ifdef WIN32 78 virtual void OnIdle(); 79 bool mHousekeepingInited; 80 #else 73 81 SocketStream mInterProcessCommsSocket; 74 82 IOStreamGetLine mInterProcessComms; 83 #endif 84 85 void HousekeepingInit(); 86 void RunHousekeepingIfNeeded(); 87 int64_t mLastHousekeepingRun; 75 88 }; 76 89 -
box/chris/merge/bin/bbstored/HousekeepStoreAccount.cpp
r217 r710 226 226 bool HousekeepStoreAccount::ScanDirectory(int64_t ObjectID) 227 227 { 228 #ifndef WIN32 228 229 if((--mCountUntilNextInterprocessMsgCheck) <= 0) 229 230 { … … 236 237 } 237 238 } 239 #endif 238 240 239 241 // Get the filename … … 252 254 BackupStoreDirectory dir; 253 255 dir.ReadFromStream(*dirStream, IOStream::TimeOutInfinite); 256 dirStream->Close(); 254 257 255 258 // Is it empty? … … 486 489 for(std::set<DelEn, DelEnCompare>::iterator i(mPotentialDeletions.begin()); i != mPotentialDeletions.end(); ++i) 487 490 { 491 #ifndef WIN32 488 492 if((--mCountUntilNextInterprocessMsgCheck) <= 0) 489 493 { … … 496 500 } 497 501 } 502 #endif 498 503 499 504 // Load up the directory it's in … … 730 735 for(std::vector<int64_t>::const_iterator i(mEmptyDirectories.begin()); i != mEmptyDirectories.end(); ++i) 731 736 { 737 #ifndef WIN32 732 738 if((--mCountUntilNextInterprocessMsgCheck) <= 0) 733 739 { … … 740 746 } 741 747 } 748 #endif 742 749 743 750 // Do not delete the root directory -
box/chris/merge/configure.ac
r626 r710 45 45 46 46 ## Check for Berkely DB. Restrict to certain versions 47 AX_PATH_BDB( , [47 AX_PATH_BDB([1.x or 4.1], [ 48 48 LIBS="$BDB_LIBS $LIBS" 49 49 LDFLAGS="$BDB_LDFLAGS $LDFLAGS" … … 90 90 AC_CHECK_HEADERS([netinet/in.h]) 91 91 AC_CHECK_HEADERS([sys/param.h sys/socket.h sys/time.h sys/types.h sys/wait.h]) 92 AC_CHECK_HEADERS([sys/ xattr.h])92 AC_CHECK_HEADERS([sys/uio.h sys/xattr.h]) 93 93 94 94 if test "$ac_cv_header_regex_h" = "yes"; then … … 117 117 AC_CHECK_DECLS([INFTIM],,, [[#include <poll.h>]]) 118 118 AC_CHECK_DECLS([SO_PEERCRED],,, [[#include <sys/socket.h>]]) 119 AC_CHECK_DECLS([O_BINARY],,,) 119 120 AC_HEADER_TIME 120 121 AC_STRUCT_TM … … 125 126 AX_BSWAP64 126 127 fi 128 127 129 if test "$target_os" != "mingw32"; then 128 130 AX_RANDOM_DEVICE 129 fi 130 AX_CHECK_MOUNT_POINT(,[ 131 if test "$target_os" != "mingw32" -a "$target_os" != "winnt"; then 131 AX_CHECK_MOUNT_POINT(,[ 132 132 AC_MSG_ERROR([[cannot work out how to discover mount points on your platform]]) 133 fi134 133 ]) 134 fi 135 135 136 AX_CHECK_MALLOC_WORKAROUND 136 137 … … 221 222 runtest.pl 222 223 test/backupstorefix/testfiles/testbackupstorefix.pl 224 test/bbackupd/testfiles/bbackupd.conf 223 225 test/bbackupd/testfiles/extcheck1.pl 224 226 test/bbackupd/testfiles/extcheck2.pl … … 238 240 to the documentation for more information on each feature. 239 241 242 Regular expressions: $ac_cv_header_regex_h 240 243 Large files: $have_large_file_support 241 244 Berkeley DB: $ax_path_bdb_ok -
box/chris/merge/docs/backup/win32_build_on_linux_using_mingw.txt
r217 r710 7 7 - Fedora and SuSE users can download RPM packages from 8 8 [http://mirzam.it.vu.nl/mingw/] 9 10 You will need to know the prefix used by the cross-compiler executables. 11 It will usually be something like "ix86-mingw32*-". All the binaries in the 12 cross-compiler package will start with this prefix. The documentation below 13 assumes that it is "i386-mingw32-". Adjust to taste. 9 14 10 15 Download Zlib from [http://www.zlib.net/], unpack and enter source directory: … … 17 22 make install prefix=/usr/local/i386-mingw32 18 23 19 Download OpenSSL 0.9.7 from 24 Download OpenSSL 0.9.8b from 25 [http://www.openssl.org/source/openssl-0.9.8b.tar.gz] 26 27 Unpack and configure: 28 29 tar xzvf openssl-0.9.8b.tar.gz 30 cd openssl-0.9.8b 31 ./Configure mingw 32 make makefile.one 33 wget http://bbdev.fluffy.co.uk/svn/box/chris/win32/support/openssl-0.9.8b-mingw-cross.patch 34 patch -p1 < openssl-0.9.8b-mingw-cross.patch 35 make -f makefile.one 20 36 21 37 Configure Box with: … … 28 44 export LDFLAGS="-mthreads" 29 45 export LIBS="-lcrypto -lws2_32 -lgdi32" 46 (if you don't have a "configure" file, run "./bootstrap") 30 47 ./configure --target=i386-mingw32 31 make CXX="$CXX" AR="$AR" RANLIB="$RANLIB" 48 make CXX="$CXX" AR="$AR" RANLIB="$RANLIB" WINDRES="i386-mingw32-windres" -
box/chris/merge/infrastructure/BoxPlatform.pm.in
r492 r710 2 2 use Exporter; 3 3 @ISA = qw/Exporter/; 4 @EXPORT = qw/$build_os $build_cpu $target_os $make_command $bsd_make $platform_define $platform_cpu $gcc_v3 $product_version $product_name $install_into_dir $sub_make_options $platform_compile_line_extra $platform_link_line_extra $platform_lib_files $platform_exe_ext /;4 @EXPORT = qw/$build_os $build_cpu $target_os $make_command $bsd_make $platform_define $platform_cpu $gcc_v3 $product_version $product_name $install_into_dir $sub_make_options $platform_compile_line_extra $platform_link_line_extra $platform_lib_files $platform_exe_ext $target_windows update_if_changed/; 5 5 6 6 BEGIN … … 8 8 9 9 # which OS are we building under? 10 $build_os = `uname`; 11 chomp $build_os; 12 $build_cpu = `uname -p`; 13 chomp $build_cpu; 10 $target_os = '@target_os@'; 11 $target_windows = 0; 12 $target_windows = 1 if $target_os =~ m'^mingw32' 13 or $target_os eq "winnt"; 14 15 if ($^O eq "MSWin32" and not -x "/usr/bin/uname") 16 { 17 $build_os = "winnt"; 18 $build_cpu = "ix86"; 19 } 20 else 21 { 22 $build_os = `uname`; 23 chomp $build_os; 24 $build_cpu = `uname -m`; 25 chomp $build_cpu; 26 } 27 14 28 # Cygwin Builds usually something like CYGWIN_NT-5.0, CYGWIN_NT-5.1 15 29 # Box Backup tried on Win2000,XP only :) … … 25 39 $platform_link_line_extra = '@LDFLAGS@'; 26 40 $platform_lib_files = '@LIBS@'; 27 $target_os = '@target_os@';28 41 $platform_exe_ext = '@EXEEXT@'; 29 42 30 43 # get version 31 open VERSION,"VERSION.txt" or die "VERSION.txt: $!"; 44 if (! -r "VERSION.txt" and -r "../../VERSION.txt") 45 { 46 open VERSION,"../../VERSION.txt" or die "../../VERSION.txt: $!"; 47 } 48 else 49 { 50 open VERSION,"VERSION.txt" or die "VERSION.txt: $!"; 51 } 52 32 53 $product_version = <VERSION>; 33 54 chomp $product_version; … … 90 111 } 91 112 113 sub update_if_changed ($) 114 { 115 my ($file) = @_; 116 die "$file.new: not found" unless -r "$file.new"; 117 118 if (-r $file) 119 { 120 die "$file.new: not found" unless -r "$file.new"; 121 if (system("diff --brief $file $file.new") == 0) 122 { 123 unlink "$file.new"; 124 return; 125 } 126 } 127 128 if (system("cp $file.new $file") != 0) 129 { 130 die "failed to copy $file.new to $file"; 131 } 132 133 if (system("diff --brief $file $file.new") != 0) 134 { 135 die "$file and $file.new are still different"; 136 } 137 138 unlink "$file.new"; 139 return; 140 } 141 92 142 1; 93 143 -
box/chris/merge/infrastructure/buildenv-testmain-template.cpp
r219 r710 42 42 43 43 int failures = 0; 44 int first_fail_line; 45 std::string first_fail_file; 44 46 45 47 int filedes_open_at_beginning = -1; … … 129 131 if(failures > 0) 130 132 { 131 printf("FAILED: %d tests failed\n", failures); 133 printf("FAILED: %d tests failed (first at " 134 "%s:%d)\n", failures, 135 first_fail_file.c_str(), 136 first_fail_line); 132 137 } 133 138 else -
box/chris/merge/infrastructure/makebuildenv.pl.in
r538 r710 15 15 print "Box build environment setup.\n\n"; 16 16 17 18 my $implicit_dep = 'lib/common'; 17 my @implicit_deps = ('lib/common'); 19 18 20 19 # work out platform variables … … 39 38 my %env_flags; 40 39 41 my $windows_include_path = "-I../../lib/win32 "; 42 if ($target_os ne "mingw32" && $target_os ne "winnt") 43 { 44 $windows_include_path = ""; 45 $env_flags{'IGNORE_lib/win32'} = 1; 40 my $windows_include_path = ""; 41 if ($target_windows) 42 { 43 $module_dependency{"lib/common"} = ["lib/win32"]; 44 push @implicit_deps, "lib/win32"; 45 } 46 else 47 { 48 # $env_flags{'IGNORE_lib/win32'} = 1; 46 49 } 47 50 … … 112 115 113 116 114 # open test mai lprogram template file117 # open test main program template file 115 118 my $test_template_file = 'infrastructure/buildenv-testmain-template.cpp'; 116 119 open FL,$test_template_file or die "Can't open test template file\n"; … … 272 275 } 273 276 } 274 $module_dependency{$mod} = [ $implicit_dep,@md];277 $module_dependency{$mod} = [@implicit_deps,@md]; 275 278 $module_library_link_opts{$mod} = [@lo]; 276 279 … … 287 290 288 291 # make dirs for implicit dep 289 mkdir "release/$implicit_dep",0755; 290 mkdir "debug/$implicit_dep",0755; 292 foreach my $dep (@implicit_deps) 293 { 294 mkdir "release/$dep",0755; 295 mkdir "debug/$dep",0755; 296 } 291 297 292 298 # write a list of all the modules we've configured to use 293 open CONFIGURED_MODS,'>local/modules.h' or die "Can't write configured modules list"; 299 open CONFIGURED_MODS,'>local/modules.h.new' or die 300 "Can't write configured modules list"; 294 301 print CONFIGURED_MODS <<__E; 295 302 // automatically generated file, do not edit … … 297 304 #define _CONFIGURED_MODULES__H 298 305 __E 299 for( $implicit_dep,@modules)306 for(@implicit_deps,@modules) 300 307 { 301 308 my $m = $_; … … 307 314 __E 308 315 close CONFIGURED_MODS; 309 316 update_if_changed("local/modules.h"); 310 317 311 318 # now make a list of all the .h files we can find, recording which module they're in 312 319 my %hfiles; 313 for my $mod (@modules, $implicit_dep)320 for my $mod (@modules, @implicit_deps) 314 321 { 315 322 opendir DIR,$mod; … … 348 355 } 349 356 350 for my $mod (@modules, $implicit_dep)357 for my $mod (@modules, @implicit_deps) 351 358 { 352 359 opendir DIR,$mod; … … 374 381 print "done\n\nGenerating Makefiles...\n"; 375 382 383 my %module_resources_win32; 376 384 377 385 # Then write a makefile for each module 378 for my $mod (@ modules, $implicit_dep)386 for my $mod (@implicit_deps, @modules) 379 387 { 380 388 print $mod,"\n"; … … 387 395 my $testmain = $test_template; 388 396 $testmain =~ s/TEST_NAME/$name/g; 389 open TESTMAIN,">$mod/_main.cpp" or die "Can't open test main file for $mod for writing\n"; 397 open TESTMAIN,">$mod/_main.cpp.new" or die 398 "Can't open test main file for $mod for writing\n"; 390 399 print TESTMAIN $testmain; 391 400 close TESTMAIN; 401 update_if_changed("$mod/_main.cpp"); 392 402 393 403 # test file... … … 395 405 { 396 406 my ($filename,$runcmd,$module) = @_; 397 open TESTFILE,">$filename" or die "Can't open test script file for $module for writing\n"; 407 open TESTFILE,">$filename.new" or die 408 "Can't open test script file for $module " . 409 "for writing\n"; 398 410 print TESTFILE "#!/bin/sh\necho TEST: $module\n"; 399 411 if(-d "$module/testfiles") … … 414 426 print TESTFILE "$runcmd\n"; 415 427 close TESTFILE; 428 update_if_changed($filename); 416 429 } 417 430 418 431 writetestfile("$mod/_t", 419 './test' . $platform_exe_ext . ' $1 $2 $3 $4 $5', $mod);432 './test' . $platform_exe_ext . ' $1 $2 $3 $4 $5', $mod); 420 433 writetestfile("$mod/_t-gdb", 421 'gdb ./test ' . $platform_exe_ext, $mod);434 'gdb ./test' . $platform_exe_ext, $mod); 422 435 423 436 } … … 442 455 # and then dedup and reorder them 443 456 my %d_done; 444 for (my $a = $#deps_raw; $a >= 0; $a--)445 { 446 if(!exists $d_done{$dep s_raw[$a]})457 foreach my $dep (reverse @deps_raw) 458 { 459 if(!exists $d_done{$dep}) 447 460 { 448 461 # insert 449 push @all_deps_for_module, $dep s_raw[$a];462 push @all_deps_for_module, $dep; 450 463 # mark as done 451 $d_done{$dep s_raw[$a]} = 1;464 $d_done{$dep} = 1; 452 465 } 453 466 } … … 481 494 # start the makefile 482 495 my $mk_name_extra = ($bsd_make)?'':'X'; 483 open MAKE,">$mod/Makefile".$mk_name_extra or die "Can't open Makefile for $mod\n"; 496 open MAKE,">$mod/Makefile".$mk_name_extra.".new" or die 497 "Can't open Makefile for $mod\n"; 484 498 my $debug_link_extra = ($target_is_library)?'':'../../debug/lib/debug/debug.a'; 485 499 486 500 my $release_flags = "-O2"; 487 if ($target_ os eq "mingw32")501 if ($target_windows) 488 502 { 489 503 $release_flags = "-O0 -g"; … … 500 514 RANLIB = ranlib 501 515 PERL = "@PERL@" 516 WINDRES = windres 502 517 .ifdef RELEASE 503 518 CXXFLAGS = -DNDEBUG $release_flags -Wall $include_paths $extra_platform_defines -DBOX_VERSION="\\"$product_version\\"" … … 547 562 } 548 563 549 # first, obtain a list of depen encies within the .h files564 # first, obtain a list of dependencies within the .h files 550 565 my %headers; 551 566 for my $h (grep /\.h\Z/i, @items) … … 567 582 # then... do the cpp files... 568 583 my @obj_base; 569 for my $cpp (@items) 570 { 571 next unless $cpp =~ m/\A(.+)\.cpp\Z/i; 572 next if $cpp =~ /\A\._/; # Temp Mac OS Resource hack 584 for my $file (@items) 585 { 586 my $is_cpp = $file =~ m/\A(.+)\.cpp\Z/i; 587 my $is_rc = $file =~ m/\A(.+)\.rc\Z/i; 588 my $base = $1; 589 590 if ($target_windows) 591 { 592 next if not $is_cpp and not $is_rc; 593 } 594 else 595 { 596 next if not $is_cpp; 597 } 598 599 next if $file =~ /\A\._/; # Temp Mac OS Resource hack 573 600 574 601 # store for later 575 my $base = $1;576 602 push @obj_base,$base; 577 603 578 604 # get the file... 579 open FL,"$mod/$ cpp";605 open FL,"$mod/$file"; 580 606 my $f; 581 read FL,$f,-s "$mod/$ cpp";607 read FL,$f,-s "$mod/$file"; 582 608 close FL; 583 609 … … 593 619 594 620 # write the line for this cpp file 595 $make .= $out_name.': '.join(' ',$cpp,map 596 { ($hfiles{$_} eq $mod)?$_:'../../'.$hfiles{$_}."/$_" } keys %dep)."\n"; 597 $make .= "\t\$(CXX) \$(CXXFLAGS) $compile_line_extra -c $cpp -o $out_name\n\n"; 598 621 my @dep_paths = map 622 { 623 ($hfiles{$_} eq $mod) 624 ? $_ 625 : '../../'.$hfiles{$_}."/$_" 626 } 627 keys %dep; 628 629 $make .= $out_name.': '.join(' ',$file,@dep_paths)."\n"; 630 631 if ($is_cpp) 632 { 633 $make .= "\t\$(CXX) \$(CXXFLAGS) $compile_line_extra ". 634 "-c $file -o $out_name\n\n"; 635 } 636 elsif ($is_rc) 637 { 638 $make .= "\t\$(WINDRES) $file $out_name\n\n"; 639 my $res_list = $module_resources_win32{$mod}; 640 $res_list ||= []; 641 push @$res_list, $base.'.o'; 642 $module_resources_win32{$mod} = $res_list; 643 } 599 644 } 600 645 … … 648 693 649 694 my $o_file_list = join(' ',map {'$(OUTDIR)/'.$_.'.o'} @objs); 695 696 if ($has_deps and not $bsd_make) 697 { 698 print MAKE ".PHONY: all\n" . 699 "all: dep_modules $end_target\n\n"; 700 } 701 650 702 print MAKE $end_target,': ',$o_file_list; 651 print MAKE ' dep_modules' if $has_deps and not $bsd_make;652 703 print MAKE " ",$lib_files unless $target_is_library; 653 704 print MAKE "\n"; 654 705 706 if ($target_windows) 707 { 708 foreach my $dep (@all_deps_for_module) 709 { 710 my $res_list = $module_resources_win32{$dep}; 711 next unless $res_list; 712 $o_file_list .= ' '.join(' ', 713 map {'$(OUTBASE)/'.$dep."/$_"} @$res_list); 714 } 715 } 716 655 717 # stuff to make the final target... 656 718 if($target_is_library) … … 731 793 { 732 794 # need to post process this into a GNU makefile 733 open MAKE,">$mod/Makefile ";734 open MAKEB,"$mod/MakefileX ";795 open MAKE,">$mod/Makefile.new" or die $!; 796 open MAKEB,"$mod/MakefileX.new" or die $!; 735 797 736 798 while(<MAKEB>) … … 744 806 close MAKEB; 745 807 close MAKE; 746 unlink "$mod/MakefileX"; 747 } 808 unlink "$mod/MakefileX.new"; 809 } 810 811 update_if_changed("$mod/Makefile"); 748 812 } 749 813 -
box/chris/merge/lib/backupclient/BackupClientFileAttributes.cpp
r464 r710 643 643 644 644 // If working as root, set user IDs 645 #ifndef WIN32 645 646 if(::geteuid() == 0) 646 647 { … … 662 663 #endif 663 664 } 665 #endif 664 666 665 667 if(static_cast<int>(xattrOffset+sizeof(u_int32_t))<=mpClearAttributes->GetSize()) -
box/chris/merge/lib/backupclient/BackupStoreFile.cpp
r456 r710 290 290 stream->CopyStreamTo(out); 291 291 } 292 293 out.Close(); 292 294 293 295 // Write the attributes -
box/chris/merge/lib/backupclient/BackupStoreObjectDump.cpp
r456 r710 114 114 // Output item 115 115 int16_t f = (*i)->GetFlags(); 116 OutputLine(file, ToTrace, "%06llx %4lld %016llx %4d %3d %4d%s%s%s%s%s%s\n", 116 #ifdef WIN32 117 OutputLine(file, ToTrace, 118 "%06I64x %4I64d %016I64x %4d %3d %4d%s%s%s%s%s%s\n", 119 #else 120 OutputLine(file, ToTrace, 121 "%06llx %4lld %016llx %4d %3d %4d%s%s%s%s%s%s\n", 122 #endif 117 123 (*i)->GetObjectID(), 118 124 (*i)->GetSizeInBlocks(), -
box/chris/merge/lib/backupstore/BackupStoreAccounts.cpp
r217 r710 142 142 { 143 143 char accid[64]; // big enough! 144 ::sprintf(accid, "%08x/", ID); 145 return std::string(std::string(BOX_RAIDFILE_ROOT_BBSTORED DIRECTORY_SEPARATOR) + accid); 144 ::sprintf(accid, "%08x" DIRECTORY_SEPARATOR, ID); 145 return std::string(std::string(BOX_RAIDFILE_ROOT_BBSTORED 146 DIRECTORY_SEPARATOR) + accid); 146 147 } 147 148 -
box/chris/merge/lib/backupstore/BackupStoreCheck.cpp
r217 r710 329 329 StoreStructure::MakeObjectFilename(StartID, mStoreRoot, mDiscSetNumber, dirName, false /* don't make sure the dir exists */); 330 330 // Check expectations 331 ASSERT(dirName.size() > 4 && dirName[dirName.size() - 4] == '/'); 331 ASSERT(dirName.size() > 4 && 332 dirName[dirName.size() - 4] == DIRECTORY_SEPARATOR_ASCHAR); 332 333 // Remove the filename from it 333 334 dirName.resize(dirName.size() - 4); // four chars for "/o00" … … 378 379 { 379 380 // Unexpected or bad file, delete it 380 ::printf("Spurious file %s/%s found%s\n", dirName.c_str(), (*i).c_str(), mFixErrors?", deleting":""); 381 ::printf("Spurious file %s" DIRECTORY_SEPARATOR "%s " 382 "found%s\n", dirName.c_str(), (*i).c_str(), 383 mFixErrors?", deleting":""); 381 384 ++mNumberErrorsFound; 382 385 if(mFixErrors) -
box/chris/merge/lib/common/BoxPlatform.h
r483 r710 41 41 #endif 42 42 43 // Slight hack; disable interception on Darwin within raidfile test44 #if def __APPLE__43 // Slight hack; disable interception in raidfile test on Darwin and Windows 44 #if defined __APPLE__ || defined WIN32 45 45 // TODO: Replace with autoconf test 46 46 #define PLATFORM_CLIB_FNS_INTERCEPTION_IMPOSSIBLE … … 139 139 #endif 140 140 141 // for Unix compatibility with Windows :-) 142 #if !HAVE_DECL_O_BINARY 143 #define O_BINARY 0 144 #endif 145 141 146 #ifdef WIN32 142 147 typedef u_int64_t InodeRefType; -
box/chris/merge/lib/common/FdGetLine.h
r217 r710 15 15 #ifdef NDEBUG 16 16 #define FDGETLINE_BUFFER_SIZE 1024 17 #elif defined WIN32 18 // need enough space for at least one unicode character 19 // in UTF-8 when calling console_read() from bbackupquery 20 #define FDGETLINE_BUFFER_SIZE 5 17 21 #else 18 22 #define FDGETLINE_BUFFER_SIZE 4 -
box/chris/merge/lib/common/Guards.h
r456 r710 25 25 #include "MemLeakFindOn.h" 26 26 27 template <int flags = O_RDONLY , int mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)>27 template <int flags = O_RDONLY | O_BINARY, int mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)> 28 28 class FileHandleGuard 29 29 { -
box/chris/merge/lib/common/UnixUser.cpp
r456 r710 76 76 UnixUser::~UnixUser() 77 77 { 78 #ifndef WIN32 78 79 if(mRevertOnDestruction) 79 80 { … … 85 86 } 86 87 } 88 #endif 87 89 } 88 90 … … 99 101 void UnixUser::ChangeProcessUser(bool Temporary) 100 102 { 103 #ifndef WIN32 101 104 if(Temporary) 102 105 { … … 120 123 } 121 124 } 125 #endif 122 126 } 123 127 -
box/chris/merge/lib/common/makeexception.pl.in
r537 r710 1 1 #!@PERL@ 2 3 use lib "../../infrastructure"; 4 use BoxPlatform; 2 5 3 6 # global exception list file 4 7 my $global_list = '../../ExceptionCodes.txt'; 5 6 8 7 9 my @exception; … … 47 49 print "Generating $class exception...\n"; 48 50 49 open CPP,">autogen_${class}Exception.cpp " or die "Can't open cpp file for writing";50 open H,">autogen_${class}Exception.h " or die "Can't open h file for writing";51 open CPP,">autogen_${class}Exception.cpp.new" or die "Can't open cpp file for writing"; 52 open H,">autogen_${class}Exception.h.new" or die "Can't open h file for writing"; 51 53 52 54 # write header file … … 200 202 close H; 201 203 close CPP; 204 205 update_if_changed("autogen_${class}Exception.cpp"); 206 update_if_changed("autogen_${class}Exception.h"); 202 207 203 208 # update the global exception list -
box/chris/merge/lib/raidfile/RaidFileRead.cpp
r217 r710 15 15 #include <errno.h> 16 16 #include <sys/stat.h> 17 18 #ifdef HAVE_SYS_UIO_H 17 19 #include <sys/uio.h> 20 #endif 21 22 #ifdef HAVE_SYSLOG_H 18 23 #include <syslog.h> 24 #endif 25 19 26 #include <stdarg.h> 27 28 #ifdef HAVE_DIRENT_H 20 29 #include <dirent.h> 30 #endif 21 31 22 32 #include <stdio.h> … … 584 594 // Open the parity file 585 595 std::string parityFilename(RaidFileUtil::MakeRaidComponentName(rdiscSet, mFilename, (2 + startDisc) % READ_NUMBER_DISCS_REQUIRED)); 586 mParityHandle = ::open(parityFilename.c_str(), O_RDONLY, 0555); 596 mParityHandle = ::open(parityFilename.c_str(), 597 O_RDONLY | O_BINARY, 0555); 587 598 if(mParityHandle == -1) 588 599 { … … 1018 1029 1019 1030 // Attempt to open 1020 int osFileHandle = ::open(writeFilename.c_str(), O_RDONLY, 0); 1031 int osFileHandle = ::open(writeFilename.c_str(), 1032 O_RDONLY | O_BINARY, 0); 1021 1033 if(osFileHandle == -1) 1022 1034 { … … 1056 1068 { 1057 1069 // Open stripe1 1058 stripe1 = ::open(stripe1Filename.c_str(), O_RDONLY, 0555); 1070 stripe1 = ::open(stripe1Filename.c_str(), 1071 O_RDONLY | O_BINARY, 0555); 1059 1072 if(stripe1 == -1) 1060 1073 { … … 1062 1075 } 1063 1076 // Open stripe2 1064 stripe2 = ::open(stripe2Filename.c_str(), O_RDONLY, 0555); 1077 stripe2 = ::open(stripe2Filename.c_str(), 1078 O_RDONLY | O_BINARY, 0555); 1065 1079 if(stripe2 == -1) 1066 1080 { … … 1170 1184 if(existingFiles & RaidFileUtil::Stripe1Exists) 1171 1185 { 1172 stripe1 = ::open(stripe1Filename.c_str(), O_RDONLY, 0555); 1186 stripe1 = ::open(stripe1Filename.c_str(), 1187 O_RDONLY | O_BINARY, 0555); 1173 1188 if(stripe1 == -1) 1174 1189 { … … 1179 1194 if(existingFiles & RaidFileUtil::Stripe2Exists) 1180 1195 { 1181 stripe2 = ::open(stripe2Filename.c_str(), O_RDONLY, 0555); 1196 stripe2 = ::open(stripe2Filename.c_str(), 1197 O_RDONLY | O_BINARY, 0555); 1182 1198 if(stripe2 == -1) 1183 1199 { … … 1186 1202 } 1187 1203 // Open parity 1188 parity = ::open(parityFilename.c_str(), O_RDONLY, 0555); 1204 parity = ::open(parityFilename.c_str(), 1205 O_RDONLY | O_BINARY, 0555); 1189 1206 if(parity == -1) 1190 1207 { -
box/chris/merge/lib/raidfile/RaidFileWrite.cpp
r437 r710 105 105 106 106 // Attempt to open 107 mOSFileHandle = ::open(writeFilename.c_str(), O_WRONLY | O_CREAT, 107 mOSFileHandle = ::open(writeFilename.c_str(), 108 O_WRONLY | O_CREAT | O_BINARY, 108 109 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); 109 110 if(mOSFileHandle == -1) … … 116 117 int errnoBlock = EWOULDBLOCK; 117 118 if(::flock(mOSFileHandle, LOCK_EX | LOCK_NB) != 0) 118 #el se119 #elif HAVE_DECL_F_SETLK 119 120 int errnoBlock = EAGAIN; 120 121 struct flock desc; … … 124 125 desc.l_len = 0; 125 126 if(::fcntl(mOSFileHandle, F_SETLK, &desc) != 0) 127 #else 128 int errnoBlock = ENOSYS; 129 if (0) 126 130 #endif 127 131 { … … 243 247 244 248 // Rename it into place -- BEFORE it's closed so lock remains 249 250 #ifdef WIN32 251 // Except on Win32 which doesn't allow renaming open files 252 // Close file... 253 if(::close(mOSFileHandle) != 0) 254 { 255 THROW_EXCEPTION(RaidFileException, OSError) 256 } 257 mOSFileHandle = -1; 258 #endif // WIN32 259 245 260 RaidFileController &rcontroller(RaidFileController::GetController()); 246 261 RaidFileDiscSet rdiscSet(rcontroller.GetDiscSet(mSetNumber)); … … 249 264 // And the current name 250 265 std::string renameFrom(renameTo + 'X'); 266 267 #ifdef WIN32 268 // need to delete the target first 269 if(::unlink(renameTo.c_str()) != 0 && 270 GetLastError() != ERROR_FILE_NOT_FOUND) 271 { 272 THROW_EXCEPTION(RaidFileException, OSError) 273 } 274 #endif 275 251 276 if(::rename(renameFrom.c_str(), renameTo.c_str()) != 0) 252 277 { … … 254 279 } 255 280 281 #ifndef WIN32 256 282 // Close file... 257 283 if(::close(mOSFileHandle) != 0) … … 260 286 } 261 287 mOSFileHandle = -1; 288 #endif // !WIN32 262 289 263 290 // Raid it? … … 293 320 294 321 // Unlink and close it 295 if((::unlink(writeFilename.c_str()) != 0) 296 || (::close(mOSFileHandle) != 0)) 322 323 #ifdef WIN32 324 // On Win32 we must close it first 325 if (::close(mOSFileHandle) != 0 || 326 ::unlink(writeFilename.c_str()) != 0) 327 #else // !WIN32 328 if (::unlink(writeFilename.c_str()) != 0 || 329 ::close(mOSFileHandle) != 0) 330 #endif // !WIN32 297 331 { 298 332 THROW_EXCEPTION(RaidFileException, OSError) … … 389 423 { 390 424 #if HAVE_DECL_O_EXLOCK 391 FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_EXLOCK )> stripe1(stripe1FilenameW.c_str());392 FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_EXLOCK )> stripe2(stripe2FilenameW.c_str());393 FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_EXLOCK )> parity(parityFilenameW.c_str());425 FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_EXLOCK | O_BINARY)> stripe1(stripe1FilenameW.c_str()); 426 FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_EXLOCK | O_BINARY)> stripe2(stripe2FilenameW.c_str()); 427 FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_EXLOCK | O_BINARY)> parity(parityFilenameW.c_str()); 394 428 #else 395 FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL )> stripe1(stripe1FilenameW.c_str());396 FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL )> stripe2(stripe2FilenameW.c_str());397 FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL )> parity(parityFilenameW.c_str());429 FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_BINARY)> stripe1(stripe1FilenameW.c_str()); 430 FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_BINARY)> stripe2(stripe2FilenameW.c_str()); 431 FileHandleGuard<(O_WRONLY | O_CREAT | O_EXCL | O_BINARY)> parity(parityFilenameW.c_str()); 398 432 #endif 399 433 … … 531 565 stripe2.Close(); 532 566 stripe1.Close(); 567 568 #ifdef WIN32 569 // Must delete before renaming 570 #define CHECK_UNLINK(file) \ 571 { \ 572 if (::unlink(file) != 0 && errno != ENOENT) \ 573 { \ 574 THROW_EXCEPTION(RaidFileException, OSError); \ 575 } \ 576 } 577 CHECK_UNLINK(stripe1Filename.c_str()); 578 CHECK_UNLINK(stripe2Filename.c_str()); 579 CHECK_UNLINK(parityFilename.c_str()); 580 #undef CHECK_UNLINK 581 #endif 533 582 534 583 // Rename them into place -
box/chris/merge/lib/server/Daemon.cpp
r456 r710 22 22 #ifdef HAVE_SYSLOG_H 23 23 #include <syslog.h> 24 #endif 25 26 #ifdef WIN32 27 #include <ws2tcpip.h> 24 28 #endif 25 29 … … 143 147 fprintf(stderr, "%s: failed to start: " 144 148 "failed to open configuration file: " 145 "%s ", DaemonName(),149 "%s\n", DaemonName(), 146 150 mConfigFileName.c_str()); 147 151 #ifdef WIN32 … … 190 194 THROW_EXCEPTION(ServerException, DaemoniseFailed) 191 195 } 196 #endif // !WIN32 192 197 193 198 // Server configuration … … 198 203 pidFileName = serverConfig.GetKeyValue("PidFile"); 199 204 FileHandleGuard<(O_WRONLY | O_CREAT | O_TRUNC), (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)> pidFile(pidFileName.c_str()); 200 205 206 #ifndef WIN32 201 207 // Handle changing to a different user 202 208 if(serverConfig.KeyExists("User")) … … 268 274 // open the log 269 275 ::openlog(DaemonName(), LOG_PID, LOG_LOCAL6); 276 270 277 // Log the start message 271 278 ::syslog(LOG_INFO, "Starting daemon (config: %s) (version " 272 279 BOX_VERSION ")", mConfigFileName.c_str()); 273 280 274 #ifndef WIN32275 281 // Write PID to file 276 282 char pid[32]; 283 284 #ifdef WIN32 285 int pidsize = sprintf(pid, "%d", (int)GetCurrentProcessId()); 286 #else 277 287 int pidsize = sprintf(pid, "%d", (int)getpid()); 288 #endif 289 278 290 if(::write(pidFile, pid, pidsize) != pidsize) 279 291 { … … 281 293 THROW_EXCEPTION(ServerException, DaemoniseFailed) 282 294 } 283 #endif284 295 285 296 // Set up memory leak reporting … … 353 364 return 1; 354 365 } 366 367 #ifdef WIN32 368 // Under win32 we must initialise the Winsock library 369 // before using sockets 370 371 WSADATA info; 372 373 if (WSAStartup(0x0101, &info) == SOCKET_ERROR) 374 { 375 // will not run without sockets 376 ::syslog(LOG_ERR, "Failed to initialise Windows Sockets"); 377 THROW_EXCEPTION(CommonException, Internal) 378 } 379 #endif 380 381 int retcode = 0; 355 382 356 383 // Main Daemon running … … 382 409 errors.c_str()); 383 410 // And give up 384 return 1; 411 retcode = 1; 412 break; 385 413 } 386 414 … … 410 438 "(%d/%d)", DaemonName(), e.what(), e.GetType(), 411 439 e.GetSubType()); 412 ret urn1;440 retcode = 1; 413 441 } 414 442 catch(std::exception &e) … … 416 444 ::syslog(LOG_ERR, "%s: terminating due to exception %s", 417 445 DaemonName(), e.what()); 418 ret urn1;446 retcode = 1; 419 447 } 420 448 catch(...) … … 422 450 ::syslog(LOG_ERR, "%s: terminating due to unknown exception", 423 451 DaemonName()); 424 return 1; 425 } 426 427 return 0; 452 retcode = 1; 453 } 454 455 #ifdef WIN32 456 WSACleanup(); 457 #endif 458 459 return retcode; 428 460 } 429 461 -
box/chris/merge/lib/server/ServerStream.h
r217 r710 57 57 } 58 58 59 #ifdef WIN32 60 virtual void OnIdle() { } 61 #endif 62 59 63 virtual void Run() 60 64 { … … 216 220 { 217 221 // Since this is a template parameter, the if() will be optimised out by the compiler 222 #ifndef WIN32 // no fork on Win32 218 223 if(ForkToHandleRequests) 219 224 { … … 256 261 else 257 262 { 263 #endif // !WIN32 258 264 // Just handle in this connection 259 265 SetProcessTitle("handling"); 260 266 HandleConnection(*connection); 261 267 SetProcessTitle("idle"); 262 } 268 #ifndef WIN32 269 } 270 #endif // !WIN32 263 271 } 264 272 } 265 273 274 #ifdef WIN32 275 OnIdle(); 276 #else // !WIN32 266 277 // Clean up child processes (if forking daemon) 267 278 if(ForkToHandleRequests) … … 278 289 } while(p > 0); 279 290 } 291 #endif // !WIN32 280 292 } 281 293 } … … 302 314 bool WillForkToHandleRequests() 303 315 { 316 #ifdef WIN32 317 return false; 318 #else 304 319 return ForkToHandleRequests; 320 #endif // WIN32 305 321 } 306 322 -
box/chris/merge/lib/server/SocketStream.cpp
r457 r710 37 37 // -------------------------------------------------------------------------- 38 38 SocketStream::SocketStream() 39 : mSocketHandle( -1),39 : mSocketHandle(INVALID_SOCKET_VALUE), 40 40 mReadClosed(false), 41 41 mWriteClosed(false), … … 86 86 THROW_EXCEPTION(ServerException, BadSocketHandle); 87 87 } 88 if(mSocketHandle == -1)88 if(mSocketHandle == INVALID_SOCKET_VALUE) 89 89 { 90 90 THROW_EXCEPTION(ServerException, DupError); … … 102 102 SocketStream::~SocketStream() 103 103 { 104 if(mSocketHandle != -1)104 if(mSocketHandle != INVALID_SOCKET_VALUE) 105 105 { 106 106 Close(); … … 118 118 void SocketStream::Attach(int socket) 119 119 { 120 if(mSocketHandle != -1) {THROW_EXCEPTION(ServerException, SocketAlreadyOpen)} 120 if(mSocketHandle != INVALID_SOCKET_VALUE) 121 { 122 THROW_EXCEPTION(ServerException, SocketAlreadyOpen) 123 } 121 124 122 125 mSocketHandle = socket; … … 135 138 void SocketStream::Open(int Type, const char *Name, int Port) 136 139 { 137 if(mSocketHandle != -1) {THROW_EXCEPTION(ServerException, SocketAlreadyOpen)} 140 if(mSocketHandle != INVALID_SOCKET_VALUE) 141 { 142 THROW_EXCEPTION(ServerException, SocketAlreadyOpen) 143 } 138 144 139 145 // Setup parameters based on type, looking up names if required … … 145 151 // Create the socket 146 152 mSocketHandle = ::socket(sockDomain, SOCK_STREAM, 0 /* let OS choose protocol */); 147 if(mSocketHandle == -1)153 if(mSocketHandle == INVALID_SOCKET_VALUE) 148 154 { 149 155 THROW_EXCEPTION(ServerException, SocketOpenError) … … 159 165 ::close(mSocketHandle); 160 166 #endif 161 mSocketHandle = -1;167 mSocketHandle = INVALID_SOCKET_VALUE; 162 168 THROW_EXCEPTION(ConnectionException, Conn_SocketConnectError) 163 169 } … … 175 181 int SocketStream::Read(void *pBuffer, int NBytes, int Timeout) 176 182 { 177 if(mSocketHandle == -1) {THROW_EXCEPTION(ServerException, BadSocketHandle)} 183 if(mSocketHandle == INVALID_SOCKET_VALUE) 184 { 185 THROW_EXCEPTION(ServerException, BadSocketHandle) 186 } 178 187 179 188 if(Timeout != IOStream::TimeOutInfinite) … … 248 257 void SocketStream::Write(const void *pBuffer, int NBytes) 249 258 { 250 if(mSocketHandle == -1) {THROW_EXCEPTION(ServerException, BadSocketHandle)} 259 if(mSocketHandle == INVALID_SOCKET_VALUE) 260 { 261 THROW_EXCEPTION(ServerException, BadSocketHandle) 262 } 251 263 252 264 // Buffer in byte sized type. … … 312 324 void SocketStream::Close() 313 325 { 314 if(mSocketHandle == -1) {THROW_EXCEPTION(ServerException, BadSocketHandle)} 326 if(mSocketHandle == INVALID_SOCKET_VALUE) 327 { 328 THROW_EXCEPTION(ServerException, BadSocketHandle) 329 } 315 330 #ifdef WIN32 316 331 if(::closesocket(mSocketHandle) == -1) … … 321 336 THROW_EXCEPTION(ServerException, SocketCloseError) 322 337 } 323 mSocketHandle = -1;338 mSocketHandle = INVALID_SOCKET_VALUE; 324 339 } 325 340 … … 334 349 void SocketStream::Shutdown(bool Read, bool Write) 335 350 { 336 if(mSocketHandle == -1) {THROW_EXCEPTION(ServerException, BadSocketHandle)} 351 if(mSocketHandle == INVALID_SOCKET_VALUE) 352 { 353 THROW_EXCEPTION(ServerException, BadSocketHandle) 354 } 337 355 338 356 // Do anything? … … 389 407 tOSSocketHandle SocketStream::GetSocketHandle() 390 408 { 391 if(mSocketHandle == -1) {THROW_EXCEPTION(ServerException, BadSocketHandle)} 409 if(mSocketHandle == INVALID_SOCKET_VALUE) 410 { 411 THROW_EXCEPTION(ServerException, BadSocketHandle) 412 } 392 413 return mSocketHandle; 393 414 } -
box/chris/merge/lib/server/SocketStream.h
r457 r710 15 15 #ifdef WIN32 16 16 typedef SOCKET tOSSocketHandle; 17 #define INVALID_SOCKET_VALUE (tOSSocketHandle)(-1) 17 18 #else 18 19 typedef int tOSSocketHandle; 20 #define INVALID_SOCKET_VALUE -1 19 21 #endif 20 22 -
box/chris/merge/lib/server/SocketStreamTLS.cpp
r457 r710 138 138 } 139 139 140 #ifndef WIN32141 140 // Make the socket non-blocking so timeouts on Read work 141 142 #ifdef WIN32 143 u_long nonblocking = 1; 144 ioctlsocket(socket, FIONBIO, &nonblocking); 145 #else // !WIN32 142 146 // This is more portable than using ioctl with FIONBIO 143 147 int statusFlags = 0; … … 310 314 case SSL_ERROR_WANT_READ: 311 315 case SSL_ERROR_WANT_WRITE: 312 // wait for the requ ried data316 // wait for the required data 313 317 // Will only get once around this loop, so don't need to calculate timeout values 314 318 if(WaitWhenRetryRequired(se, Timeout) == false) -
box/chris/merge/lib/server/makeprotocol.pl.in
r537 r710 1 1 #!@PERL@ 2 2 use strict; 3 4 use lib "../../infrastructure"; 5 use BoxPlatform; 3 6 4 7 # Make protocol C++ classes from a protocol description file … … 168 171 # open files 169 172 my $h_filename = 'autogen_'.$protocol_name.'Protocol'.$type.'.h'; 170 open CPP,'>autogen_'.$protocol_name.'Protocol'.$type.'.cpp ';171 open H,">$h_filename ";173 open CPP,'>autogen_'.$protocol_name.'Protocol'.$type.'.cpp.new'; 174 open H,">$h_filename.new"; 172 175 173 176 print CPP <<__E; … … 913 916 close CPP; 914 917 918 update_if_changed('autogen_'.$protocol_name.'Protocol'.$type.'.cpp'); 919 update_if_changed($h_filename); 915 920 916 921 sub obj_is_type … … 982 987 # need to translate it 983 988 my ($format,$arg) = @{$log_display_types{$ty}}; 989 $arg =~ s/VAR/m$nm/g; 990 991 if ($format eq "0x%llx" and $target_windows) 992 { 993 $format = "0x%I64x"; 994 $arg = "(uint64_t)$arg"; 995 } 996 984 997 push @str,$format; 985 $arg =~ s/VAR/m$nm/g;986 998 push @arg,$arg; 987 999 } -
box/chris/merge/runtest.pl.in
r537 r710 1 1 #!@PERL@ 2 3 use strict; 4 use warnings; 2 5 3 6 use lib 'infrastructure'; … … 6 9 my ($test_name,$test_mode) = @ARGV; 7 10 8 $test_mode = 'debug' if $test_mode eq '';11 $test_mode = 'debug' if not defined $test_mode or $test_mode eq ''; 9 12 10 13 if($test_name eq '' || ($test_mode ne 'debug' && $test_mode ne 'release')) … … 18 21 19 22 __E 20 exit( 0);23 exit(2); 21 24 } 22 25 23 26 my @results; 27 my $exit_code = 0; 24 28 25 29 if($test_name ne 'ALL') 26 30 { 27 # run one test 28 runtest($test_name); 31 # run one or more specified test 32 if ($test_name =~ m/,/) 33 { 34 foreach my $test (split m/,/, $test_name) 35 { 36 runtest($test); 37 } 38 } 39 else 40 { 41 runtest($test_name); 42 } 29 43 } 30 44 else … … 58 72 print "--------\n",join("\n",@results),"\n"; 59 73 74 exit $exit_code; 75 60 76 sub runtest 61 77 { … … 68 84 { 69 85 push @results,"$t: make failed"; 86 $exit_code = 2; 70 87 return; 71 88 } … … 83 100 } 84 101 close RESULTS; 102 85 103 chomp $last; 86 104 push @results,"$t: $last"; 105 106 if ($last ne "PASSED") 107 { 108 $exit_code = 1; 109 } 87 110 } 88 111 else -
box/chris/merge/test/backupdiff/testbackupdiff.cpp
r356 r710 67 67 void make_file_of_zeros(const char *filename, size_t size) 68 68 { 69 static const size_t bs = 0x10000; 70 size_t remSize = size; 71 void *b = malloc(bs); 72 memset(b, 0, bs); 73 FILE *f = fopen(filename, "wb"); 74 75 // Using largish blocks like this is much faster, while not consuming too much RAM 76 while(remSize > bs) 77 { 78 fwrite(b, bs, 1, f); 79 remSize -= bs; 80 } 81 fwrite(b, remSize, 1, f); 82 83 fclose(f); 84 free(b); 69 #ifdef WIN32 70 HANDLE handle = openfile(filename, O_WRONLY | O_CREAT | O_EXCL, 0); 71 TEST_THAT(handle != INVALID_HANDLE_VALUE); 72 SetFilePointer(handle, size, NULL, FILE_BEGIN); 73 TEST_THAT(GetLastError() == NO_ERROR); 74 TEST_THAT(SetEndOfFile(handle) == true); 75 TEST_THAT(CloseHandle(handle) == true); 76 #else 77 int fd = open(filename, O_WRONLY | O_CREAT | O_EXCL, 0600); 78 if (fd < 0) perror(filename); 79 TEST_THAT(fd >= 0); 80 TEST_THAT(ftruncate(fd, size) == 0); 81 TEST_THAT(close(fd) == 0); 82 #endif 85 83 86 84 TEST_THAT((size_t)TestGetFileSize(filename) == size); … … 119 117 { 120 118 nnew++; 119 #ifdef WIN32 120 TRACE2("%8I64d this s=%8I64d", b, s); 121 #else 121 122 TRACE2("%8lld this s=%8lld", b, s); 123 #endif 122 124 } 123 125 else 124 126 { 125 127 nold++; 128 #ifdef WIN32 129 TRACE2("%8I64d other i=%8I64d", b, 0 - s); 130 #else 126 131 TRACE2("%8lld other i=%8lld", b, 0 - s); 132 #endif 127 133 } 128 134 // Decode the rest … … 208 214 else 209 215 { 216 #ifdef WIN32 217 // Emulate the above stage! 218 char src[256], dst[256]; 219 sprintf(src, "testfiles\\f%d.diff", to); 220 sprintf(dst, "testfiles\\f%d.encoded", to); 221 TEST_THAT(CopyFile(src, dst, FALSE) != 0) 222 #else 210 223 // Emulate the above stage! 211 224 char cmd[256]; 212 225 sprintf(cmd, "cp testfiles/f%d.diff testfiles/f%d.encoded", to, to); 213 226 ::system(cmd); 227 #endif 214 228 } 215 229 … … 356 370 // Want to trace out all the details 357 371 #ifndef NDEBUG 372 #ifndef WIN32 358 373 BackupStoreFile::TraceDetailsOfDiffProcess = true; 374 #endif 359 375 #endif 360 376 … … 371 387 std::auto_ptr<IOStream> encoded(BackupStoreFile::EncodeFile("testfiles/f0", 1 /* dir ID */, f0name)); 372 388 encoded->CopyStreamTo(out); 389 out.Close(); 373 390 check_encoded_file("testfiles/f0.encoded", 0, 33, 0); 374 391 } … … 431 448 std::auto_ptr<IOStream> encoded(BackupStoreFile::EncodeFile("testfiles/f9", 1 /* dir ID */, fn)); 432 449 encoded->CopyStreamTo(out); 450 out.Close(); 433 451 check_encoded_file("testfiles/f9.zerotest", 0, 0, 0); 434 452 } … … 441 459 } 442 460 461 #ifndef WIN32 443 462 // Check that symlinks aren't diffed 444 463 TEST_THAT(::symlink("f2", "testfiles/f2.symlink") == 0) … … 468 487 check_encoded_file("testfiles/f2.symlink.diff", 0, 0, 0); 469 488 } 470 471 // Check that diffing against a file which isn't "complete" and referes another isn't allowed 489 #endif 490 491 // Check that diffing against a file which isn't "complete" and 492 // references another isn't allowed 472 493 { 473 494 FileStream blockindex("testfiles/f1.diff"); … … 481 502 } 482 503 483 // Found a nasty case where files of lots of the same thing sock up lots of processor 484 // time -- because of lots of matches found. Check this out! 504 // Found a nasty case where files of lots of the same thing 505 // suck up lots of processor time -- because of lots of matches 506 // found. Check this out! 507 508 #ifdef WIN32 509 ::fprintf(stdout, "Testing diffing two large streams, " 510 "may take a while!\n"); 511 ::fflush(stdout); 512 #endif 513 485 514 make_file_of_zeros("testfiles/zero.0", 20*1024*1024); 486 515 make_file_of_zeros("testfiles/zero.1", 200*1024*1024); 516 487 517 // Generate a first encoded file 488 518 { … … 504 534 0, 0)); 505 535 encoded->CopyStreamTo(out); 536 537 printf("Time taken: %d seconds\n", (int)(time(0) - beginTime)); 538 539 #ifdef WIN32 540 TEST_THAT(time(0) < (beginTime + 300)); 541 #else 506 542 TEST_THAT(time(0) < (beginTime + 40)); 543 #endif 507 544 } 508 545 // Remove zero-files to save disk space -
box/chris/merge/test/backupstore/testbackupstore.cpp
r341 r710 426 426 427 427 free(data); 428 unlink("testfiles/test_download"); 428 in.Close(); 429 TEST_THAT(unlink("testfiles/test_download") == 0); 429 430 } 430 431 … … 931 932 TEST_THAT(loginConf->GetClientStoreMarker() == 0); 932 933 934 #ifndef WIN32 933 935 // Check that we can't open a new connection which requests write permissions 934 936 { … … 942 944 protocol.QueryFinished(); 943 945 } 946 #endif 944 947 945 948 // Set the client store marker 946 949 protocol.QuerySetClientStoreMarker(0x8732523ab23aLL); 947 950 951 #ifndef WIN32 948 952 // Open a new connection which is read only 949 953 SocketStreamTLS connReadOnly; … … 964 968 TEST_THAT(loginConf->GetClientStoreMarker() == 0x8732523ab23aLL); 965 969 } 970 #else // WIN32 971 BackupProtocolClient& protocolReadOnly(protocol); 972 #endif 966 973 967 974 test_server_1(protocol, protocolReadOnly); 968 969 970 975 // Create and upload some test files 971 976 int64_t maxID = 0; … … 1439 1444 1440 1445 // Finish the connections 1446 #ifndef WIN32 1441 1447 protocolReadOnly.QueryFinished(); 1448 #endif 1442 1449 protocol.QueryFinished(); 1443 1450 1444 1451 // Close logs 1452 #ifndef WIN32 1445 1453 ::fclose(protocolReadOnlyLog); 1454 #endif 1446 1455 ::fclose(protocolLog); 1447 1456 } … … 1521 1530 // The test block to a file 1522 1531 { 1523 FileStream f("testfiles/testenc1", O_WRONLY | O_CREAT | O_EXCL); 1532 FileStream f("testfiles" DIRECTORY_SEPARATOR 1533 "testenc1", O_WRONLY | O_CREAT | O_EXCL); 1524 1534 f.Write(encfile, sizeof(encfile)); 1525 1535 } … … 1527 1537 // Encode it 1528 1538 { 1529 FileStream out("testfiles/testenc1_enc", O_WRONLY | O_CREAT | O_EXCL); 1530 BackupStoreFilenameClear name("testfiles/testenc1"); 1531 1532 std::auto_ptr<IOStream> encoded(BackupStoreFile::EncodeFile("testfiles/testenc1", 32, name)); 1539 FileStream out("testfiles" DIRECTORY_SEPARATOR 1540 "testenc1_enc", O_WRONLY | O_CREAT | O_EXCL); 1541 BackupStoreFilenameClear name("testfiles" 1542 DIRECTORY_SEPARATOR "testenc1"); 1543 1544 std::auto_ptr<IOStream> encoded( 1545 BackupStoreFile::EncodeFile( 1546 "testfiles" DIRECTORY_SEPARATOR 1547 "testenc1", 32, name)); 1533 1548 encoded->CopyStreamTo(out); 1534 1549 } … … 1536 1551 // Verify it 1537 1552 { 1538 FileStream enc("testfiles/testenc1_enc"); 1553 FileStream enc("testfiles" DIRECTORY_SEPARATOR 1554 "testenc1_enc"); 1539 1555 TEST_THAT(BackupStoreFile::VerifyEncodedFileFormat(enc) == true); 1540 1556 } … … 1542 1558 // Decode it 1543 1559 { 1544 FileStream enc("testfiles/testenc1_enc"); 1545 BackupStoreFile::DecodeFile(enc, "testfiles/testenc1_orig", IOStream::TimeOutInfinite); 1560 FileStream enc("testfiles" DIRECTORY_SEPARATOR 1561 "testenc1_enc"); 1562 BackupStoreFile::DecodeFile(enc, "testfiles" 1563 DIRECTORY_SEPARATOR "testenc1_orig", 1564 IOStream::TimeOutInfinite); 1546 1565 } 1547 1566 1548 1567 // Read in rebuilt original, and compare contents 1549 1568 { 1550 TEST_THAT(TestGetFileSize("testfiles/testenc1_orig") == sizeof(encfile)); 1551 FileStream in("testfiles/testenc1_orig"); 1569 TEST_THAT(TestGetFileSize("testfiles" 1570 DIRECTORY_SEPARATOR "testenc1_orig") 1571 == sizeof(encfile)); 1572 FileStream in("testfiles" DIRECTORY_SEPARATOR 1573 "testenc1_orig"); 1552 1574 int encfile_i[ENCFILE_SIZE]; 1553 1575 in.Read(encfile_i, sizeof(encfile_i)); … … 1557 1579 // Check how many blocks it had, and test the stream based interface 1558 1580 { 1559 FileStream enc("testfiles/testenc1_enc"); 1581 FileStream enc("testfiles" DIRECTORY_SEPARATOR 1582 "testenc1_enc"); 1560 1583 std::auto_ptr<BackupStoreFile::DecodedStream> decoded(BackupStoreFile::DecodeFileStream(enc, IOStream::TimeOutInfinite)); 1561 1584 CollectInBufferStream d; … … 1571 1594 { 1572 1595 #define FILE_SIZE_JUST_OVER ((4096*2)+58) 1573 FileStream f("testfiles/testenc2", O_WRONLY | O_CREAT | O_EXCL); 1596 FileStream f("testfiles" DIRECTORY_SEPARATOR 1597 "testenc2", O_WRONLY | O_CREAT | O_EXCL); 1574 1598 f.Write(encfile + 2, FILE_SIZE_JUST_OVER); 1599 f.Close(); 1575 1600 BackupStoreFilenameClear name("testenc2"); 1576 std::auto_ptr<IOStream> encoded(BackupStoreFile::EncodeFile("testfiles/testenc2", 32, name)); 1601 std::auto_ptr<IOStream> encoded( 1602 BackupStoreFile::EncodeFile( 1603 "testfiles" DIRECTORY_SEPARATOR 1604 "testenc2", 32, name)); 1577 1605 CollectInBufferStream e; 1578 1606 encoded->CopyStreamTo(e); … … 1590 1618 // Test that reordered streams work too 1591 1619 { 1592 FileStream enc("testfiles/testenc1_enc"); 1620 FileStream enc("testfiles" DIRECTORY_SEPARATOR 1621 "testenc1_enc"); 1593 1622 std::auto_ptr<IOStream> reordered(BackupStoreFile::ReorderFileToStreamOrder(&enc, false)); 1594 1623 std::auto_ptr<BackupStoreFile::DecodedStream> decoded(BackupStoreFile::DecodeFileStream(*reordered, IOStream::TimeOutInfinite)); … … 1602 1631 } 1603 1632 1633 #ifndef WIN32 1604 1634 // Try out doing this on a symlink 1605 1635 { … … 1615 1645 BackupStoreFile::DecodeFile(b, "testfiles/testsymlink_2", IOStream::TimeOutInfinite); 1616 1646 } 1647 #endif 1617 1648 } 1618 1649 … … 1620 1651 { 1621 1652 RaidFileWrite::CreateDirectory(0, "test-info"); 1622 BackupStoreInfo::CreateNew(76, "test-info/", 0, 3461231233455433LL, 2934852487LL); 1623 TEST_CHECK_THROWS(BackupStoreInfo::CreateNew(76, "test-info/", 0, 0, 0), RaidFileException, CannotOverwriteExistingFile); 1624 std::auto_ptr<BackupStoreInfo> info(BackupStoreInfo::Load(76, "test-info/", 0, true)); 1653 BackupStoreInfo::CreateNew(76, "test-info" DIRECTORY_SEPARATOR, 1654 0, 3461231233455433LL, 2934852487LL); 1655 TEST_CHECK_THROWS(BackupStoreInfo::CreateNew(76, 1656 "test-info" DIRECTORY_SEPARATOR, 0, 0, 0), 1657 RaidFileException, CannotOverwriteExistingFile); 1658 std::auto_ptr<BackupStoreInfo> info( 1659 BackupStoreInfo::Load(76, 1660 "test-info" DIRECTORY_SEPARATOR, 0, true)); 1625 1661 TEST_CHECK_THROWS(info->Save(), BackupStoreException, StoreInfoIsReadOnly); 1626 1662 TEST_CHECK_THROWS(info->ChangeBlocksUsed(1), BackupStoreException, StoreInfoIsReadOnly); … … 1631 1667 } 1632 1668 { 1633 std::auto_ptr<BackupStoreInfo> info(BackupStoreInfo::Load(76, "test-info/", 0, false)); 1669 std::auto_ptr<BackupStoreInfo> info(BackupStoreInfo::Load(76, 1670 "test-info" DIRECTORY_SEPARATOR, 0, false)); 1634 1671 info->ChangeBlocksUsed(8); 1635 1672 info->ChangeBlocksInOldFiles(9); … … 1649 1686 } 1650 1687 { 1651 std::auto_ptr<BackupStoreInfo> info(BackupStoreInfo::Load(76, "test-info/", 0, true)); 1688 std::auto_ptr<BackupStoreInfo> info(BackupStoreInfo::Load(76, 1689 "test-info" DIRECTORY_SEPARATOR, 0, true)); 1652 1690 TEST_THAT(info->GetBlocksUsed() == 7); 1653 1691 TEST_THAT(info->GetBlocksInOldFiles() == 5); … … 1667 1705 TLSContext context; 1668 1706 context.Initialise(false /* client */, 1669 "testfiles /clientCerts.pem",1670 "testfiles /clientPrivKey.pem",1671 "testfiles /clientTrustedCAs.pem");1707 "testfiles" DIRECTORY_SEPARATOR "clientCerts.pem", 1708 "testfiles" DIRECTORY_SEPARATOR "clientPrivKey.pem", 1709 "testfiles" DIRECTORY_SEPARATOR "clientTrustedCAs.pem"); 1672 1710 1673 1711 // First, try logging in without an account having been created... just make sure login fails. 1712 1713 #ifdef WIN32 1714 int pid = LaunchServer("..\\..\\bin\\bbstored\\bbstored testfiles/bbstored.conf", "testfiles/bbstored.pid"); 1715 #else 1674 1716 int pid = LaunchServer("../../bin/bbstored/bbstored testfiles/bbstored.conf", "testfiles/bbstored.pid"); 1717 #endif 1718 1675 1719 TEST_THAT(pid != -1 && pid != 0); 1676 1720 if(pid > 0) … … 1701 1745 1702 1746 // Create an account for the test client 1747 #ifdef WIN32 1748 TEST_THAT_ABORTONFAIL(::system("..\\..\\bin\\bbstoreaccounts\\bbstoreaccounts -c testfiles/bbstored.conf create 01234567 0 10000B 20000B") == 0); 1749 #else 1703 1750 TEST_THAT_ABORTONFAIL(::system("../../bin/bbstoreaccounts/bbstoreaccounts -c testfiles/bbstored.conf create 01234567 0 10000B 20000B") == 0); 1704 1751 TestRemoteProcessMemLeaks("bbstoreaccounts.memleaks"); 1752 #endif 1753 1705 1754 TEST_THAT(TestDirExists("testfiles/0_0/backup/01234567")); 1706 1755 TEST_THAT(TestDirExists("testfiles/0_1/backup/01234567")); … … 1726 1775 ::sleep(1); 1727 1776 TEST_THAT(!ServerIsAlive(pid)); 1777 #ifndef WIN32 1728 1778 TestRemoteProcessMemLeaks("bbstored.memleaks"); 1779 #endif 1729 1780 1730 1781 // Set a new limit on the account -- leave the hard limit high to make sure the target for 1731 1782 // freeing space is the soft limit. 1783 1784 #ifdef WIN32 1785 TEST_THAT_ABORTONFAIL(::system("..\\..\\bin\\bbstoreaccounts\\bbstoreaccounts -c testfiles/bbstored.conf setlimit 01234567 10B 20000B") == 0); 1786 #else 1732 1787 TEST_THAT_ABORTONFAIL(::system("../../bin/bbstoreaccounts/bbstoreaccounts -c testfiles/bbstored.conf setlimit 01234567 10B 20000B") == 0); 1733 1788 TestRemoteProcessMemLeaks("bbstoreaccounts.memleaks"); 1789 #endif 1734 1790 1735 1791 // Start things up 1792 #ifdef WIN32 1793 pid = LaunchServer("..\\..\\bin\\bbstored\\bbstored testfiles/bbstored.conf", "testfiles/bbstored.pid"); 1794 #else 1736 1795 pid = LaunchServer("../../bin/bbstored/bbstored testfiles/bbstored.conf", "testfiles/bbstored.pid"); 1796 #endif 1797 1737 1798 ::sleep(1); 1738 1799 TEST_THAT(ServerIsAlive(pid)); … … 1759 1820 1760 1821 // Set a really small hard limit 1822 #ifdef WIN32 1823 TEST_THAT_ABORTONFAIL(::system("..\\..\\bin\\bbstoreaccounts\\bbstoreaccounts -c testfiles/bbstored.conf setlimit 01234567 10B 20B") == 0); 1824 #else 1761 1825 TEST_THAT_ABORTONFAIL(::system("../../bin/bbstoreaccounts/bbstoreaccounts -c testfiles/bbstored.conf setlimit 01234567 10B 20B") == 0); 1762 1826 TestRemoteProcessMemLeaks("bbstoreaccounts.memleaks"); 1827 #endif 1763 1828 1764 1829 // Try to upload a file and create a directory, and check an error is generated … … 1809 1874 ::sleep(1); 1810 1875 TEST_THAT(!ServerIsAlive(pid)); 1876 1877 #ifndef WIN32 1811 1878 TestRemoteProcessMemLeaks("bbstored.memleaks"); 1879 #endif 1812 1880 } 1813 1881 … … 1821 1889 // Create an account for the test client 1822 1890 TEST_THAT_ABORTONFAIL(::system("../../bin/bbstoreaccounts/bbstoreaccounts -c testfiles/bbstored.conf create 01234567 0 30000B 40000B") == 0); 1891 1892 #ifndef WIN32 1823 1893 TestRemoteProcessMemLeaks("bbstoreaccounts.memleaks"); 1894 #endif 1824 1895 1825 1896 // First, try logging in without an account having been created... just make sure login fails. 1897 1898 #ifdef WIN32 1899 int pid = LaunchServer("..\\..\\bin\\bbstored\\bbstored testfiles/bbstored_multi.conf", "testfiles/bbstored.pid"); 1900 #else 1826 1901 int pid = LaunchServer("../../bin/bbstored/bbstored testfiles/bbstored_multi.conf", "testfiles/bbstored.pid"); 1902 #endif 1903 1827 1904 TEST_THAT(pid != -1 && pid != 0); 1828 1905 if(pid > 0) … … 1841 1918 ::sleep(1); 1842 1919 TEST_THAT(!ServerIsAlive(pid)); 1920 #ifndef WIN32 1843 1921 TestRemoteProcessMemLeaks("bbstored.memleaks"); 1922 #endif 1844 1923 } 1845 1924 … … 1848 1927 } 1849 1928 1929 #ifdef WIN32 1930 WCHAR* ConvertUtf8ToWideString(const char* pString); 1931 std::string ConvertPathToAbsoluteUnicode(const char *pFileName); 1932 #endif 1933 1850 1934 int test(int argc, const char *argv[]) 1851 1935 { 1936 #ifdef WIN32 1937 // Under win32 we must initialise the Winsock library 1938 // before using sockets 1939 1940 WSADATA info; 1941 TEST_THAT(WSAStartup(0x0101, &info) != SOCKET_ERROR) 1942 1943 // this had better work, or bbstored will die when combining diffs 1944 char* file = "foo"; 1945 std::string abs = ConvertPathToAbsoluteUnicode(file); 1946 WCHAR* wfile = ConvertUtf8ToWideString(abs.c_str()); 1947 1948 DWORD accessRights = FILE_READ_ATTRIBUTES | 1949 FILE_LIST_DIRECTORY | FILE_READ_EA | FILE_WRITE_ATTRIBUTES | 1950 FILE_WRITE_DATA | FILE_WRITE_EA /*| FILE_ALL_ACCESS*/; 1951 DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; 1952 1953 HANDLE h1 = CreateFileW(wfile, accessRights, shareMode, 1954 NULL, OPEN_ALWAYS, FILE_FLAG_BACKUP_SEMANTICS, NULL); 1955 assert(h1 != INVALID_HANDLE_VALUE); 1956 TEST_THAT(h1 != INVALID_HANDLE_VALUE); 1957 1958 accessRights = FILE_READ_ATTRIBUTES | 1959 FILE_LIST_DIRECTORY | FILE_READ_EA; 1960 1961 HANDLE h2 = CreateFileW(wfile, accessRights, shareMode, 1962 NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); 1963 assert(h2 != INVALID_HANDLE_VALUE); 1964 TEST_THAT(h2 != INVALID_HANDLE_VALUE); 1965 1966 CloseHandle(h2); 1967 CloseHandle(h1); 1968 1969 h1 = openfile("foo", O_CREAT | O_RDWR, 0); 1970 TEST_THAT(h1 != INVALID_HANDLE_VALUE); 1971 h2 = openfile("foo", O_RDWR, 0); 1972 TEST_THAT(h2 != INVALID_HANDLE_VALUE); 1973 CloseHandle(h2); 1974 CloseHandle(h1); 1975 #endif 1976 1852 1977 // SSL library 1853 1978 SSLLib::Initialise(); … … 1866 1991 // Use the setup crypto command to set up all these keys, so that the bbackupquery command can be used 1867 1992 // for seeing what's going on. 1993 #ifdef WIN32 1994 BackupClientCryptoKeys_Setup("testfiles\\bbackupd.keys"); 1995 #else 1868 1996 BackupClientCryptoKeys_Setup("testfiles/bbackupd.keys"); 1997 #endif 1869 1998 1870 1999 // encode in some filenames -- can't do static initialisation because the key won't be set up when these are initialised -
box/chris/merge/test/backupstorefix/testfiles/testbackupstorefix.pl.in
r537 r710 55 55 while(<INITIAL>) 56 56 { 57 chomp; 57 chomp; s/\r//; 58 58 $expected{$_} = 1; 59 59 m/\A(.+?) .+? (.+)\Z/; … … 100 100 { 101 101 print LISTING_COPY; 102 chomp; 102 chomp; s/\r//; 103 103 s/\[FILENAME NOT ENCRYPTED\]//; 104 104 if(exists $expected{$_}) -
box/chris/merge/test/backupstorepatch/testbackupstorepatch.cpp
r341 r710 284 284 int test(int argc, const char *argv[]) 285 285 { 286 #ifdef WIN32 287 // Under win32 we must initialise the Winsock library 288 // before using sockets 289 290 WSADATA info; 291 TEST_THAT(WSAStartup(0x0101, &info) != SOCKET_ERROR) 292 #endif 293 286 294 // Allocate a buffer 287 295 buffer = ::malloc(BUFFER_SIZE); … … 310 318 311 319 // Create an account 320 #ifdef WIN32 321 TEST_THAT_ABORTONFAIL(::system("..\\..\\bin\\bbstoreaccounts\\bbstoreaccounts -c testfiles/bbstored.conf create 01234567 0 30000B 40000B") == 0); 322 #else 312 323 TEST_THAT_ABORTONFAIL(::system("../../bin/bbstoreaccounts/bbstoreaccounts -c testfiles/bbstored.conf create 01234567 0 30000B 40000B") == 0); 313 324 TestRemoteProcessMemLeaks("bbstoreaccounts.memleaks"); 325 #endif 314 326 315 327 // Create test files … … 320 332 321 333 // First, try logging in without an account having been created... just make sure login fails. 334 #ifdef WIN32 335 int pid = LaunchServer("..\\..\\bin\\bbstored\\bbstored testfiles/bbstored.conf", "testfiles/bbstored.pid"); 336 #else 322 337 int pid = LaunchServer("../../bin/bbstored/bbstored testfiles/bbstored.conf", "testfiles/bbstored.pid"); 338 #endif 339 323 340 TEST_THAT(pid != -1 && pid != 0); 324 341 if(pid > 0) … … 398 415 test_files[f].IDOnServer = stored->GetObjectID(); 399 416 test_files[f].IsCompletelyDifferent = isCompletelyDifferent; 400 printf("ID %lld, completely different: %s\n", test_files[f].IDOnServer, 417 418 #ifdef WIN32 419 printf("ID %I64d, completely different: %s\n", 420 #else 421 printf("ID %lld, completely different: %s\n", 422 #endif 423 test_files[f].IDOnServer, 401 424 test_files[f].IsCompletelyDifferent?"yes":"no"); 402 425 } … … 566 589 } 567 590 568 // Send the server a restart signal, so it does housekeeping immedaitely, and wait for it to happen 591 #ifdef WIN32 592 wait_for_operation(12); 593 #else 594 // Send the server a restart signal, so it does housekeeping immediately, and wait for it to happen 569 595 ::sleep(1); // wait for old connections to terminate 570 596 ::kill(pid, SIGHUP); 597 #endif 598 571 599 // Get the revision number of the info file 572 600 int64_t first_revision = 0; … … 612 640 TEST_THAT(KillServer(pid)); 613 641 TEST_THAT(!ServerIsAlive(pid)); 642 643 #ifndef WIN32 614 644 TestRemoteProcessMemLeaks("bbstored.memleaks"); 645 #endif 615 646 } 616 647 -
box/chris/merge/test/basicserver/TestCommands.cpp
r217 r710 2 2 #include "Box.h" 3 3 4 #ifdef HAVE_SYSLOG_H 4 5 #include <syslog.h> 6 #endif 5 7 6 8 #include "autogen_TestProtocolServer.h" -
box/chris/merge/test/basicserver/testbasicserver.cpp
r217 r710 32 32 #include "MemLeakFindOn.h" 33 33 34 35 34 #define SERVER_LISTEN_PORT 2003 36 35 … … 63 62 void testservers_pause_before_reply() 64 63 { 65 struct timespec t; 66 t.tv_sec = 0; 67 t.tv_nsec = COMMS_SERVER_WAIT_BEFORE_REPLYING * 1000 * 1000; // convert to ns 68 ::nanosleep(&t, NULL); 64 #ifdef WIN32 65 Sleep(COMMS_SERVER_WAIT_BEFORE_REPLYING); 66 #else 67 struct timespec t; 68 t.tv_sec = 0; 69 t.tv_nsec = COMMS_SERVER_WAIT_BEFORE_REPLYING * 1000 * 1000; // convert to ns 70 ::nanosleep(&t, NULL); 71 #endif 69 72 } 70 73 … … 428 431 } 429 432 433 #ifdef WIN32 434 // Under win32 we must initialise the Winsock library 435 // before using sockets 436 437 WSADATA info; 438 TEST_THAT(WSAStartup(0x0101, &info) != SOCKET_ERROR) 439 #endif 440 430 441 //printf("SKIPPING TESTS------------------------\n"); 431 442 //goto protocolserver; … … 433 444 // Launch a basic server 434 445 { 435 int pid = LaunchServer("./test srv1 testfiles/srv1.conf", "testfiles/srv1.pid"); 446 #ifdef WIN32 447 int pid = LaunchServer("test srv1 testfiles\\srv1.conf", 448 "testfiles\\srv1.pid"); 449 #else 450 int pid = LaunchServer("./test srv1 testfiles/srv1.conf", 451 "testfiles/srv1.pid"); 452 #endif 453 436 454 TEST_THAT(pid != -1 && pid != 0); 437 455 if(pid > 0) 438 456 { 439 457 // Check that it's written the expected file 440 TEST_THAT(TestFileExists("testfiles/srv1.test1")); 458 TEST_THAT(TestFileExists("testfiles" 459 DIRECTORY_SEPARATOR "srv1.test1")); 441 460 TEST_THAT(ServerIsAlive(pid)); 442 461 // Move the config file over 443 TEST_THAT(::rename("testfiles/srv1b.conf", "testfiles/srv1.conf") != -1); 462 #ifdef WIN32 463 TEST_THAT(::unlink("testfiles" DIRECTORY_SEPARATOR 464 "srv1.conf") != -1); 465 #endif 466 TEST_THAT(::rename( 467 "testfiles" DIRECTORY_SEPARATOR "srv1b.conf", 468 "testfiles" DIRECTORY_SEPARATOR "srv1.conf") 469 != -1); 470 #ifndef WIN32 444 471 // Get it to reread the config file 445 472 TEST_THAT(HUPServer(pid)); … … 447 474 TEST_THAT(ServerIsAlive(pid)); 448 475 // Check that new file exists 449 TEST_THAT(TestFileExists("testfiles/srv1.test2")); 476 TEST_THAT(TestFileExists("testfiles" 477 DIRECTORY_SEPARATOR "srv1.test2")); 478 #endif // !WIN32 450 479 // Kill it off 451 480 TEST_THAT(KillServer(pid)); 481 #ifndef WIN32 452 482 TestRemoteProcessMemLeaks("generic-daemon.memleaks"); 483 #endif // !WIN32 453 484 } 454 485 } … … 456 487 // Launch a test forking server 457 488 { 458 int pid = LaunchServer("./test srv2 testfiles/srv2.conf", "testfiles/srv2.pid"); 489 #ifdef WIN32 490 int pid = LaunchServer("test srv2 testfiles\\srv2.conf", 491 "testfiles\\srv2.pid"); 492 #else 493 int pid = LaunchServer("./test srv2 testfiles/srv2.conf", 494 "testfiles/srv2.pid"); 495 #endif 496 459 497 TEST_THAT(pid != -1 && pid != 0); 460 498 if(pid > 0) … … 462 500 // Will it restart? 463 501 TEST_THAT(ServerIsAlive(pid)); 502 #ifndef WIN32 464 503 TEST_THAT(HUPServer(pid)); 465 504 ::sleep(1); 466 505 TEST_THAT(ServerIsAlive(pid)); 506 #endif // !WIN32 467 507 // Make some connections 468 508 { 469 509 SocketStream conn1; 470 510 conn1.Open(Socket::TypeINET, "localhost", 2003); 511 #ifndef WIN32 471 512 SocketStream conn2; 472 513 conn2.Open(Socket::TypeUNIX, "testfiles/srv2.sock"); 473 514 SocketStream conn3; 474 515 conn3.Open(Socket::TypeINET, "localhost", 2003); 516 #endif // !WIN32 475 517 // Quick check that reconnections fail 476 518 TEST_CHECK_THROWS(conn1.Open(Socket::TypeUNIX, "testfiles/srv2.sock");, ServerException, SocketAlreadyOpen); … … 478 520 std::vector<IOStream *> conns; 479 521 conns.push_back(&conn1); 522 #ifndef WIN32 480 523 conns.push_back(&conn2); 481 524 conns.push_back(&conn3); 525 #endif // !WIN32 482 526 Srv2TestConversations(conns); 483 527 // Implicit close 484 528 } 529 #ifndef WIN32 485 530 // HUP again 486 531 TEST_THAT(HUPServer(pid)); 487 532 ::sleep(1); 488 533 TEST_THAT(ServerIsAlive(pid)); 534 #endif // !WIN32 489 535 // Kill it 490 536 TEST_THAT(KillServer(pid)); 491 537 ::sleep(1); 492 538 TEST_THAT(!ServerIsAlive(pid)); 539 #ifndef WIN32 493 540 TestRemoteProcessMemLeaks("test-srv2.memleaks"); 541 #endif // !WIN32 494 542 } 495 543 } … … 497 545 // Launch a test SSL server 498 546 { 547 #ifdef WIN32 548 int pid = LaunchServer("test srv3 testfiles\\srv3.conf", 549 "testfiles\\srv3.pid"); 550 #else 499 551 int pid = LaunchServer("./test srv3 testfiles/srv3.conf", "testfiles/srv3.pid"); 552 #endif 500 553 TEST_THAT(pid != -1 && pid != 0); 501 554 if(pid > 0) … … 503 556 // Will it restart? 504 557 TEST_THAT(ServerIsAlive(pid)); 558 559 #ifndef WIN32 505 560 TEST_THAT(HUPServer(pid)); 506 561 ::sleep(1); 507 562 TEST_THAT(ServerIsAlive(pid)); 563 #endif 564 508 565 // Make some connections 509 566 { … … 520 577 SocketStreamTLS conn1; 521 578 conn1.Open(context, Socket::TypeINET, "localhost", 2003); 579 #ifndef WIN32 522 580 SocketStreamTLS conn2; 523 581 conn2.Open(context, Socket::TypeUNIX, "testfiles/srv3.sock"); 524 582 SocketStreamTLS conn3; 525 583 conn3.Open(context, Socket::TypeINET, "localhost", 2003); 584 #endif 526 585 // Quick check that reconnections fail 527 586 TEST_CHECK_THROWS(conn1.Open(context, Socket::TypeUNIX, "testfiles/srv3.sock");, ServerException, SocketAlreadyOpen); … … 529 588 std::vector<IOStream *> conns; 530 589 conns.push_back(&conn1); 590 #ifndef WIN32 531 591 conns.push_back(&conn2); 532 592 conns.push_back(&conn3); 593 #endif 533 594 Srv2TestConversations(conns); 534 595 // Implicit close 535 596 } 597 #ifndef WIN32 536 598 // HUP again 537 599 TEST_THAT(HUPServer(pid)); 538 600 ::sleep(1); 539 601 TEST_THAT(ServerIsAlive(pid)); 602 #endif 540 603 // Kill it 541 604 TEST_THAT(KillServer(pid)); 542 605 ::sleep(1); 543 606 TEST_THAT(!ServerIsAlive(pid)); 607 #ifndef WIN32 544 608 TestRemoteProcessMemLeaks("test-srv3.memleaks"); 609 #endif 545 610 } 546 611 } … … 549 614 // Launch a test protocol handling server 550 615 { 551 int pid = LaunchServer("./test srv4 testfiles/srv4.conf", "testfiles/srv4.pid"); 616 #ifdef WIN32 617 int pid = LaunchServer("test srv4 testfiles\\srv4.conf", 618 "testfiles\\srv4.pid"); 619 #else 620 int pid = LaunchServer("./test srv4 testfiles/srv4.conf", 621 "testfiles/srv4.pid"); 622 #endif 552 623 TEST_THAT(pid != -1 && pid != 0); 553 624 if(pid > 0) … … 558 629 // Open a connection to it 559 630 SocketStream conn; 631 #ifdef WIN32 632 conn.Open(Socket::TypeINET, "localhost", 2003); 633 #else 560 634 conn.Open(Socket::TypeUNIX, "testfiles/srv4.sock"); 635 #endif 561 636 562 637 // Create a protocol … … 621 696 ::sleep(1); 622 697 TEST_THAT(!ServerIsAlive(pid)); 698 #ifndef WIN32 623 699 TestRemoteProcessMemLeaks("test-srv4.memleaks"); 700 #endif 624 701 } 625 702 } -
box/chris/merge/test/bbackupd/testbbackupd.cpp
r462 r710 719 719 wait_for_backup_operation(); 720 720 compareReturnValue = ::system("../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query3e.log \"compare -ac\" quit"); 721 TEST_THAT(compareReturnValue == 2*256); // should find differences721 TEST_THAT(compareReturnValue == 3*256); // should find differences 722 722 TestRemoteProcessMemLeaks("bbackupquery.memleaks"); 723 723 // Check that it was reported correctly -
box/chris/merge/test/bbackupd/testfiles/extcheck1.pl.in
r537 r710 2 2 use strict; 3 3 4 unless(open IN,"../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query4.log \"compare -ac\" quit|") 4 my $flags = $ARGV[0] or ""; 5 6 unless(open IN,"../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query4.log \"compare -ac$flags\" quit|") 5 7 { 6 8 print "Couldn't open compare utility\n"; … … 16 18 if(m/continousupdate/) 17 19 { 18 $ret = 2 unless m/exists/; 20 unless (/exists/) 21 { 22 print "FAIL: continousupdate line does not match\n"; 23 $ret = 2; 24 } 19 25 $seen = 1; 20 26 } 21 27 else 22 28 { 23 $ret = 2 unless m/\AWARNING/ || m/\ADifferences/ || /might be reason/ || /probably due to file mod/; 29 unless (/\AWARNING/ or /\ADifferences/ or /might be reason/ 30 or /probably due to file mod/) 31 { 32 print "FAIL: Summary line does not match\n"; 33 $ret = 2; 34 } 24 35 } 25 print ;36 print "READ: $_"; 26 37 } 27 38 -
box/chris/merge/test/bbackupd/testfiles/extcheck2.pl.in
r537 r710 2 2 use strict; 3 3 4 unless(open IN,"../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query4.log \"compare -ac\" quit|") 4 my $flags = $ARGV[0] or ""; 5 6 unless(open IN,"../../bin/bbackupquery/bbackupquery -q -c testfiles/bbackupd.conf -l testfiles/query4.log \"compare -ac$flags\" quit|") 5 7 { 6 8 print "Couldn't open compare utility\n"; … … 15 17 if(m/continousupdate/) 16 18 { 17 $ret = 2 unless m/contents/ || m/attributes/; 19 unless (m/contents/ or m/attributes/) 20 { 21 print "FAIL: continuousupdate line does not match\n"; 22 $ret = 2; 23 } 18 24 } 19 25 else 20 26 { 21 $ret = 2 unless m/\AWARNING/ || m/\ADifferences/ || /might be reason/ || /probably due to file mod/; 27 unless (/\AWARNING/ or /\ADifferences/ or /might be reason/ 28 or /probably due to file mod/) 29 { 30 print "FAIL: summary line does not match\n"; 31 $ret = 2; 32 } 22 33 } 23 print; 34 35 print "READ: $_"; 24 36 } 25 37 -
box/chris/merge/test/common/testcommon.cpp
r219 r710 25 25 #include "Conversion.h" 26 26 #include "autogen_ConversionException.h" 27 #include "CollectInBufferStream.h" 28 #include "Archive.h" 27 29 28 30 #include "MemLeakFindOn.h" … … 566 568 test_conversions(); 567 569 570 // test that we can use Archive and CollectInBufferStream 571 // to read and write arbitrary types to a memory buffer 572 573 { 574 CollectInBufferStream buffer; 575 ASSERT(buffer.GetPosition() == 0); 576 577 { 578 Archive archive(buffer, 0); 579 ASSERT(buffer.GetPosition() == 0); 580 581 archive.Write((bool) true); 582 archive.Write((bool) false); 583 archive.Write((int) 0x12345678); 584 archive.Write((int) 0x87654321); 585 archive.Write((int64_t) 0x0badfeedcafebabeLL); 586 archive.Write((uint64_t) 0xfeedfacedeadf00dLL); 587 archive.Write((uint8_t) 0x01); 588 archive.Write((uint8_t) 0xfe); 589 archive.Write(std::string("hello world!")); 590 archive.Write(std::string("goodbye cruel world!")); 591 } 592 593 CollectInBufferStream buf2; 594 buf2.Write(buffer.GetBuffer(), buffer.GetSize()); 595 TEST_THAT(buf2.GetPosition() == buffer.GetSize()); 596 597 buf2.SetForReading(); 598 TEST_THAT(buf2.GetPosition() == 0); 599 600 { 601 Archive archive(buf2, 0); 602 TEST_THAT(buf2.GetPosition() == 0); 603 604 bool b; 605 archive.Read(b); TEST_THAT(b == true); 606 archive.Read(b); TEST_THAT(b == false); 607 608 int i; 609 archive.Read(i); TEST_THAT(i == 0x12345678); 610 archive.Read(i); TEST_THAT((unsigned int)i == 0x87654321); 611 612 uint64_t i64; 613 archive.Read(i64); TEST_THAT(i64 == 0x0badfeedcafebabeLL); 614 archive.Read(i64); TEST_THAT(i64 == 0xfeedfacedeadf00dLL); 615 616 uint8_t i8; 617 archive.Read(i8); TEST_THAT(i8 == 0x01); 618 archive.Read(i8); TEST_THAT(i8 == 0xfe); 619 620 std::string s; 621 archive.Read(s); TEST_THAT(s == "hello world!"); 622 archive.Read(s); TEST_THAT(s == "goodbye cruel world!"); 623 624 TEST_THAT(!buf2.StreamDataLeft()); 625 } 626 } 627 568 628 return 0; 569 629 } -
box/chris/merge/test/raidfile/intercept.cpp
r310 r710 15 15 #include <sys/types.h> 16 16 #include <unistd.h> 17 18 #ifdef HAVE_SYS_UIO_H 17 19 #include <sys/uio.h> 20 #endif 21 18 22 #include <errno.h> 19 23 -
box/chris/merge/test/raidfile/testraidfile.cpp
r217 r710 13 13 #include <unistd.h> 14 14 #include <errno.h> 15 16 #ifdef HAVE_SYSCALL 15 17 #include <sys/syscall.h> 18 #endif 16 19 17 20 #include <string.h> … … 208 211 } 209 212 TEST_THAT(!readstream4.StreamDataLeft()); // check IOStream interface is correct 213 pread.reset(); 210 214 211 215 // Be nasty, and create some errors for the RAID stuff to recover from... … … 213 217 { 214 218 char stripe1fn[256], stripe1fnRename[256]; 215 sprintf(stripe1fn, "testfiles/%d_%d/%s.rf", set, startDisc, filename); 216 sprintf(stripe1fnRename, "testfiles/%d_%d/%s.rf-REMOVED", set, startDisc, filename); 219 sprintf(stripe1fn, "testfiles" DIRECTORY_SEPARATOR "%d_%d" 220 DIRECTORY_SEPARATOR "%s.rf", set, startDisc, filename); 221 sprintf(stripe1fnRename, "testfiles" DIRECTORY_SEPARATOR "%d_%d" 222 DIRECTORY_SEPARATOR "%s.rf-REMOVED", set, startDisc, 223 filename); 217 224 char stripe2fn[256], stripe2fnRename[256]; 218 sprintf(stripe2fn, "testfiles/%d_%d/%s.rf", set, (startDisc + 1) % RAID_NUMBER_DISCS, filename); 219 sprintf(stripe2fnRename, "testfiles/%d_%d/%s.rf-REMOVED", set, (startDisc + 1) % RAID_NUMBER_DISCS, filename); 225 sprintf(stripe2fn, "testfiles" DIRECTORY_SEPARATOR "%d_%d" 226 DIRECTORY_SEPARATOR "%s.rf", set, 227 (startDisc + 1) % RAID_NUMBER_DISCS, filename); 228 sprintf(stripe2fnRename, "testfiles" DIRECTORY_SEPARATOR "%d_%d" 229 DIRECTORY_SEPARATOR "%s.rf-REMOVED", set, 230 (startDisc + 1) % RAID_NUMBER_DISCS, filename); 220 231 221 232 // Read with stripe1 + parity … … 253 264 mungefilename[m++] = '\0'; 254 265 char stripe1munge[256]; 255 sprintf(stripe1munge, "testfiles/%d_%d/.raidfile-unreadable/%s", set, startDisc, mungefilename); 266 sprintf(stripe1munge, "testfiles" DIRECTORY_SEPARATOR "%d_%d" 267 DIRECTORY_SEPARATOR ".raidfile-unreadable" 268 DIRECTORY_SEPARATOR "%s", set, startDisc, 269 mungefilename); 256 270 char stripe2munge[256]; 257 sprintf(stripe2munge, "testfiles/%d_%d/.raidfile-unreadable/%s", set, (startDisc + 1) % RAID_NUMBER_DISCS, mungefilename); 271 sprintf(stripe2munge, "testfiles" DIRECTORY_SEPARATOR "%d_%d" 272 DIRECTORY_SEPARATOR ".raidfile-unreadable" 273 DIRECTORY_SEPARATOR "%s", set, 274 (startDisc + 1) % RAID_NUMBER_DISCS, mungefilename); 258 275 259 276 … … 360 377 // This time, don't discard and transform it to a RAID File 361 378 char writefnPre[256]; 362 sprintf(writefnPre, "testfiles/%d_%d/%s.rfwX", set, startDisc, filename); 379 sprintf(writefnPre, "testfiles" DIRECTORY_SEPARATOR "%d_%d" 380 DIRECTORY_SEPARATOR "%s.rfwX", set, startDisc, filename); 363 381 TEST_THAT(TestFileExists(writefnPre)); 364 382 char writefn[256]; 365 sprintf(writefn, "testfiles/%d_%d/%s.rfw", set, startDisc, filename); 383 sprintf(writefn, "testfiles" DIRECTORY_SEPARATOR "%d_%d" 384 DIRECTORY_SEPARATOR "%s.rfw", set, startDisc, filename); 366 385 int usageInBlocks = write4.GetDiscUsageInBlocks(); 367 386 write4.Commit(DoTransform); … … 391 410 } 392 411 char stripe1fn[256]; 393 sprintf(stripe1fn, "testfiles/%d_%d/%s.rf", set, startDisc, filename); 412 sprintf(stripe1fn, "testfiles" DIRECTORY_SEPARATOR "%d_%d" 413 DIRECTORY_SEPARATOR "%s.rf", set, startDisc, filename); 394 414 TEST_THAT(TestGetFileSize(stripe1fn) == fs1); 395 415 char stripe2fn[256]; 396 sprintf(stripe2fn, "testfiles/%d_%d/%s.rf", set, (startDisc + 1) % RAID_NUMBER_DISCS, filename); 416 sprintf(stripe2fn, "testfiles" DIRECTORY_SEPARATOR "%d_%d" 417 DIRECTORY_SEPARATOR "%s.rf", set, 418 (startDisc + 1) % RAID_NUMBER_DISCS, filename); 397 419 TEST_THAT(TestGetFileSize(stripe2fn) == (int)(datasize - fs1)); 398 420 // Parity file size 399 421 char parityfn[256]; 400 sprintf(parityfn, "testfiles/%d_%d/%s.rf", set, (startDisc + 2) % RAID_NUMBER_DISCS, filename); 422 sprintf(parityfn, "testfiles" DIRECTORY_SEPARATOR "%d_%d" 423 DIRECTORY_SEPARATOR "%s.rf", set, 424 (startDisc + 2) % RAID_NUMBER_DISCS, filename); 401 425 // Mildly complex calculation 402 426 unsigned int blocks = datasize / RAID_BLOCK_SIZE; … … 437 461 { 438 462 int f; 439 TEST_THAT((f = ::open(stripe1fn, O_RDONLY, 0)) != -1); 463 TEST_THAT((f = ::open(stripe1fn, O_RDONLY | O_BINARY, 464 0)) != -1); 440 465 TEST_THAT(sizeof(testblock) == ::read(f, testblock, sizeof(testblock))); 441 466 for(unsigned int q = 0; q < sizeof(testblock); ++q) … … 444 469 } 445 470 ::close(f); 446 TEST_THAT((f = ::open(stripe2fn, O_RDONLY, 0)) != -1); 471 TEST_THAT((f = ::open(stripe2fn, O_RDONLY | O_BINARY, 472 0)) != -1); 447 473 TEST_THAT(sizeof(testblock) == ::read(f, testblock, sizeof(testblock))); 448 474 for(unsigned int q = 0; q < sizeof(testblock); ++q) … … 537 563 // Generate a random pre-existing write file (and ensure that it doesn't exist already) 538 564 int f; 539 TEST_THAT((f = ::open("testfiles/0_2/overwrite_B.rfwX", O_WRONLY | O_CREAT | O_EXCL, 0755)) != -1); 565 TEST_THAT((f = ::open("testfiles" DIRECTORY_SEPARATOR "0_2" 566 DIRECTORY_SEPARATOR "overwrite_B.rfwX", 567 O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0755)) != -1); 540 568 TEST_THAT(::write(f, "TESTTEST", 8) == 8); 541 569 ::close(f); … … 558 586 // Initialise the controller 559 587 RaidFileController &rcontroller = RaidFileController::GetController(); 560 rcontroller.Initialise("testfiles /raidfile.conf");588 rcontroller.Initialise("testfiles" DIRECTORY_SEPARATOR "raidfile.conf"); 561 589 562 590 // some data … … 575 603 // Try creating a directory 576 604 RaidFileWrite::CreateDirectory(0, "test-dir"); 577 TEST_THAT(TestDirExists("testfiles/0_0/test-dir")); 578 TEST_THAT(TestDirExists("testfiles/0_1/test-dir")); 579 TEST_THAT(TestDirExists("testfiles/0_2/test-dir")); 605 TEST_THAT(TestDirExists("testfiles" DIRECTORY_SEPARATOR "0_0" 606 DIRECTORY_SEPARATOR "test-dir")); 607 TEST_THAT(TestDirExists("testfiles" DIRECTORY_SEPARATOR "0_1" 608 DIRECTORY_SEPARATOR "test-dir")); 609 TEST_THAT(TestDirExists("testfiles" DIRECTORY_SEPARATOR "0_2" 610 DIRECTORY_SEPARATOR "test-dir")); 580 611 TEST_THAT(RaidFileRead::DirectoryExists(0, "test-dir")); 581 612 TEST_THAT(!RaidFileRead::DirectoryExists(0, "test-dir-not")); … … 609 640 // Before it's deleted, check to see the contents are as expected 610 641 int f; 611 TEST_THAT((f = ::open("testfiles/0_2/test1.rfwX", O_RDONLY, 0)) >= 0); 642 TEST_THAT((f = ::open("testfiles" DIRECTORY_SEPARATOR "0_2" 643 DIRECTORY_SEPARATOR "test1.rfwX", O_RDONLY | O_BINARY, 0)) 644 >= 0); 612 645 char buffer[sizeof(data)]; 613 TEST_THAT(::read(f, buffer, sizeof(buffer)) == sizeof(buffer)); 646 int bytes_read = ::read(f, buffer, sizeof(buffer)); 647 TEST_THAT(bytes_read == sizeof(buffer)); 614 648 for(unsigned int l = 0; l < 1024; ++l) 615 649 { … … 625 659 } 626 660 TEST_THAT(::lseek(f, sizeof(data), SEEK_SET) == sizeof(buffer)); 627 TEST_THAT(::read(f, buffer, sizeof(buffer)) == sizeof(buffer)); 661 bytes_read = ::read(f, buffer, sizeof(buffer)); 662 TEST_THAT(bytes_read == sizeof(buffer)); 628 663 for(unsigned int l = 0; l < 1024; ++l) 629 664 { … … 636 671 // Commit the data 637 672 write1.Commit(); 638 TEST_THAT((f = ::open("testfiles/0_2/test1.rfw", O_RDONLY, 0)) >= 0); 673 TEST_THAT((f = ::open("testfiles" DIRECTORY_SEPARATOR "0_2" 674 DIRECTORY_SEPARATOR "test1.rfw", O_RDONLY | O_BINARY, 0)) 675 >= 0); 639 676 ::close(f); 640 677 … … 688 725 // This time, discard it 689 726 write2.Discard(); 690 TEST_THAT((f = ::open("testfiles/0_2/test1.rfw", O_RDONLY, 0)) == -1); 727 TEST_THAT((f = ::open("testfiles" DIRECTORY_SEPARATOR "0_2" 728 DIRECTORY_SEPARATOR "test1.rfw", O_RDONLY | O_BINARY, 0)) 729 == -1); 691 730 692 731 // And leaving it there... … … 696 735 // This time, commit it 697 736 writeLeave.Commit(); 698 TEST_THAT((f = ::open("testfiles/0_2/test1.rfw", O_RDONLY, 0)) != -1); 737 TEST_THAT((f = ::open("testfiles" DIRECTORY_SEPARATOR "0_2" 738 DIRECTORY_SEPARATOR "test1.rfw", O_RDONLY | O_BINARY, 0)) 739 != -1); 699 740 ::close(f); 700 741 … … 713 754 write3b.Commit(); 714 755 // Test it 715 testReadingFileContents(0, "test1", data+3, sizeof(data) - 3, false /*TestRAIDProperties*/); 756 testReadingFileContents(0, "test1", data+3, sizeof(data) - 3, false 757 /* TestRAIDProperties */); 716 758 717 759 // And once again, but this time making it a raid file … … 722 764 write3c.Commit(true); // make RAID 723 765 // Test it 724 testReadingFileContents(0, "test1", data+7, sizeof(data) - 7, false /*TestRAIDProperties*/); 766 testReadingFileContents(0, "test1", data+7, sizeof(data) - 7, false 767 /*TestRAIDProperties*/); 725 768 726 769 // Test opening a file which doesn't exist … … 737 780 738 781 // Try removing the parity file 739 TEST_THAT(::rename("testfiles/0_0/damage.rf", "testfiles/0_0/damage.rf-NT") == 0); 782 TEST_THAT(::rename("testfiles" DIRECTORY_SEPARATOR "0_0" 783 DIRECTORY_SEPARATOR "damage.rf", 784 "testfiles" DIRECTORY_SEPARATOR "0_0" 785 DIRECTORY_SEPARATOR "damage.rf-NT") == 0); 740 786 { 741 787 std::auto_ptr<RaidFileRead> pr0 = RaidFileRead::Open(0, "damage"); 742 788 pr0->Read(buffer, sizeof(data)); 743 789 } 744 TEST_THAT(::rename("testfiles /0_0/damage.rf-NT", "testfiles/0_0/damage.rf") == 0);745 790 TEST_THAT(::rename("testfiles" DIRECTORY_SEPARATOR "0_0" DIRECTORY_SEPARATOR "damage.rf-NT", "testfiles" DIRECTORY_SEPARATOR "0_0" DIRECTORY_SEPARATOR "damage.rf") == 0); 791 746 792 // Delete one of the files 747 TEST_THAT(::unlink("testfiles /0_1/damage.rf") == 0);// stripe 1793 TEST_THAT(::unlink("testfiles" DIRECTORY_SEPARATOR "0_1" DIRECTORY_SEPARATOR "damage.rf") == 0); // stripe 1 748 794 749 795 #ifdef TRF_CAN_INTERCEPT 750 796 // Open it and read... 751 797 { 752 intercept_setup_error("testfiles /0_2/damage.rf", 0, EIO, SYS_read); // stripe 2798 intercept_setup_error("testfiles" DIRECTORY_SEPARATOR "0_2" DIRECTORY_SEPARATOR "damage.rf", 0, EIO, SYS_read); // stripe 2 753 799 std::auto_ptr<RaidFileRead> pr1 = RaidFileRead::Open(0, "damage"); 754 800 TEST_CHECK_THROWS( … … 762 808 763 809 // Delete another 764 TEST_THAT(::unlink("testfiles /0_0/damage.rf") == 0);// parity810 TEST_THAT(::unlink("testfiles" DIRECTORY_SEPARATOR "0_0" DIRECTORY_SEPARATOR "damage.rf") == 0); // parity 765 811 766 812 TEST_CHECK_THROWS( … … 773 819 RaidFileWrite::CreateDirectory(0, "dirread"); 774 820 // Make some contents 775 RaidFileWrite::CreateDirectory(0, "dirread /dfsdf1");776 RaidFileWrite::CreateDirectory(0, "dirread /ponwq2");777 { 778 RaidFileWrite w(0, "dirread /sdf9873241");821 RaidFileWrite::CreateDirectory(0, "dirread" DIRECTORY_SEPARATOR "dfsdf1"); 822 RaidFileWrite::CreateDirectory(0, "dirread" DIRECTORY_SEPARATOR "ponwq2"); 823 { 824 RaidFileWrite w(0, "dirread" DIRECTORY_SEPARATOR "sdf9873241"); 779 825 w.Open(); 780 826 w.Write(data, sizeof(data)); … … 782 828 } 783 829 { 784 RaidFileWrite w(0, "dirread /fsdcxjni3242");830 RaidFileWrite w(0, "dirread" DIRECTORY_SEPARATOR "fsdcxjni3242"); 785 831 w.Open(); 786 832 w.Write(data, sizeof(data)); … … 788 834 } 789 835 { 790 RaidFileWrite w(0, "dirread /cskjnds3");836 RaidFileWrite w(0, "dirread" DIRECTORY_SEPARATOR "cskjnds3"); 791 837 w.Open(); 792 838 w.Write(data, sizeof(data)); … … 804 850 TEST_THAT(list_matches(names, dir_list1)); 805 851 // Delete things 806 TEST_THAT(::unlink("testfiles /0_0/dirread/sdf9873241.rf") == 0);852 TEST_THAT(::unlink("testfiles" DIRECTORY_SEPARATOR "0_0" DIRECTORY_SEPARATOR "dirread" DIRECTORY_SEPARATOR "sdf9873241.rf") == 0); 807 853 TEST_THAT(true == RaidFileRead::ReadDirectoryContents(0, std::string("dirread"), RaidFileRead::DirReadType_FilesOnly, names)); 808 854 TEST_THAT(list_matches(names, file_list1)); 809 855 // Delete something else so that it's not recoverable 810 TEST_THAT(::unlink("testfiles /0_1/dirread/sdf9873241.rf") == 0);856 TEST_THAT(::unlink("testfiles" DIRECTORY_SEPARATOR "0_1" DIRECTORY_SEPARATOR "dirread" DIRECTORY_SEPARATOR "sdf9873241.rf") == 0); 811 857 TEST_THAT(false == RaidFileRead::ReadDirectoryContents(0, std::string("dirread"), RaidFileRead::DirReadType_FilesOnly, names)); 812 858 TEST_THAT(list_matches(names, file_list1)); 813 859 // And finally... 814 TEST_THAT(::unlink("testfiles /0_2/dirread/sdf9873241.rf") == 0);860 TEST_THAT(::unlink("testfiles" DIRECTORY_SEPARATOR "0_2" DIRECTORY_SEPARATOR "dirread" DIRECTORY_SEPARATOR "sdf9873241.rf") == 0); 815 861 TEST_THAT(true == RaidFileRead::ReadDirectoryContents(0, std::string("dirread"), RaidFileRead::DirReadType_FilesOnly, names)); 816 862 TEST_THAT(list_matches(names, file_list2)); -
box/chris/merge/test/win32/testlibwin32.cpp
r456 r710 6 6 7 7 #ifdef WIN32 8 9 #include <assert.h> 10 #include <AccCtrl.h> 11 #include <Aclapi.h> 8 12 9 13 #include "../../bin/bbackupd/BackupDaemon.h" … … 13 17 int main(int argc, char* argv[]) 14 18 { 19 // ACL tests 20 char* exename = getenv("WINDIR"); 21 22 PSID psidOwner; 23 PSID psidGroup; 24 PACL pDacl; 25 PSECURITY_DESCRIPTOR pSecurityDesc; 26 27 DWORD result = GetNamedSecurityInfo( 28 exename, // pObjectName 29 SE_FILE_OBJECT, // ObjectType 30 DACL_SECURITY_INFORMATION | // SecurityInfo 31 GROUP_SECURITY_INFORMATION | 32 OWNER_SECURITY_INFORMATION, 33 &psidOwner, // ppsidOwner, 34 &psidGroup, // ppsidGroup, 35 &pDacl, // ppDacl, 36 NULL, // ppSacl, 37 &pSecurityDesc // ppSecurityDescriptor 38 ); 39 if (result != ERROR_SUCCESS) 40 { 41 printf("Error getting security info for '%s': error %d", 42 exename, result); 43 } 44 assert(result == ERROR_SUCCESS); 45 46 char namebuf[1024]; 47 char domainbuf[1024]; 48 SID_NAME_USE nametype; 49 DWORD namelen = sizeof(namebuf); 50 DWORD domainlen = sizeof(domainbuf); 51 52 assert(LookupAccountSid(NULL, psidOwner, namebuf, &namelen, 53 domainbuf, &domainlen, &nametype)); 54 55 printf("Owner:\n"); 56 printf("User name: %s\n", namebuf); 57 printf("Domain name: %s\n", domainbuf); 58 printf("Name type: %d\n", nametype); 59 printf("\n"); 60 61 namelen = sizeof(namebuf); 62 domainlen = sizeof(domainbuf); 63 64 assert(LookupAccountSid(NULL, psidGroup, namebuf, &namelen, 65 domainbuf, &domainlen, &nametype)); 66 67 printf("Group:\n"); 68 printf("User name: %s\n", namebuf); 69 printf("Domain name: %s\n", domainbuf); 70 printf("Name type: %d\n", nametype); 71 printf("\n"); 72 73 ULONG numEntries; 74 PEXPLICIT_ACCESS pEntries; 75 result = GetExplicitEntriesFromAcl 76 ( 77 pDacl, // pAcl 78 &numEntries, // pcCountOfExplicitEntries, 79 &pEntries // pListOfExplicitEntries 80 ); 81 assert(result == ERROR_SUCCESS); 82 83 printf("Found %lu explicit DACL entries for '%s'\n\n", 84 (unsigned long)numEntries, exename); 85 86 for (ULONG i = 0; i < numEntries; i++) 87 { 88 EXPLICIT_ACCESS* pEntry = &(pEntries[i]); 89 printf("DACL entry %lu:\n", (unsigned long)i); 90 91 DWORD perms = pEntry->grfAccessPermissions; 92 printf(" Access permissions: ", perms); 93 94 #define PRINT_PERM(name) \ 95 if (perms & name) \ 96 { \ 97 printf(#name " "); \ 98 perms &= ~name; \ 99 } 100 101 PRINT_PERM(FILE_ADD_FILE); 102 PRINT_PERM(FILE_ADD_SUBDIRECTORY); 103 PRINT_PERM(FILE_ALL_ACCESS); 104 PRINT_PERM(FILE_APPEND_DATA); 105 PRINT_PERM(FILE_CREATE_PIPE_INSTANCE); 106 PRINT_PERM(FILE_DELETE_CHILD); 107 PRINT_PERM(FILE_EXECUTE); 108 PRINT_PERM(FILE_LIST_DIRECTORY); 109 PRINT_PERM(FILE_READ_ATTRIBUTES); 110 PRINT_PERM(FILE_READ_DATA); 111 PRINT_PERM(FILE_READ_EA); 112 PRINT_PERM(FILE_TRAVERSE); 113 PRINT_PERM(FILE_WRITE_ATTRIBUTES); 114 PRINT_PERM(FILE_WRITE_DATA); 115 PRINT_PERM(FILE_WRITE_EA); 116 PRINT_PERM(STANDARD_RIGHTS_READ); 117 PRINT_PERM(STANDARD_RIGHTS_WRITE); 118 PRINT_PERM(SYNCHRONIZE); 119 PRINT_PERM(DELETE); 120 PRINT_PERM(READ_CONTROL); 121 PRINT_PERM(WRITE_DAC); 122 PRINT_PERM(WRITE_OWNER); 123 PRINT_PERM(MAXIMUM_ALLOWED); 124 PRINT_PERM(GENERIC_ALL); 125 PRINT_PERM(GENERIC_EXECUTE); 126 PRINT_PERM(GENERIC_WRITE); 127 PRINT_PERM(GENERIC_READ); 128 printf("\n"); 129 130 if (perms) 131 { 132 printf(" Bits left over: %08x\n", perms); 133 } 134 assert(!perms); 135 136 printf(" Access mode: "); 137 switch(pEntry->grfAccessMode) 138 { 139 case NOT_USED_ACCESS: 140 printf("NOT_USED_ACCESS\n"); break; 141 case GRANT_ACCESS: 142 printf("GRANT_ACCESS\n"); break; 143 case DENY_ACCESS: 144 printf("DENY_ACCESS\n"); break; 145 case REVOKE_ACCESS: 146 printf("REVOKE_ACCESS\n"); break; 147 case SET_AUDIT_SUCCESS: 148 printf("SET_AUDIT_SUCCESS\n"); break; 149 case SET_AUDIT_FAILURE: 150 printf("SET_AUDIT_FAILURE\n"); break; 151 default: 152 printf("Unknown (%08x)\n", pEntry->grfAccessMode); 153 } 154 155 printf(" Trustee: "); 156 assert(pEntry->Trustee.pMultipleTrustee == NULL); 157 assert(pEntry->Trustee.MultipleTrusteeOperation == NO_MULTIPLE_TRUSTEE); 158 switch(pEntry->Trustee.TrusteeForm) 159 { 160 case TRUSTEE_IS_SID: 161 { 162 PSID trusteeSid = (PSID)(pEntry->Trustee.ptstrName); 163 164 namelen = sizeof(namebuf); 165 domainlen = sizeof(domainbuf); 166 167 assert(LookupAccountSid(NULL, trusteeSid, namebuf, &namelen, 168 domainbuf, &domainlen, &nametype)); 169 170 printf("SID of %s\\%s (%d)\n", domainbuf, namebuf, nametype); 171 } 172 break; 173 case TRUSTEE_IS_NAME: 174 printf("Name\n"); break; 175 case TRUSTEE_BAD_FORM: 176 printf("Bad form\n"); assert(0); 177 case TRUSTEE_IS_OBJECTS_AND_SID: 178 printf("Objects and SID\n"); break; 179 case TRUSTEE_IS_OBJECTS_AND_NAME: 180 printf("Objects and name\n"); break; 181 default: 182 printf("Unknown form\n"); assert(0); 183 } 184 185 printf(" Trustee type: "); 186 switch(pEntry->Trustee.TrusteeType) 187 { 188 case TRUSTEE_IS_UNKNOWN: 189 printf("Unknown type.\n"); break; 190 case TRUSTEE_IS_USER: 191 printf("User\n"); break; 192 case TRUSTEE_IS_GROUP: 193 printf("Group\n"); break; 194 case TRUSTEE_IS_DOMAIN: 195 printf("Domain\n"); break; 196 case TRUSTEE_IS_ALIAS: 197 printf("Alias\n"); break; 198 case TRUSTEE_IS_WELL_KNOWN_GROUP: 199 printf("Well-known group\n"); break; 200 case TRUSTEE_IS_DELETED: 201 printf("Deleted account\n"); break; 202 case TRUSTEE_IS_INVALID: 203 printf("Invalid trustee type\n"); break; 204 case TRUSTEE_IS_COMPUTER: 205 printf("Computer\n"); break; 206 default: 207 printf("Unknown type %d\n", pEntry->Trustee.TrusteeType); 208 assert(0); 209 } 210 211 printf("\n"); 212 } 213 214 assert(LocalFree((HLOCAL)pEntries) == 0); 215 assert(LocalFree((HLOCAL)pSecurityDesc) == 0); 216 15 217 chdir("c:\\tmp"); 16 218 openfile("test", O_CREAT, 0); … … 26 228 { 27 229 info = readdir(ourDir); 28 if ( info) printf("File/Dir name is : %s\r\n", info->d_name);29 30 }while ( info != NULL);230 if (info) printf("File/Dir name is : %s\r\n", info->d_name); 231 } 232 while (info != NULL); 31 233 32 234 closedir(ourDir); 33 34 235 } 35 236 … … 42 243 { 43 244 info = readdir(ourDir); 44 if ( info == NULL) break;245 if (info == NULL) break; 45 246 std::string file(diry + info->d_name); 46 247 stat(file.c_str(), &ourfs); 47 if ( info) printf("File/Dir name is : %s\r\n", info->d_name);48 49 }while ( info != NULL );248 if (info) printf("File/Dir name is : %s\r\n", info->d_name); 249 } 250 while ( info != NULL ); 50 251 51 252 closedir(ourDir); … … 55 256 stat("c:\\windows", &ourfs); 56 257 stat("c:\\autoexec.bat", &ourfs); 57 printf("Finished dir read"); 58 #if 0 59 //remove - sleepycat include a version of getopt - mine never REALLY worked ! 258 printf("Finished dir read\n"); 259 60 260 //test our getopt function 61 std::string commline("-q -c fgfgfg -f -l hello"); 62 63 int c; 64 while((c = getopt(commline.size(), (char * const *)commline.c_str(), "qwc:l:")) != -1) 65 { 66 printf("switch = %c, param is %s\r\n", c, optarg); 67 } 68 #endif 261 char * test_argv[] = 262 { 263 "foobar.exe", 264 "-qwc", 265 "-", 266 "-c", 267 "fgfgfg", 268 "-f", 269 "-l", 270 "hello", 271 "-", 272 "force-sync", 273 NULL 274 }; 275 int test_argc; 276 for (test_argc = 0; test_argv[test_argc]; test_argc++) { } 277 const char* opts = "qwc:l:"; 278 279 assert(getopt(test_argc, test_argv, opts) == 'q'); 280 assert(getopt(test_argc, test_argv, opts) == 'w'); 281 assert(getopt(test_argc, test_argv, opts) == 'c'); 282 assert(strcmp(optarg, "-") == 0); 283 assert(getopt(test_argc, test_argv, opts) == 'c'); 284 assert(strcmp(optarg, "fgfgfg") == 0); 285 assert(getopt(test_argc, test_argv, opts) == '?'); 286 assert(optopt == 'f'); 287 assert(getopt(test_argc, test_argv, opts) == 'l'); 288 assert(strcmp(optarg, "hello") == 0); 289 assert(getopt(test_argc, test_argv, opts) == -1); 290 // assert(optopt == 0); // no more options 291 assert(strcmp(test_argv[optind], "-") == 0); 292 assert(strcmp(test_argv[optind+1], "force-sync") == 0); 69 293 //end of getopt test 70 294 71 295 //now test our statfs funct 72 296 stat("c:\\cert.cer", &ourfs); 73 74 75 297 76 298 char *timee; … … 78 300 timee = ctime(&ourfs.st_mtime); 79 301 80 if ( S_ISREG(ourfs.st_mode))81 { 82 printf("is a normal file ");302 if (S_ISREG(ourfs.st_mode)) 303 { 304 printf("is a normal file\n"); 83 305 } 84 306 else 85 307 { 86 printf("is a directory?"); 87 } 88 89 lstat("c:\\windows", &ourfs); 308 printf("is a directory?\n"); 309 exit(1); 310 } 311 312 lstat(getenv("WINDIR"), &ourfs); 90 313 91 314 if ( S_ISDIR(ourfs.st_mode)) 92 315 { 93 printf("is a directory ");316 printf("is a directory\n"); 94 317 } 95 318 else 96 319 { 97 printf("is a file?"); 320 printf("is a file?\n"); 321 exit(1); 98 322 } 99 323 … … 106 330 closelog(); 107 331 332 /* 108 333 //first off get the path name for the default 109 334 char buf[MAX_PATH]; … … 113 338 std::string conf("-c " + buffer.substr(0,(buffer.find("win32test.exe"))) + "bbackupd.conf"); 114 339 //std::string conf( "-c " + buffer.substr(0,(buffer.find("bbackupd.exe"))) + "bbackupd.conf"); 115 340 */ 116 341 117 342 return 0; -
box/chris/merge/win32.bat
r456 r710 3 3 echo quick and dirty to get up and running by generating the required files 4 4 echo using Cygwin and Perl 5 6 copy .\infrastructure\BoxPlatform.pm.in .\infrastructure\BoxPlatform.pm 5 7 6 8 cd .\bin\bbackupquery\ & perl ./../../bin/bbackupquery/makedocumentation.pl … … 26 28 cd ..\..\ 27 29 28 copy lib\win32\config.h.win32 lib\common\BoxConfig.h 30 perl -i.orig -pe 's/@PERL@/perl/' ./test/bbackupd/testfiles/bbackupd.conf
Note: See TracChangeset
for help on using the changeset viewer.
