#define _CRT_SECURE_NO_DEPRECATE #include "windows.h" #undef SetPort #include <string> #pragma warning(push) #pragma warning(disable : 4267 4244) #include <clientapi.h> #include <options.h> #pragma warning( pop ) #include "fs.h" #include "fs_filesys.h" #include "fs_client.h" #include "filewriter.h" const char* cUsageString1 = "Usage: "; const char* cUsageString2 = " [-c client -H host -p port -P pass -u user -h] sync [-[I|M|S|A] -a -v sync_options]"; static std::string sExtendedErrorMessage; static std::string sErrorMessage; EResult Sync(int argc, char **argv, const char* inToolName, SyncStatCallbackFunc inSyncStatCallback, FileStatCallbackFunc inFileStatCallback, BufferCallbackFunc inReadCallback, BufferCallbackFunc inWriteCallback) { // Get rid of executable name --argc; ++argv; // Construct proper usage string std::string usage_string = std::string(cUsageString1) + inToolName + cUsageString2; // Now see if there are any global options present Error error; Options options; ErrorId usage; usage.code = E_FAILED; usage.fmt = usage_string.c_str(); options.Parse(argc, argv, "c:H:p:P:u:h", OPT_ANY, usage, &error); if (error.Test()) { StrBuf msg; error.Fmt(&msg); sErrorMessage = std::string("Error parsing arguments.\n") + msg.Text() + "\n"; return FS_ERROR_ARGUMENT; } // Check for help request if (options['h'] || options['?']) { sErrorMessage = usage_string; return FS_HELP; } ClientApi client; StrPtr* opt_value; // Get command line overrides of client, host, user, port and password if (opt_value = options['c']) client.SetClient(opt_value); if (opt_value = options['H']) client.SetHost(opt_value); if (opt_value = options['u']) client.SetUser(opt_value); if (opt_value = options['p']) client.SetPort(opt_value); if (opt_value = options['P']) client.SetPassword(opt_value); // Verify that the "sync" is present if (argc == 0 || ::strcmp(*argv, "sync") != 0) { sErrorMessage = std::string(inToolName) + std::string(" supports only the p4 sync command.\n") + usage_string; return FS_ERROR_NO_SYNC; } // Ok, seen the "sync", now get rid of it. --argc; ++argv; if (!FileWriter::GetSetFileValidDataFunction()) { // We must be on Windows 2000, so set the default filewriter type to MT FileWriter::SetType(FileWriter::MT); } char** clean_args = new char*[argc]; int clean_arg_count = 0; bool type_set = false; for (int i = 0; i < argc; ++i) { if (strlen(argv[i]) == 2 && argv[i][0] == '-') { if (argv[i][1] == 'I' || argv[i][1] == 'M' || argv[i][1] == 'S' || argv[i][1] == 'A') { if (type_set) { sErrorMessage = std::string("Invalid arguments: cannot use multiple filewriter types.\n") + usage_string; return FS_ERROR_ARGUMENT; } type_set = true; } switch (argv[i][1]) { case 'I' : FileWriter::SetType(FileWriter::IMMEDIATE); break; case 'M' : FileWriter::SetType(FileWriter::MT); break; case 'S' : FileWriter::SetType(FileWriter::SYNC); break; case 'A' : FileWriter::SetType(FileWriter::ASYNC); break; case 'a' : FileWriter::UsePreAllocation(false); break; case 'v' : FileWriter::UseSetFileValid(false); break; default : clean_args[clean_arg_count++] = argv[i]; break; } } else { clean_args[clean_arg_count++] = argv[i]; } } FileWriter::SetReadCallback(inReadCallback); FileWriter::SetWriteCallback(inWriteCallback); // Client is now ready to initialise client.SetProtocol("tag", ""); client.Init(&error); if (error.Test()) { StrBuf msg; error.Fmt(&msg); sErrorMessage = std::string(msg.Text()); return FS_ERROR_INIT; } client.SetProg(inToolName); // Client is ready, now run the actual sync command, using any specified options FsClientUser client_user; client_user.SetSyncStatCallback(inSyncStatCallback); client_user.SetFileStatCallback(inFileStatCallback); client.SetArgv(clean_arg_count, clean_args); client.Run("sync", &client_user); client.Final(&error); delete[] clean_args; FileWriter::Finalize(); sExtendedErrorMessage = client_user.GetErrorMessage(); if (error.Test()) { StrBuf msg; error.Fmt(&msg); sErrorMessage = std::string(msg.Text()); sExtendedErrorMessage += sErrorMessage; return FS_ERROR_IO; } if (!sExtendedErrorMessage.empty()) return FS_ERROR_SYNC; return FS_OK; } const char* GetErrorMessage() { return sErrorMessage.c_str(); } const char* GetExtendedErrorMessage() { return sExtendedErrorMessage.c_str(); } void AbortSync() { FileWriter::AbortSync(); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#3 | 6451 | Frank Compagner |
- Now fully support unicode & utf-16 files - Improved accuracy of P4fsV progress bar - Added logging to help in remote debugging |
||
#2 | 6420 | Frank Compagner |
A number of improvements: - p4fs now supports the global -s (scripted output) option. - p4fs and P4fsV now support the modtime client option. - P4CHARSET is now correctly handled (though no full Unicode support yet). - Increased the maximum command line length for p4fs to the Windows maximum 32768. - Improved error handling. - Fixed a crash when cancelling a sync using the async or multithreaded writers. - P4fsV progressbar now behaves well when passing more than one filespec - P4fsV will now offer the option to overwrite any locally changed (but not checked out) files when it finds these during a sync (cannot clobber ...). - Made the P4fsV error dialog resizeable. - P4fsV Windows layout fixed so it works properly with all Windows style setings. - Ooh, and prettier icons too. |
||
#1 | 6187 | Frank Compagner | Added p4fs project |