| 1: | // CVSServerConnection.cs | |
| 2: | // Copyright (C) 2001 Mike Krueger | |
| 3: | // | |
| 4: | // This program is free software; you can redistribute it and/or | |
| 5: | // modify it under the terms of the GNU General Public License | |
| 6: | // as published by the Free Software Foundation; either version 2 | |
| 7: | // of the License, or (at your option) any later version. | |
| 8: | // | |
| 9: | // This program is distributed in the hope that it will be useful, | |
| 10: | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| 11: | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| 12: | // GNU General Public License for more details. | |
| 13: | // | |
| 14: | // You should have received a copy of the GNU General Public License | |
| 15: | // along with this program; if not, write to the Free Software | |
| 16: | // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
| 17: | // | |
| 18: | // As a special exception, the copyright holders of this library give you | |
| 19: | // permission to link this library with independent modules to produce an | |
| 20: | // executable, regardless of the license terms of these independent | |
| 21: | // modules, and to copy and distribute the resulting executable under | |
| 22: | // terms of your choice, provided that you also meet, for each linked | |
| 23: | // independent module, the terms and conditions of the license of that | |
| 24: | // module. An independent module is a module which is not derived from | |
| 25: | // or based on this library. If you modify this library, you may extend | |
| 26: | // this exception to your version of the library, but you are not | |
| 27: | // obligated to do so. If you do not wish to do so, delete this | |
| 28: | // exception statement from your version. | |
| 29: | ||
| 30: | using System; | |
| 31: | using System.IO; | |
| 32: | using System.Collections; | |
| 33: | using System.Threading; | |
| 34: | using System.Text; | |
| 35: | using System.Net; | |
| 36: | using System.Net.Sockets; | |
| 37: | using System.Diagnostics; | |
| 38: | ||
| 39: | using ICSharpCode.SharpCvsLib.Misc; | |
| 40: | using ICSharpCode.SharpCvsLib.Requests; | |
| 41: | using ICSharpCode.SharpCvsLib.Responses; | |
| 42: | using ICSharpCode.SharpCvsLib.FileHandler; | |
| 43: | ||
| 44: | namespace ICSharpCode.SharpCvsLib { | |
| 45: | ||
| 46: | public delegate void MessageEventHandler(string message); | |
| 47: | ||
| 48: | public class CVSServerConnection : IConnection, IResponseServices | |
| 49: | { | |
| 50: | const int DEFAULT_PORT = 2401; | |
| 51: | ||
| 52: | string nextFileDate; | |
| 53: | ||
| 54: | TcpClient tcpclient = null; | |
| 55: | ||
| 56: | CvsStream inputstream = null; | |
| 57: | CvsStream outputstream = null; | |
| 58: | ||
| 59: | WorkingDirectory repository; | |
| 60: | ||
| 61: | IFileHandler uncompressedFileHandler = new UncompressedFileHandler(); | |
| 62: | ||
| 63: | public IFileHandler UncompressedFileHandler { | |
| 64: | get { | |
| 65: | return uncompressedFileHandler; | |
| 66: | } | |
| 67: | } | |
| 68: | ||
| 69: | public CvsStream InputStream { | |
| 70: | get { | |
| 71: | return inputstream; | |
| 72: | } | |
| 73: | set { | |
| 74: | inputstream = value; | |
| 75: | } | |
| 76: | } | |
| 77: | ||
| 78: | public CvsStream OutputStream { | |
| 79: | get { | |
| 80: | return outputstream; | |
| 81: | } | |
| 82: | set { | |
| 83: | outputstream = value; | |
| 84: | } | |
| 85: | } | |
| 86: | ||
| 87: | public event MessageEventHandler MessageEvent; | |
| 88: | ||
| 89: | public void SendMessage(string message) | |
| 90: | { | |
| 91: | if (MessageEvent != null) { | |
| 92: | MessageEvent(message); | |
| 93: | } | |
| 94: | } | |
| 95: | ||
| 96: | class Module | |
| 97: | { | |
| 98: | public string localdir = null; | |
| 99: | public ArrayList entries = new ArrayList(); | |
| 100: | } | |
| 101: | ||
| 102: | void HandleResponses() | |
| 103: | { | |
| 104: | SortedList modules = new SortedList(); | |
| 105: | ||
| 106: | while (true) { | |
| 107: | string responseStr = inputstream.ReadToFirstWS(); | |
| 108: | Console.WriteLine("Response : " + responseStr); | |
| 109: | ||
| 110: | if (responseStr.Length == 0) { | |
| 111: | SendMessage("server timed out"); | |
| 112: | break; | |
| 113: | } | |
| 114: | ||
| 115: | IResponse response = ResponseFactory.CreateResponse(responseStr.Substring(0, responseStr.Length - 1)); | |
| 116: | Console.WriteLine("got : " + response); | |
| 117: | ||
| 118: | if (response == null) { | |
| 119: | if (responseStr.EndsWith(" ")) { | |
| 120: | inputstream.ReadLine(); | |
| 121: | } | |
| 122: | break; | |
| 123: | } | |
| 124: | response.Process(inputstream, this); | |
| 125: | if (response.IsTerminating) { | |
| 126: | break; | |
| 127: | } | |
| 128: | } | |
| 129: | // repository.CreateCVSFiles(); | |
| 130: | } | |
| 131: | ||
| 132: | public void SubmitRequest(IRequest request) | |
| 133: | { | |
| 134: | Console.WriteLine("send : " + request.RequestString); | |
| 135: | ||
| 136: | outputstream.SendString(request.RequestString); | |
| 137: | ||
| 138: | if (request.DoesModifyConnection) { | |
| 139: | request.ModifyConnection(this); | |
| 140: | } | |
| 141: | ||
| 142: | if (request.IsResponseExpected) { | |
| 143: | HandleResponses(); | |
| 144: | } | |
| 145: | } | |
| 146: | ||
| 147: | public void Connect(WorkingDirectory repository, string password) | |
| 148: | { | |
| 149: | this.repository = repository; | |
| 150: | Authentification(password); | |
| 151: | } | |
| 152: | ||
| 153: | string shell = "ssh"; | |
| 154: | public string Shell { | |
| 155: | get { | |
| 156: | return shell; | |
| 157: | } | |
| 158: | set { | |
| 159: | shell = value; | |
| 160: | } | |
| 161: | } | |
| 162: | ||
| 163: | Process p = null; | |
| 164: | ||
| 165: | void ExitShellEvent(object sender, EventArgs e) | |
| 166: | { | |
| 167: | Console.WriteLine("Process EXITED"); | |
| 168: | if (p.ExitCode != 0) { | |
| 169: | throw new AuthentificationFailedException(); | |
| 170: | } | |
| 171: | } | |
| 172: | ||
| 173: | public void Authentification(string password) | |
| 174: | { | |
| 175: | switch (repository.CvsRoot.Protocol) { | |
| 176: | case "ext": | |
| 177: | try { | |
| 178: | ProcessStartInfo startInfo = new ProcessStartInfo(shell, "-l " + repository.CvsRoot.User + " " + repository.CvsRoot.Host + " \"cvs server\""); | |
| 179: | Console.WriteLine("-l " + repository.CvsRoot.User + " " + repository.CvsRoot.Host + " \"cvs server\""); | |
| 180: | startInfo.RedirectStandardError = true; | |
| 181: | startInfo.RedirectStandardInput = true; | |
| 182: | startInfo.RedirectStandardOutput = true; | |
| 183: | startInfo.UseShellExecute = false; | |
| 184: | p = new Process(); | |
| 185: | p.StartInfo = startInfo; | |
| 186: | p.Exited += new EventHandler(ExitShellEvent); | |
| 187: | p.Start(); | |
| 188: | } catch (Exception e) { | |
| 189: | Console.WriteLine(e.ToString()); | |
| 190: | throw new CantExecuteShellException(shell); | |
| 191: | } | |
| 192: | BufferedStream errstream = new BufferedStream(p.StandardError.BaseStream); | |
| 193: | inputstream = new CvsStream(new BufferedStream(p.StandardOutput.BaseStream)); | |
| 194: | outputstream = new CvsStream(new BufferedStream(p.StandardInput.BaseStream)); | |
| 195: | break; | |
| 196: | case "pserver": | |
| 197: | tcpclient = new TcpClient(); | |
| 198: | tcpclient.Connect(repository.CvsRoot.Host, DEFAULT_PORT); | |
| 199: | inputstream = outputstream = new CvsStream(tcpclient.GetStream()); | |
| 200: | SubmitRequest(new PServerAuthRequest(repository.CvsRoot.CvsRepository, repository.CvsRoot.User, password)); | |
| 201: | inputstream.Flush(); | |
| 202: | string retStr = inputstream.ReadLine(); | |
| 203: | switch (retStr) { | |
| 204: | case "I LOVE YOU": | |
| 205: | SendMessage("Connection established"); | |
| 206: | break; | |
| 207: | case "I HATE YOU": | |
| 208: | throw new AuthentificationFailedException(); | |
| 209: | default: | |
| 210: | SendMessage("Unknown Server response : >" + retStr + "<"); | |
| 211: | throw new ApplicationException("Unknown Server response : >" + retStr + "<"); // TODO : invent a better exception for this case. | |
| 212: | } | |
| 213: | break; | |
| 214: | } | |
| 215: | SubmitRequest(new ValidResponsesRequest()); | |
| 216: | SubmitRequest(new ValidRequestsRequest()); | |
| 217: | ||
| 218: | SubmitRequest(new RootRequest(repository.CvsRoot.CvsRepository)); | |
| 219: | SubmitRequest(new UseUnchangedRequest()); | |
| 220: | } | |
| 221: | ||
| 222: | public string ConvertPath(string localPath, string repository) | |
| 223: | { | |
| 224: | return localPath + repository.Replace("/", Path.DirectorySeparatorChar.ToString()).Replace("\\", Path.DirectorySeparatorChar.ToString()); | |
| 225: | } | |
| 226: | ||
| 227: | public void SetEntry(string localFile, Entry entry) | |
| 228: | { | |
| 229: | // TODO : implement set entry | |
| 230: | } | |
| 231: | ||
| 232: | public WorkingDirectory Repository { | |
| 233: | get { | |
| 234: | return repository; | |
| 235: | } | |
| 236: | } | |
| 237: | ||
| 238: | public string NextFileDate { | |
| 239: | get { | |
| 240: | return nextFileDate; | |
| 241: | } | |
| 242: | set { | |
| 243: | nextFileDate = value; | |
| 244: | } | |
| 245: | } | |
| 246: | string nextFile = null; | |
| 247: | public string NextFile { | |
| 248: | get { | |
| 249: | return nextFile; | |
| 250: | } | |
| 251: | set { | |
| 252: | nextFile = value; | |
| 253: | } | |
| 254: | } | |
| 255: | ||
| 256: | public void Close() | |
| 257: | { | |
| 258: | if (repository != null && repository.CvsRoot != null) { | |
| 259: | switch (repository.CvsRoot.Protocol) { | |
| 260: | case "ext": | |
| 261: | if (p != null && !p.HasExited) { | |
| 262: | p.Kill(); | |
| 263: | p.WaitForExit(); | |
| 264: | p = null; | |
| 265: | } | |
| 266: | break; | |
| 267: | } | |
| 268: | } | |
| 269: | } | |
| 270: | } | |
| 271: | } |
This page was automatically generated by SharpDevelop.