Example #1
0
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;
}