bool CDataServer::CopyFile(const nString& SrcPath, const nString& DestPath) { //???mangle here for perf reasons? if (IsFileReadOnly(DestPath)) SetFileReadOnly(DestPath, false); CFileStream Src, Dest; if (!Src.Open(SrcPath, SAM_READ, SAP_SEQUENTIAL)) FAIL; if (!Dest.Open(DestPath, SAM_WRITE, SAP_SEQUENTIAL)) { Src.Close(); FAIL; } int Size = Src.GetSize(); char* pBuffer = (char*)n_malloc(Size); int RealSize = Src.Read(pBuffer, Size); n_assert(RealSize == Size); Src.Close(); RealSize = Dest.Write(pBuffer, Size); n_assert(RealSize == Size); Dest.Close(); n_free(pBuffer); OK; }
bool DoDiff(DirectoryGroups& dirGroups, std::string rev1, std::string rev2, bool forceQuery) { std::string dir = UniqueTemporaryDir(); AutoDirectoryDeleter dirDeleter(dir); std::string diffFile = dir; std::string diffFile2 = diffFile; bool ok = true; CVSAction glue(0); if (rev1.empty()) rev1 = CVSStatus::GetRevisionNumber(dirGroups.mySingleAbsolute); // Should we do a text diff only? std::string externalApp = GetExternalApplication("Diff", dirGroups, forceQuery); forceQuery = false; if (externalApp.empty()) { // Perform a textual diff glue.SetProgressFinishedCaption(Printf(_("Finished diff in %s"), wxText(dirGroups.mySingleDirectory).c_str())); glue.SetProgressCaption(Printf(_("Diffing in %s"), wxText(dirGroups.mySingleDirectory).c_str())); MakeArgs args; args.add_option("diff"); args.add_option("-u"); args.add_option("-r"); args.add_option(rev1); if (!rev2.empty()) { args.add_option("-r"); args.add_option(rev2); } args.add_arg(dirGroups.mySingleRelative); return glue.Command(dirGroups.mySingleDirectory, args); } bool unixSandbox = IsUnixSandbox(StripLastPart(dirGroups.mySingleAbsolute)); diffFile += "\\" + MakeRevFilename(ExtractLastPart(dirGroups.mySingleAbsolute), rev1); DeleteFileA(diffFile.c_str()); AutoFileDeleter diffFileDeleter(diffFile); AutoFileDeleter diffFile2Deleter; if (!rev2.empty()) { diffFile2 += "\\" + MakeRevFilename(ExtractLastPart(dirGroups.mySingleAbsolute), rev2); DeleteFileA(diffFile2.c_str()); diffFile2Deleter.Attach(diffFile2); } glue.SetProgressFinishedCaption(Printf(_("Finished diff in %s"), wxText(dirGroups.mySingleDirectory).c_str())); glue.SetProgressCaption(Printf(_("Diffing in %s"), wxText(dirGroups.mySingleDirectory).c_str())); std::string cvsroot = CVSStatus::CVSRootForPath(dirGroups.mySingleDirectory); CVSServerFeatures sf; if (unixSandbox) sf.Initialize(&glue); // Diffing two revisions if (!rev1.empty()) { glue.SetCVSRoot(CVSRoot(cvsroot)); MakeArgs args; std::string tempDir = UniqueTemporaryDir(); glue.SetCloseIfOK(true); args.add_global_option("-f"); args.add_option("checkout"); if (rev1 != "HEAD") { args.add_option("-r"); args.add_option(rev1); } args.add_option("-d"); args.add_option("temp"); if (unixSandbox) sf.AddUnixLineEndingsFlag(args); std::string s = EnsureTrailingUnixDelimiter(CVSStatus::CVSRepositoryForPath(dirGroups.mySingleAbsolute)) + ExtractLastPart(dirGroups.mySingleAbsolute); args.add_arg(s); ok = glue.Command(tempDir, args); if (ok) { // Copy file to destination std::string file = EnsureTrailingDelimiter(tempDir) + "temp\\" + ExtractLastPart(dirGroups.mySingleAbsolute); SetFileReadOnly(file.c_str(), false); CopyFileA(file.c_str(), diffFile.c_str(), false); SetFileReadOnly(diffFile.c_str(), true); } // Erase temporary directory DeleteDirectoryRec(tempDir); if (!ok) return false; glue.CloseConsoleOutput(); } if (!rev2.empty()) { glue.SetCVSRoot(CVSRoot(cvsroot)); MakeArgs args; std::string tempDir = UniqueTemporaryDir(); glue.SetCloseIfOK(true); args.add_global_option("-f"); args.add_option("checkout"); args.add_option("-r"); args.add_option(rev2); args.add_option("-d"); args.add_option("temp"); if (unixSandbox) sf.AddUnixLineEndingsFlag(args); std::string s = EnsureTrailingUnixDelimiter(CVSStatus::CVSRepositoryForPath(dirGroups.mySingleAbsolute)) + ExtractLastPart(dirGroups.mySingleAbsolute); args.add_arg(s); ok = glue.Command(tempDir, args); if (ok) { // Copy file to destination std::string file = EnsureTrailingDelimiter(tempDir) + "temp\\" + ExtractLastPart(dirGroups.mySingleAbsolute); SetFileReadOnly(file.c_str(), false); CopyFileA(file.c_str(), diffFile2.c_str(), false); SetFileReadOnly(diffFile2.c_str(), true); } // Erase temporary directory DeleteDirectoryRec(tempDir); if (!ok) return false; glue.CloseConsoleOutput(); } if (!FileExists(diffFile.c_str())) { DoMessageDialog(0, wxString(_("This file is new and has never been committed to the server or is an empty file on the server.")) + wxString(wxT("\n\n")) + wxString(wxText(dirGroups.mySingleAbsolute))); return true; } do { externalApp = GetExternalApplication("Diff", dirGroups, forceQuery); forceQuery = false; if (externalApp.empty()) { return false; } // Perform diff, waiting for it to finish (so we can delete file) glue.LockProgressDialog(true); if (rev2.empty()) forceQuery = !RunExternalDiff(diffFile, dirGroups.mySingleAbsolute, dirGroups); else forceQuery = !RunExternalDiff(diffFile, diffFile2, dirGroups); glue.LockProgressDialog(false); } while (forceQuery); return true; }
// View a revision bool DoView(DirectoryGroups& dirGroups, std::string rev) { std::string dir = UniqueTemporaryDir(); std::string viewFile = dir; bool ok = true; CVSAction glue(0); std::string cvsroot; bool unixSandbox = IsUnixSandbox(StripLastPart(dirGroups.mySingleAbsolute)); if (!rev.empty()) { viewFile += "\\" + MakeRevFilename(ExtractLastPart(dirGroups.mySingleAbsolute), rev); DeleteFileA(viewFile.c_str()); } glue.SetProgressFinishedCaption(Printf(_("Viewing %s"), wxText(dirGroups.mySingleAbsolute).c_str())); glue.SetProgressCaption(Printf(_("Viewing %s"), wxText(dirGroups.mySingleAbsolute).c_str())); cvsroot = CVSStatus::CVSRootForPath(dirGroups.mySingleDirectory); // Viewing revision if (!rev.empty()) { glue.SetCVSRoot(CVSRoot(cvsroot)); MakeArgs args; std::string sTempDir = UniqueTemporaryDir(); glue.SetCloseIfOK(true); args.add_option("checkout"); if (unixSandbox) { CVSServerFeatures sf; sf.Initialize(&glue); sf.AddUnixLineEndingsFlag(args); } if (rev != "HEAD") { args.add_option("-r"); args.add_option(rev); } args.add_option("-d"); args.add_option("temp"); std::string s = EnsureTrailingUnixDelimiter(CVSStatus::CVSRepositoryForPath(dirGroups.mySingleAbsolute)) + ExtractLastPart(dirGroups.mySingleAbsolute); args.add_arg(s); ok = glue.Command(sTempDir, args); if (ok) { // Copy file to destination std::string file = EnsureTrailingDelimiter(sTempDir) + "temp\\" + ExtractLastPart(dirGroups.mySingleAbsolute); SetFileReadOnly(file.c_str(), false); CopyFileA(file.c_str(), viewFile.c_str(), false); SetFileReadOnly(viewFile.c_str(), true); } // Erase temporary directory DeleteDirectoryRec(sTempDir); if (!ok) goto Cleanup; } if (!FileExists(viewFile.c_str())) { DoMessageDialog(0, wxString(_("This file is new and has never been committed to the server or is an empty file on the server.")) + wxString(wxT("\n\n")) + wxString(wxText(dirGroups.mySingleAbsolute))); return true; } // Perform view, waiting for it to finish (so we can delete file) glue.LockProgressDialog(true); if (rev.empty()) LaunchFile(dirGroups.mySingleAbsolute, true); else LaunchFile(viewFile, true); glue.LockProgressDialog(false); Cleanup: // Clean up if (!rev.empty()) { SetFileReadOnly(viewFile.c_str(), false); DeleteFileA(viewFile.c_str()); } DeleteDirectoryRec(dir); return ok; }