-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathProgram.cs
138 lines (129 loc) · 5.94 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// <copyright file="Program.cs" company="Zhaoquan Huang">
// Copyright (c) Zhaoquan Huang. All rights reserved
// </copyright>
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Zhaobang.FtpServer.Authenticate;
using Zhaobang.FtpServer.Connections;
using Zhaobang.FtpServer.File;
namespace Zhaobang.FtpServer
{
/// <summary>
/// The main program.
/// </summary>
internal class Program
{
/// <summary>
/// The entry point of the program.
/// </summary>
/// <param name="args">Argumentss entered in the shell/param>.
private static void Main(string[] args)
{
Console.WriteLine("FTP Server by Zhaobang China");
Console.WriteLine("Server version: {0}", System.Reflection.Assembly.GetExecutingAssembly().GetName().Version);
Console.WriteLine("Library version: {0}", System.Reflection.Assembly.GetAssembly(typeof(FtpServer)).GetName().Version);
Console.WriteLine("This is an open source project. Project site: https://github.com/ZhaobangChina/FtpServer/tree/master/Server");
Console.WriteLine();
RunConfig config = RunConfig.Default;
XmlSerializer serializer = new XmlSerializer(typeof(RunConfig));
FileInfo configFileInfo = new FileInfo(Path.Combine(Environment.CurrentDirectory, "RunConfig.xml"));
List<FtpServer> servers = new List<FtpServer>();
if (configFileInfo.Exists)
{
using (Stream configFileStream = configFileInfo.OpenRead())
{
config = serializer.Deserialize(configFileStream) as RunConfig;
}
}
else
{
using (Stream configFileStream = configFileInfo.OpenWrite())
{
Console.WriteLine("Creating default config file at {0}", configFileInfo.FullName);
serializer.Serialize(configFileStream, config);
Console.WriteLine("Default config file created");
}
}
X509Certificate certificate = null;
try
{
if (!string.IsNullOrEmpty(config.CertificatePath))
{
certificate = new X509Certificate(config.CertificatePath, config.CertificatePassword);
config.CertificatePassword = null;
}
var cancelSource = new CancellationTokenSource();
var runResults = config.EndPoints.Select(
ep =>
{
var fileProviderFactory = new SimpleFileProviderFactory(config.BaseDirectory);
var dataConnectionFactory =
certificate == null ? new LocalDataConnectionFactory() : (IDataConnectionFactory)new SslLocalDataConnectionFactory(certificate);
var authenticator = new AnonymousAuthenticator();
var controlConnectionSslFactory =
certificate == null ? null : new ControlConnectionSslFactory(certificate);
var server = new FtpServer(ep, fileProviderFactory, dataConnectionFactory, authenticator, controlConnectionSslFactory);
servers.Add(server);
return server.RunAsync(cancelSource.Token)
.ContinueWith(result =>
{
if (result.Exception != null)
{
Console.WriteLine($"Server at {ep} has stopped because of: \n{result.Exception.Message}\n");
}
else
{
Console.WriteLine($"Server at {ep} has stopped successfully.");
}
});
})
.ToArray();
Console.WriteLine("FTP server has been started.");
Console.WriteLine("Config file: \n\t{0}", configFileInfo.FullName);
Console.WriteLine("Root dir: \n\t{0}", config.BaseDirectory);
Console.WriteLine(
"End points:\n\t{0}",
string.Join("\n\t", config.EndPoints.Select(ep => ep.ToString())));
Console.WriteLine("Use command \"quit\" to stop FTP server.");
Console.WriteLine("Use command \"users\" to list connected users.");
while (true)
{
var command = Console.ReadLine();
if (command.ToUpper(CultureInfo.InvariantCulture) == "QUIT")
{
cancelSource.Cancel();
Console.WriteLine("Stopped accepting new connections. Waiting until all clients quit.");
Task.WaitAll(runResults);
Console.WriteLine("Quited.");
return;
}
else if (command.ToUpper(CultureInfo.InvariantCulture) == "USERS")
{
Console.WriteLine("Connected users:");
foreach (var server in servers)
{
lock (server.Tracer.ConnectedUsersSyncRoot)
{
foreach (var user in server.Tracer.ConnectedUsersView)
{
Console.WriteLine(user.ToString());
}
}
}
}
}
}
finally
{
certificate.Dispose();
}
}
}
}