mirror of
https://github.com/livingcomputermuseum/IFS.git
synced 2026-05-04 15:06:17 +00:00
Cleanup, cleanup, cleanup. Fixed guest account a bit.
This commit is contained in:
@@ -131,7 +131,7 @@ namespace IFS.FTP
|
||||
if (!(e is ThreadAbortException))
|
||||
{
|
||||
Log.Write(LogType.Error, LogComponent.FTP, "FTP worker thread terminated with exception '{0}'.", e.Message);
|
||||
_channel.SendAbort("Server encountered an error.");
|
||||
Channel.SendAbort("Server encountered an error.");
|
||||
|
||||
OnExit(this);
|
||||
}
|
||||
@@ -300,7 +300,7 @@ namespace IFS.FTP
|
||||
{
|
||||
// Discard input until we get a Mark. We should (in general) get a
|
||||
// command, followed by EndOfCommand.
|
||||
FTPCommand command = (FTPCommand)_channel.WaitForMark();
|
||||
FTPCommand command = (FTPCommand)Channel.WaitForMark();
|
||||
|
||||
data = ReadNextCommandData();
|
||||
|
||||
@@ -344,7 +344,7 @@ namespace IFS.FTP
|
||||
|
||||
while(true)
|
||||
{
|
||||
int length = _channel.Read(ref buffer, buffer.Length);
|
||||
int length = Channel.Read(ref buffer, buffer.Length);
|
||||
|
||||
ms.Write(buffer, 0, length);
|
||||
|
||||
@@ -363,7 +363,7 @@ namespace IFS.FTP
|
||||
}
|
||||
|
||||
data = ms.ToArray();
|
||||
return (FTPCommand)_channel.LastMark;
|
||||
return (FTPCommand)Channel.LastMark;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -397,8 +397,8 @@ namespace IFS.FTP
|
||||
sb.Append(matchingFile.ToString());
|
||||
}
|
||||
|
||||
_channel.SendMark((byte)FTPCommand.HereIsPropertyList, false);
|
||||
_channel.Send(Helpers.StringToArray(sb.ToString()));
|
||||
Channel.SendMark((byte)FTPCommand.HereIsPropertyList, false);
|
||||
Channel.Send(Helpers.StringToArray(sb.ToString()));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -406,13 +406,13 @@ namespace IFS.FTP
|
||||
// command.
|
||||
foreach (PropertyList matchingFile in files)
|
||||
{
|
||||
_channel.SendMark((byte)FTPCommand.HereIsPropertyList, false);
|
||||
_channel.Send(Helpers.StringToArray(matchingFile.ToString()));
|
||||
Channel.SendMark((byte)FTPCommand.HereIsPropertyList, false);
|
||||
Channel.Send(Helpers.StringToArray(matchingFile.ToString()));
|
||||
}
|
||||
}
|
||||
|
||||
// End the enumeration.
|
||||
_channel.SendMark((byte)FTPCommand.EndOfCommand, true);
|
||||
Channel.SendMark((byte)FTPCommand.EndOfCommand, true);
|
||||
|
||||
}
|
||||
|
||||
@@ -460,7 +460,7 @@ namespace IFS.FTP
|
||||
Log.Write(LogType.Verbose, LogComponent.FTP, "Sending file...");
|
||||
|
||||
// Send the file data.
|
||||
_channel.SendMark((byte)FTPCommand.HereIsFile, true);
|
||||
Channel.SendMark((byte)FTPCommand.HereIsFile, true);
|
||||
data = new byte[512];
|
||||
|
||||
while (true)
|
||||
@@ -474,7 +474,7 @@ namespace IFS.FTP
|
||||
}
|
||||
|
||||
Log.Write(LogType.Verbose, LogComponent.FTP, "Sending data, current file position {0}.", outFile.Position);
|
||||
_channel.Send(data, read, true);
|
||||
Channel.Send(data, read, true);
|
||||
|
||||
if (read < data.Length)
|
||||
{
|
||||
@@ -486,13 +486,13 @@ namespace IFS.FTP
|
||||
|
||||
// End the file successfully. Note that we do NOT send an EOC here.
|
||||
Log.Write(LogType.Verbose, LogComponent.FTP, "Sent.");
|
||||
_channel.SendMark((byte)FTPCommand.Yes, false);
|
||||
_channel.Send(Serializer.Serialize(new FTPYesNoVersion(0, "File transferred successfully.")));
|
||||
Channel.SendMark((byte)FTPCommand.Yes, false);
|
||||
Channel.Send(Serializer.Serialize(new FTPYesNoVersion(0, "File transferred successfully.")));
|
||||
}
|
||||
|
||||
// End the transfer.
|
||||
Log.Write(LogType.Verbose, LogComponent.FTP, "All requested files sent.");
|
||||
_channel.SendMark((byte)FTPCommand.EndOfCommand, true);
|
||||
Channel.SendMark((byte)FTPCommand.EndOfCommand, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -544,7 +544,7 @@ namespace IFS.FTP
|
||||
//
|
||||
// We now expect a "Here-Is-File"...
|
||||
//
|
||||
FTPCommand hereIsFile = (FTPCommand)_channel.WaitForMark();
|
||||
FTPCommand hereIsFile = (FTPCommand)Channel.WaitForMark();
|
||||
|
||||
if (hereIsFile != FTPCommand.HereIsFile)
|
||||
{
|
||||
@@ -684,20 +684,20 @@ namespace IFS.FTP
|
||||
|
||||
// End the file successfully. Note that we do NOT send an EOC here, only after all files have been deleted.
|
||||
Log.Write(LogType.Verbose, LogComponent.FTP, "Deleted.");
|
||||
_channel.SendMark((byte)FTPCommand.Yes, false);
|
||||
_channel.Send(Serializer.Serialize(new FTPYesNoVersion(0, "File deleted successfully.")));
|
||||
Channel.SendMark((byte)FTPCommand.Yes, false);
|
||||
Channel.Send(Serializer.Serialize(new FTPYesNoVersion(0, "File deleted successfully.")));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// TODO: calculate real NO codes
|
||||
_channel.SendMark((byte)FTPCommand.No, false);
|
||||
_channel.Send(Serializer.Serialize(new FTPYesNoVersion((byte)NoCode.AccessDenied, e.Message)));
|
||||
Channel.SendMark((byte)FTPCommand.No, false);
|
||||
Channel.Send(Serializer.Serialize(new FTPYesNoVersion((byte)NoCode.AccessDenied, e.Message)));
|
||||
}
|
||||
}
|
||||
|
||||
// End the transfer.
|
||||
Log.Write(LogType.Verbose, LogComponent.FTP, "All requested files deleted.");
|
||||
_channel.SendMark((byte)FTPCommand.EndOfCommand, true);
|
||||
Channel.SendMark((byte)FTPCommand.EndOfCommand, true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -774,13 +774,13 @@ namespace IFS.FTP
|
||||
//
|
||||
// Send the property list (without EOC)
|
||||
//
|
||||
_channel.SendMark((byte)FTPCommand.HereIsPropertyList, false);
|
||||
_channel.Send(Helpers.StringToArray(mailProps.ToString()));
|
||||
Channel.SendMark((byte)FTPCommand.HereIsPropertyList, false);
|
||||
Channel.Send(Helpers.StringToArray(mailProps.ToString()));
|
||||
|
||||
//
|
||||
// Send the mail text.
|
||||
//
|
||||
_channel.SendMark((byte)FTPCommand.HereIsFile, true);
|
||||
Channel.SendMark((byte)FTPCommand.HereIsFile, true);
|
||||
byte[] data = new byte[512];
|
||||
|
||||
while (true)
|
||||
@@ -794,7 +794,7 @@ namespace IFS.FTP
|
||||
}
|
||||
|
||||
Log.Write(LogType.Verbose, LogComponent.FTP, "Sending mail data, current file position {0}.", mailStream.Position);
|
||||
_channel.Send(data, read, true);
|
||||
Channel.Send(data, read, true);
|
||||
|
||||
if (read < data.Length)
|
||||
{
|
||||
@@ -869,7 +869,7 @@ namespace IFS.FTP
|
||||
//
|
||||
// We now expect a "Here-Is-File"...
|
||||
//
|
||||
FTPCommand hereIsFile = (FTPCommand)_channel.WaitForMark();
|
||||
FTPCommand hereIsFile = (FTPCommand)Channel.WaitForMark();
|
||||
|
||||
if (hereIsFile != FTPCommand.HereIsFile)
|
||||
{
|
||||
@@ -951,6 +951,9 @@ namespace IFS.FTP
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates all files in the IFS FTP directory matching the specified specification, and returns a full PropertyList for each.
|
||||
///
|
||||
/// We also return all directories to make the directory structure discoverable. These are enumerated as "dirname <directory>"
|
||||
/// This doesn't match the original IFS behavior but is a lot nicer to deal with as an end-user.
|
||||
/// </summary>
|
||||
/// <param name="fileSpec"></param>
|
||||
/// <returns></returns>
|
||||
@@ -969,7 +972,31 @@ namespace IFS.FTP
|
||||
// These will be absolute paths.
|
||||
string[] matchingFiles = Directory.GetFiles(path, fileName, SearchOption.TopDirectoryOnly);
|
||||
|
||||
// Build a property list containing the required properties.
|
||||
// Find all directories that match the fileName, as above.
|
||||
string[] matchingDirectories = Directory.GetDirectories(path, fileName, SearchOption.TopDirectoryOnly);
|
||||
|
||||
// Build a property list containing the required properties for the directories
|
||||
// For now, we ignore any Desired-Property requests (this is legal) and return all properties we know about.
|
||||
foreach (string matchingDirectory in matchingDirectories)
|
||||
{
|
||||
string nameOnly = String.Format("{0} <directory>", Path.GetFileName(matchingDirectory));
|
||||
|
||||
PropertyList dirProps = new PropertyList();
|
||||
|
||||
dirProps.SetPropertyValue(KnownPropertyNames.ServerFilename, nameOnly);
|
||||
dirProps.SetPropertyValue(KnownPropertyNames.Directory, path);
|
||||
dirProps.SetPropertyValue(KnownPropertyNames.NameBody, nameOnly);
|
||||
dirProps.SetPropertyValue(KnownPropertyNames.Type, "Binary"); // We treat all files as binary for now
|
||||
dirProps.SetPropertyValue(KnownPropertyNames.ByteSize, "8"); // 8-bit bytes, please.
|
||||
dirProps.SetPropertyValue(KnownPropertyNames.Version, "1"); // No real versioning support
|
||||
dirProps.SetPropertyValue(KnownPropertyNames.CreationDate, File.GetCreationTime(matchingDirectory).ToString("dd-MMM-yy HH:mm:ss"));
|
||||
dirProps.SetPropertyValue(KnownPropertyNames.WriteDate, File.GetLastWriteTime(matchingDirectory).ToString("dd-MMM-yy HH:mm:ss"));
|
||||
dirProps.SetPropertyValue(KnownPropertyNames.ReadDate, File.GetLastAccessTime(matchingDirectory).ToString("dd-MMM-yy HH:mm:ss"));
|
||||
|
||||
properties.Add(dirProps);
|
||||
}
|
||||
|
||||
// Build a property list containing the required properties for the files.
|
||||
// For now, we ignore any Desired-Property requests (this is legal) and return all properties we know about.
|
||||
foreach (string matchingFile in matchingFiles)
|
||||
{
|
||||
@@ -1120,6 +1147,14 @@ namespace IFS.FTP
|
||||
string userName = fileSpec.GetPropertyValue(KnownPropertyNames.UserName);
|
||||
string password = String.Empty;
|
||||
|
||||
//
|
||||
// If the username is "guest" then we default to the guest account and ignore the password entirely.
|
||||
//
|
||||
if (userName == UserToken.Guest.UserName)
|
||||
{
|
||||
return UserToken.Guest;
|
||||
}
|
||||
|
||||
if (fileSpec.ContainsPropertyValue(KnownPropertyNames.UserPassword))
|
||||
{
|
||||
password = fileSpec.GetPropertyValue(KnownPropertyNames.UserPassword);
|
||||
@@ -1129,7 +1164,7 @@ namespace IFS.FTP
|
||||
|
||||
if (user == null)
|
||||
{
|
||||
SendFTPNoResponse(NoCode.AccessDenied, "Invalid username or password.");
|
||||
SendFTPNoResponse(NoCode.AccessDenied, "Invalid username or password.");
|
||||
}
|
||||
|
||||
return user;
|
||||
@@ -1157,30 +1192,30 @@ namespace IFS.FTP
|
||||
|
||||
private void SendFTPResponse(FTPCommand responseCommand, object data)
|
||||
{
|
||||
_channel.SendMark((byte)responseCommand, false);
|
||||
_channel.Send(Serializer.Serialize(data));
|
||||
_channel.SendMark((byte)FTPCommand.EndOfCommand, true);
|
||||
Channel.SendMark((byte)responseCommand, false);
|
||||
Channel.Send(Serializer.Serialize(data));
|
||||
Channel.SendMark((byte)FTPCommand.EndOfCommand, true);
|
||||
}
|
||||
|
||||
private void SendFTPResponse(FTPCommand responseCommand, PropertyList data)
|
||||
{
|
||||
_channel.SendMark((byte)responseCommand, false);
|
||||
_channel.Send(Helpers.StringToArray(data.ToString()));
|
||||
_channel.SendMark((byte)FTPCommand.EndOfCommand, true);
|
||||
Channel.SendMark((byte)responseCommand, false);
|
||||
Channel.Send(Helpers.StringToArray(data.ToString()));
|
||||
Channel.SendMark((byte)FTPCommand.EndOfCommand, true);
|
||||
}
|
||||
|
||||
private void SendFTPNoResponse(NoCode code, string message)
|
||||
{
|
||||
_channel.SendMark((byte)FTPCommand.No, false);
|
||||
_channel.Send(Serializer.Serialize(new FTPYesNoVersion((byte)code, message)));
|
||||
_channel.SendMark((byte)FTPCommand.EndOfCommand, true);
|
||||
Channel.SendMark((byte)FTPCommand.No, false);
|
||||
Channel.Send(Serializer.Serialize(new FTPYesNoVersion((byte)code, message)));
|
||||
Channel.SendMark((byte)FTPCommand.EndOfCommand, true);
|
||||
}
|
||||
|
||||
private void SendFTPYesResponse(string message)
|
||||
{
|
||||
_channel.SendMark((byte)FTPCommand.Yes, false);
|
||||
_channel.Send(Serializer.Serialize(new FTPYesNoVersion(1, message)));
|
||||
_channel.SendMark((byte)FTPCommand.EndOfCommand, true);
|
||||
Channel.SendMark((byte)FTPCommand.Yes, false);
|
||||
Channel.Send(Serializer.Serialize(new FTPYesNoVersion(1, message)));
|
||||
Channel.SendMark((byte)FTPCommand.EndOfCommand, true);
|
||||
}
|
||||
|
||||
private void ShutdownWorker()
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace IFS.FTP
|
||||
{
|
||||
public PropertyList()
|
||||
{
|
||||
_propertyList = new Dictionary<string, string>();
|
||||
_propertyList = new Dictionary<string, List<string>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -115,7 +115,7 @@ namespace IFS.FTP
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the value for the specified property, if present. Otherwise returns null.
|
||||
/// Returns the first value for the specified property, if present. Otherwise returns null.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
@@ -123,6 +123,26 @@ namespace IFS.FTP
|
||||
{
|
||||
name = name.ToLowerInvariant();
|
||||
|
||||
if (_propertyList.ContainsKey(name))
|
||||
{
|
||||
return _propertyList[name][0];
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the list of property values associated with the given property name, if present.
|
||||
/// Otherwise returns null.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <returns></returns>
|
||||
public List<string> GetPropertyValues(string name)
|
||||
{
|
||||
name = name.ToLowerInvariant();
|
||||
|
||||
if (_propertyList.ContainsKey(name))
|
||||
{
|
||||
return _propertyList[name];
|
||||
@@ -133,17 +153,44 @@ namespace IFS.FTP
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets a single value for the specified property, if present.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="value"></param>
|
||||
public void SetPropertyValue(string name, string value)
|
||||
{
|
||||
name = name.ToLowerInvariant();
|
||||
name = name.ToLowerInvariant();
|
||||
|
||||
List<string> newpList = new List<string>();
|
||||
newpList.Add(value);
|
||||
|
||||
if (_propertyList.ContainsKey(name))
|
||||
{
|
||||
_propertyList[name] = value;
|
||||
{
|
||||
_propertyList[name] = newpList;
|
||||
}
|
||||
else
|
||||
{
|
||||
_propertyList.Add(name, value);
|
||||
_propertyList.Add(name, newpList);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets multiple values for the specified property, if present.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="value"></param>
|
||||
public void SetPropertyValues(string name, List<string> values)
|
||||
{
|
||||
name = name.ToLowerInvariant();
|
||||
|
||||
if (_propertyList.ContainsKey(name))
|
||||
{
|
||||
_propertyList[name] = values;
|
||||
}
|
||||
else
|
||||
{
|
||||
_propertyList.Add(name, values);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,7 +207,10 @@ namespace IFS.FTP
|
||||
|
||||
foreach(string key in _propertyList.Keys)
|
||||
{
|
||||
sb.AppendFormat("({0} {1})", key, EscapeString(_propertyList[key]));
|
||||
foreach (string value in _propertyList[key])
|
||||
{
|
||||
sb.AppendFormat("({0} {1})", key, EscapeString(value));
|
||||
}
|
||||
}
|
||||
|
||||
// Closing paren
|
||||
@@ -297,17 +347,21 @@ namespace IFS.FTP
|
||||
//
|
||||
if (!_propertyList.ContainsKey(propertyName))
|
||||
{
|
||||
_propertyList.Add(propertyName, propertyValue.ToString());
|
||||
// New property key
|
||||
List<string> newpList = new List<string>();
|
||||
newpList.Add(propertyValue.ToString());
|
||||
_propertyList.Add(propertyName, newpList);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException(String.Format("Duplicate property entry for '{0}", propertyName));
|
||||
// Property key with multiple values
|
||||
_propertyList[propertyName].Add(propertyValue.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
return index + startOffset + 1;
|
||||
}
|
||||
|
||||
private Dictionary<string, string> _propertyList;
|
||||
private Dictionary<string, List<string>> _propertyList;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user