Skip to content

Commit

Permalink
refactor zOS: post-connect
Browse files Browse the repository at this point in the history
  • Loading branch information
robinrodricks committed Jan 2, 2022
1 parent 37d03dc commit 1a0b6e7
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 50 deletions.
26 changes: 6 additions & 20 deletions FluentFTP/Client/FtpClient_Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -516,16 +516,9 @@ public virtual void Connect() {
// FIX : #318 always set the type when we create a new connection
ForceSetDataType = true;

if (ServerType == FtpServer.IBMzOSFTP)
{
if (!(reply = Execute("SITE DATASETMODE")).Success)
{
throw new FtpCommandException(reply);
}
if (!(reply = Execute("SITE QUOTESOVERRIDE")).Success)
{
throw new FtpCommandException(reply);
}
// Execute server-specific post-connection event
if (ServerHandler != null) {
ServerHandler.AfterConnected(this);
}

#if !CORE14
Expand Down Expand Up @@ -703,16 +696,9 @@ public virtual void Connect() {
// FIX : #318 always set the type when we create a new connection
ForceSetDataType = true;

if (ServerType == FtpServer.IBMzOSFTP)
{
if (!(reply = await ExecuteAsync("SITE DATASETMODE", token)).Success)
{
throw new FtpCommandException(reply);
}
if (!(reply = await ExecuteAsync("SITE QUOTESOVERRIDE", token)).Success)
{
throw new FtpCommandException(reply);
}
// Execute server-specific post-connection event
if (ServerHandler != null) {
ServerHandler.AfterConnectedAsync(this, token);
}
}

Expand Down
46 changes: 29 additions & 17 deletions FluentFTP/Client/FtpClient_IBMzOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ public partial class FtpClient : IDisposable {
/// <returns>The realm</returns>
public FtpZOSListRealm GetZOSListRealm() {

LogFunc(nameof(GetZOSListRealm));

// this case occurs immediately after connection and after the working dir has changed
if (_LastWorkingDir == null) {
ReadCurrentWorkingDirectory();
Expand Down Expand Up @@ -87,45 +89,40 @@ public FtpZOSListRealm GetZOSListRealm() {
/// current working directory.
/// </summary>
/// <returns>The realm</returns>
public async Task<FtpZOSListRealm> GetZOSListRealmAsync(CancellationToken token = default(CancellationToken))
{
public async Task<FtpZOSListRealm> GetZOSListRealmAsync(CancellationToken token = default(CancellationToken)) {
LogFunc(nameof(GetZOSListRealmAsync));

// this case occurs immediately after connection and after the working dir has changed
if (_LastWorkingDir == null)
{
if (_LastWorkingDir == null) {
await ReadCurrentWorkingDirectoryAsync(token);
}

if (ServerType != FtpServer.IBMzOSFTP) {
if (ServerType != FtpServer.IBMzOSFTP) {
return FtpZOSListRealm.Invalid;
}

// It is a unix like path (starts with /)
if (_LastWorkingDir[0] != '\'')
{
if (_LastWorkingDir[0] != '\'') {
return FtpZOSListRealm.Unix;
}

// Ok, the CWD starts with a single quoute. Classic z/OS dataset realm
FtpReply reply;

// Go to where we are. The reply will tell us what it is we we are...
if (!(reply = await ExecuteAsync("CWD " + _LastWorkingDir, token)).Success)
{
if (!(reply = await ExecuteAsync("CWD " + _LastWorkingDir, token)).Success) {
throw new FtpCommandException(reply);
}

// 250-The working directory may be a load library
// 250 The working directory "GEEK.PRODUCTS.LOADLIB" is a partitioned data set

if (reply.InfoMessages!=null &&
reply.InfoMessages.Contains("may be a load library"))
{
if (reply.InfoMessages != null &&
reply.InfoMessages.Contains("may be a load library")) {
return FtpZOSListRealm.MemberU;
}

if (reply.Message.Contains("is a partitioned data set"))
{
if (reply.Message.Contains("is a partitioned data set")) {
return FtpZOSListRealm.Member;
}

Expand All @@ -145,6 +142,14 @@ public FtpZOSListRealm GetZOSListRealm() {
/// </remarks>
/// <returns>The size of the file</returns>
public long GetZOSFileSize(string path) {

// Verify args
if (path.IsBlank()) {
throw new ArgumentException("Required parameter is null or blank.", "path");
}

LogFunc(nameof(GetZOSFileSize), new object[] { path });

// prevent automatic parser detection switching to unix on HFS paths
ListingParser = FtpParser.IBMzOS;

Expand All @@ -169,13 +174,20 @@ public long GetZOSFileSize(string path) {
/// Make sure you are in the right realm (z/OS or HFS) before doing this
/// </remarks>
/// <returns>The size of the file</returns>
public async Task<long> GetZOSFileSizeAsync(string path, CancellationToken token = default(CancellationToken))
{
public async Task<long> GetZOSFileSizeAsync(string path, CancellationToken token = default(CancellationToken)) {// verify args

// Verify args
if (path.IsBlank()) {
throw new ArgumentException("Required parameter is null or blank.", "path");
}

LogFunc(nameof(GetZOSFileSizeAsync), new object[] { path });

// prevent automatic parser detection switching to unix on HFS paths
ListingParser = FtpParser.IBMzOS;

FtpListItem[] entries = await GetListingAsync(path, token);
// no entries or more than one: path is NOT for a single dataset or file
// no entries or more than one: path is NOT for a single dataset or file

if (entries.Length != 1) return -1;
// if the path is for a SINGLE dataset or file, there will be only one entry
Expand Down
21 changes: 8 additions & 13 deletions FluentFTP/Proxy/FtpClientSocks5Proxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,30 @@
#endif


namespace FluentFTP.Proxy
{
public class FtpClientSocks5Proxy : FtpClientProxy
{
public FtpClientSocks5Proxy(ProxyInfo proxy) : base(proxy)
{
namespace FluentFTP.Proxy {
/// <summary> A FTP client with a SOCKS5 proxy implementation. </summary>
public class FtpClientSocks5Proxy : FtpClientProxy {
public FtpClientSocks5Proxy(ProxyInfo proxy) : base(proxy) {
}

protected override void Connect(FtpSocketStream stream)
{
protected override void Connect(FtpSocketStream stream) {
base.Connect(stream);
var proxy = new SocksProxy(Host, Port, stream);
proxy.Negotiate();
proxy.Authenticate();
proxy.Connect();
}

protected override void Connect(FtpSocketStream stream, string host, int port, FtpIpVersion ipVersions)
{
protected override void Connect(FtpSocketStream stream, string host, int port, FtpIpVersion ipVersions) {
base.Connect(stream);
var proxy = new SocksProxy(Host, port, stream);
proxy.Negotiate();
proxy.Authenticate();
proxy.Connect();
}

#if ASYNC
protected override async Task ConnectAsync(FtpSocketStream stream, CancellationToken cancellationToken)
{
protected override async Task ConnectAsync(FtpSocketStream stream, CancellationToken cancellationToken) {
await base.ConnectAsync(stream, cancellationToken);
var proxy = new SocksProxy(Host, Port, stream);
await proxy.NegotiateAsync();
Expand Down
18 changes: 18 additions & 0 deletions FluentFTP/Servers/FtpBaseServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,5 +103,23 @@ public virtual async Task<bool> CreateDirectoryAsync(FtpClient client, string pa
}
#endif

/// <summary>
/// Perform server-specific post-connection commands here.
/// Return true if you executed a server-specific command.
/// </summary>
public virtual void AfterConnected(FtpClient client) {

}

#if ASYNC
/// <summary>
/// Perform server-specific post-connection commands here.
/// Return true if you executed a server-specific command.
/// </summary>
public virtual async Task AfterConnectedAsync(FtpClient client, CancellationToken token) {

}
#endif

}
}
29 changes: 29 additions & 0 deletions FluentFTP/Servers/Handlers/IbmZosFtpServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,34 @@ public override FtpParser GetParser() {
return FtpParser.IBMzOS;
}

/// <summary>
/// Perform server-specific post-connection commands here.
/// Return true if you executed a server-specific command.
/// </summary>
public override void AfterConnected(FtpClient client) {
FtpReply reply;
if (!(reply = client.Execute("SITE DATASETMODE")).Success) {
throw new FtpCommandException(reply);
}
if (!(reply = client.Execute("SITE QUOTESOVERRIDE")).Success) {
throw new FtpCommandException(reply);
}
}

#if ASYNC
/// <summary>
/// Perform server-specific post-connection commands here.
/// Return true if you executed a server-specific command.
/// </summary>
public override async Task AfterConnectedAsync(FtpClient client, CancellationToken token) {
FtpReply reply;
if (!(reply = await client.ExecuteAsync("SITE DATASETMODE", token)).Success) {
throw new FtpCommandException(reply);
}
if (!(reply = await client.ExecuteAsync("SITE QUOTESOVERRIDE", token)).Success) {
throw new FtpCommandException(reply);
}
}
#endif
}
}

0 comments on commit 1a0b6e7

Please sign in to comment.