// CVSServerConnection.cs
// Copyright (C) 2001 Mike Krueger
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// As a special exception, if you link this library with other files to
// produce an executable, this library does not by itself cause the
// resulting executable to be covered by the GNU General Public License.
// This exception does not however invalidate any other reasons why the
// executable file might be covered by the GNU General Public License.
using System;
using System.IO;
using System.Collections;
using System.Threading;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Diagnostics;
using CVS.Misc;
using CVS.Requests;
using CVS.Responses;
using CVS.FileHandler;
namespace CVS{
public delegate void MessageEventHandler(string message);
public class CVSServerConnection : IConnection, IResponseServices
{
const int DEFAULT_PORT = 2401;
string nextFileDate;
TcpClient tcpclient = null;
CvsStream inputstream = null;
CvsStream outputstream = null;
WorkingDirectory repository;
IFileHandler uncompressedFileHandler = new UncompressedFileHandler();
public IFileHandler UncompressedFileHandler {
get {
return uncompressedFileHandler;
}
}
public CvsStream InputStream {
get {
return inputstream;
}
set {
inputstream = value;
}
}
public CvsStream OutputStream {
get {
return outputstream;
}
set {
outputstream = value;
}
}
public event MessageEventHandler MessageEvent;
public void SendMessage(string message)
{
if (MessageEvent != null) {
MessageEvent(message);
}
}
class Module
{
public string localdir = null;
public ArrayList entries = new ArrayList();
}
void HandleResponses()
{
SortedList modules = new SortedList();
while (true) {
string responseStr = inputstream.ReadToFirstWS();
Console.WriteLine("Response : " + responseStr);
if (responseStr.Length == 0) {
SendMessage("server timed out");
break;
}
IResponse response = ResponseFactory.CreateResponse(responseStr.Substring(0, responseStr.Length - 1));
Console.WriteLine("got : " + response);
if (response == null) {
if (responseStr.EndsWith(" ")) {
inputstream.ReadLine();
}
break;
}
response.Process(inputstream, this);
if (response.IsTerminating) {
break;
}
}
// repository.CreateCVSFiles();
}
public void SubmitRequest(IRequest request)
{
Console.WriteLine("send : " + request.RequestString);
outputstream.SendString(request.RequestString);
if (request.DoesModifyConnection) {
request.ModifyConnection(this);
}
if (request.IsResponseExpected) {
HandleResponses();
}
}
public void Connect(WorkingDirectory repository, string password)
{
this.repository = repository;
Authentification(password);
}
string shell = "ssh";
public string Shell {
get {
return shell;
}
set {
shell = value;
}
}
Process p = null;
void ExitShellEvent(object sender, EventArgs e)
{
Console.WriteLine("Process EXITED");
if (p.ExitCode != 0) {
throw new AuthentificationFailedException();
}
}
public void Authentification(string password)
{
switch (repository.CvsRoot.Protocol) {
case "ext":
try {
ProcessStartInfo startInfo = new ProcessStartInfo(shell, "-l " + repository.CvsRoot.User + " " + repository.CvsRoot.Host + " \"cvs server\"");
Console.WriteLine("-l " + repository.CvsRoot.User + " " + repository.CvsRoot.Host + " \"cvs server\"");
startInfo.RedirectStandardError = true;
startInfo.RedirectStandardInput = true;
startInfo.RedirectStandardOutput = true;
startInfo.UseShellExecute = false;
p = new Process();
p.StartInfo = startInfo;
p.Exited += new EventHandler(ExitShellEvent);
p.Start();
} catch (Exception e) {
Console.WriteLine(e.ToString());
throw new CantExecuteShellException(shell);
}
BufferedStream errstream = new BufferedStream(p.StandardError.BaseStream);
inputstream = new CvsStream(new BufferedStream(p.StandardOutput.BaseStream));
outputstream = new CvsStream(new BufferedStream(p.StandardInput.BaseStream));
break;
case "pserver":
tcpclient = new TcpClient();
tcpclient.Connect(repository.CvsRoot.Host, DEFAULT_PORT);
inputstream = outputstream = new CvsStream(tcpclient.GetStream());
SubmitRequest(new PServerAuthRequest(repository.CvsRoot.CvsRepository, repository.CvsRoot.User, password));
inputstream.Flush();
string retStr = inputstream.ReadLine();
switch (retStr) {
case "I LOVE YOU":
SendMessage("Connection established");
break;
case "I HATE YOU":
throw new AuthentificationFailedException();
default:
SendMessage("Unknown Server response : >" + retStr + "<");
throw new ApplicationException("Unknown Server response : >" + retStr + "<"); // TODO : invent a better exception for this case.
}
break;
}
SubmitRequest(new ValidResponsesRequest());
SubmitRequest(new ValidRequestsRequest());
SubmitRequest(new RootRequest(repository.CvsRoot.CvsRepository));
SubmitRequest(new UseUnchangedRequest());
}
public string ConvertPath(string localPath, string repository)
{
return localPath + repository.Replace("/", Path.DirectorySeparatorChar.ToString()).Replace("\\", Path.DirectorySeparatorChar.ToString());
}
public void SetEntry(string localFile, Entry entry)
{
// TODO : implement set entry
}
public WorkingDirectory Repository {
get {
return repository;
}
}
public string NextFileDate {
get {
return nextFileDate;
}
set {
nextFileDate = value;
}
}
string nextFile = null;
public string NextFile {
get {
return nextFile;
}
set {
nextFile = value;
}
}
public void Close()
{
if (repository != null && repository.CvsRoot != null) {
switch (repository.CvsRoot.Protocol) {
case "ext":
if (p != null && !p.HasExited) {
p.Kill();
p.WaitForExit();
p = null;
}
break;
}
}
}
}
}
|