/// <summary> /// Parses Unix format listings /// </summary> /// <param name="client">The FTP client</param> /// <param name="record">A line from the listing</param> /// <returns>FtpListItem if the item is able to be parsed</returns> public static FtpListItem Parse(FtpClient client, string record) { // test it is a valid line, e.g. "total 342522" is invalid var ch = record[0]; if (ch != FileMarker && ch != DirectoryMarker && ch != SymbolicLinkMarker) { return(null); } var values = record.SplitString(); if (values.Length < MinFieldCount) { var msg = new StringBuilder("Unexpected number of fields in listing '"); msg .Append(record) .Append("' - expected minimum ").Append(MinFieldCount) .Append(" fields but found ").Append(values.Length).Append(" fields"); client.LogStatus(FtpTraceLevel.Verbose, msg.ToString()); return(null); } // field pos var index = 0; // first field is perms string permissions; bool isDir, isLink; ParsePermissions(values, ref index, out permissions, out isDir, out isLink); // some servers don't supply the link count var linkCount = ParseLinkCount(client, values, ref index); // parse owner & group permissions string owner, group; ParseOwnerGroup(values, ref index, out owner, out group); // parse size var size = ParseFileSize(client, values, ref index); // parse the date/time fields var dayOfMonth = ParseDayOfMonth(values, ref index); var dateTimePos = index; var lastModified = DateTime.MinValue; ParseDateTime(client, values, ref index, dayOfMonth, ref lastModified); // parse name of file or dir. Extract symlink if possible string name = null; string linkedname = null; ParseName(client, record, values, isLink, dayOfMonth, dateTimePos, ref name, ref linkedname); // create a new list item object with the parsed metadata var file = new FtpListItem(record, name, size, isDir, ref lastModified); if (isLink) { file.Type = FtpFileSystemObjectType.Link; file.LinkCount = linkCount; file.LinkTarget = linkedname.Trim(); } file.RawGroup = group; file.RawOwner = owner; file.RawPermissions = permissions; file.CalculateUnixPermissions(permissions); return(file); }
/// <summary> /// Parses Unix format listings with alternate parser /// </summary> /// <param name="record">A line from the listing</param> /// <returns>FtpListItem if the item is able to be parsed</returns> public static FtpListItem ParseUnixAlt(FtpClient client, string record) { // test it is a valid line, e.g. "total 342522" is invalid var ch = record[0]; if (ch != FileMarker && ch != DirectoryMarker && ch != SymbolicLinkMarker) { return(null); } var values = record.SplitString(); if (values.Length < MinFieldCountAlt) { var listing = new StringBuilder("Unexpected number of fields in listing '"); listing.Append(record) .Append("' - expected minimum ").Append(MinFieldCountAlt) .Append(" fields but found ").Append(values.Length).Append(" fields"); throw new FormatException(listing.ToString()); } // field pos var index = 0; // first field is perms var permissions = values[index++]; ch = permissions[0]; var isDir = false; var isLink = false; if (ch == DirectoryMarker) { isDir = true; } else if (ch == SymbolicLinkMarker) { isLink = true; } var group = values[index++]; // some servers don't supply the link count var linkCount = 0; if (char.IsDigit(values[index][0])) { // assume it is if a digit var linkCountStr = values[index++]; try { linkCount = int.Parse(linkCountStr); } catch (FormatException) { client.LogStatus(FtpTraceLevel.Error, "Failed to parse link count: " + linkCountStr); } } var owner = values[index++]; // size var size = 0L; var sizeStr = values[index++]; try { size = long.Parse(sizeStr); } catch (FormatException) { client.LogStatus(FtpTraceLevel.Error, "Failed to parse size: " + sizeStr); } // next 3 fields are the date time // we expect the month first on Unix. var dateTimePos = index; var lastModified = DateTime.MinValue; var stamp = new StringBuilder(values[index++]); stamp.Append('-').Append(values[index++]).Append('-'); var field = values[index++]; if (field.IndexOf((char)':') < 0) { stamp.Append(field); // year try { lastModified = DateTime.ParseExact(stamp.ToString(), DateTimeAltFormats1, client.ListingCulture.DateTimeFormat, DateTimeStyles.None); } catch (FormatException) { client.LogStatus(FtpTraceLevel.Error, "Failed to parse date string '" + stamp.ToString() + "'"); } } else { // add the year ourselves as not present var year = client.ListingCulture.Calendar.GetYear(DateTime.Now); stamp.Append(year).Append('-').Append(field); try { lastModified = DateTime.ParseExact(stamp.ToString(), DateTimeAltFormats2, client.ListingCulture.DateTimeFormat, DateTimeStyles.None); } catch (FormatException) { client.LogStatus(FtpTraceLevel.Error, "Failed to parse date string '" + stamp.ToString() + "'"); } // can't be in the future - must be the previous year // add 2 days for time zones (thanks hgfischer) if (lastModified > DateTime.Now.AddDays(2)) { lastModified = lastModified.AddYears(-1); } } // name of file or dir. Extract symlink if possible string name = null; // find the starting point of the name by finding the pos of all the date/time fields var pos = 0; var ok = true; for (var i = dateTimePos; i < dateTimePos + 3; i++) { pos = record.IndexOf(values[i], pos); if (pos < 0) { ok = false; break; } else { pos += values[i].Length; } } if (ok) { name = record.Substring(pos).Trim(); } else { client.LogStatus(FtpTraceLevel.Error, "Failed to retrieve name: " + record); } // create a new list item object with the parsed metadata var file = new FtpListItem(record, name, size, isDir, ref lastModified); if (isLink) { file.Type = FtpFileSystemObjectType.Link; file.LinkCount = linkCount; } file.RawGroup = group; file.RawOwner = owner; file.RawPermissions = permissions; file.CalculateUnixPermissions(permissions); return(file); }
private void lvFTPList_DragDrop(object sender, DragEventArgs e) { if (e.Data.GetDataPresent(typeof(string[]))) { Point point = lvFTPList.PointToClient(new Point(e.X, e.Y)); ListViewItem lvi = lvFTPList.GetItemAt(point.X, point.Y); if (lvi != null && e.AllowedEffect == DragDropEffects.Move) { if (tempSelected != null && tempSelected != lvi) { tempSelected.Selected = false; } FtpListItem file = lvi.Tag as FtpListItem; if (file != null && file.Type == FtpFileSystemObjectType.Directory) { string[] filenames = e.Data.GetData(typeof(string[])) as string[]; if (filenames != null) { int renameCount = 0; foreach (string filename in filenames) { if (file.Name != filename) { string path = Helpers.CombineURL(currentDirectory, filename); string movePath = string.Empty; if (file.Type == FtpFileSystemObjectType.Link) { if (file.Name == ".") { movePath = URLHelpers.AddSlash(filename, SlashType.Prefix, 2); } else if (file.Name == "..") { movePath = URLHelpers.AddSlash(filename, SlashType.Prefix); } } else { movePath = Helpers.CombineURL(file.FullName, filename); } if (!string.IsNullOrEmpty(movePath)) { Client.Rename(path, movePath); renameCount++; } } } if (renameCount > 0) { RefreshDirectory(); } } } } tempSelected = null; } else if (e.Data.GetDataPresent(DataFormats.FileDrop)) { string[] files = e.Data.GetData(DataFormats.FileDrop) as string[]; if (files != null) { Client.UploadFiles(files, currentDirectory); RefreshDirectory(); } } }
/// <summary> /// Parses LIST format listings /// </summary> /// <param name="buf">A line from the listing</param> /// <param name="capabilities">Server capabilities</param> /// <returns>FtpListItem if the item is able to be parsed</returns> static FtpListItem ParseUnixList(string buf, FtpCapability capabilities) { FtpListItem item = new FtpListItem(); Match m = null; string regex = @"(?<permissions>[\w-]{10})\s+" + @"(?<objectcount>\d+)\s+" + @"(?<user>[\w\d]+)\s+" + @"(?<group>[\w\d]+)\s+" + @"(?<size>\d+)\s+" + @"(?<modify>\w+\s+\d+\s+\d+:\d+|\w+\s+\d+\s+\d+)\s+" + @"(?<name>.*)$"; if (!(m = Regex.Match(buf, regex, RegexOptions.IgnoreCase)).Success) { return(null); } if (m.Groups["permissions"].Value.StartsWith("d")) { item.Type = FtpFileSystemObjectType.Directory; } else if (m.Groups["permissions"].Value.StartsWith("-")) { item.Type = FtpFileSystemObjectType.File; } else { return(null); } // if we can't determine a file name then // we are not considering this a successful parsing operation. if (m.Groups["name"].Value.Length < 1) { return(null); } item.Name = m.Groups["name"].Value; if (item.Type == FtpFileSystemObjectType.Directory && (item.Name == "." || item.Name == "..")) { return(null); } //// // Ignore the Modify times sent in LIST format for files // when the server has support for the MDTM command // because they will never be as accurate as what can be had // by using the MDTM command. MDTM does not work on directories // so if a modify time was parsed from the listing we will try // to convert it to a DateTime object and use it for directories. //// if ((!capabilities.HasFlag(FtpCapability.MDTM) || item.Type == FtpFileSystemObjectType.Directory) && m.Groups["modify"].Value.Length > 0) { item.Modified = m.Groups["modify"].Value.GetFtpDate(DateTimeStyles.AssumeUniversal); } if (m.Groups["size"].Value.Length > 0) { long size; if (long.TryParse(m.Groups["size"].Value, out size)) { item.Size = size; } } if (m.Groups["permissions"].Value.Length > 0) { Match perms = Regex.Match(m.Groups["permissions"].Value, @"[\w-]{1}(?<owner>[\w-]{3})(?<group>[\w-]{3})(?<others>[\w-]{3})", RegexOptions.IgnoreCase); if (perms.Success) { if (perms.Groups["owner"].Value.Length == 3) { if (perms.Groups["owner"].Value[0] == 'r') { item.OwnerPermissions |= FtpPermission.Read; } if (perms.Groups["owner"].Value[1] == 'w') { item.OwnerPermissions |= FtpPermission.Write; } if (perms.Groups["owner"].Value[2] == 'x' || perms.Groups["owner"].Value[2] == 's') { item.OwnerPermissions |= FtpPermission.Execute; } if (perms.Groups["owner"].Value[2] == 's' || perms.Groups["owner"].Value[2] == 'S') { item.SpecialPermissions |= FtpSpecialPermissions.SetUserID; } } if (perms.Groups["group"].Value.Length == 3) { if (perms.Groups["group"].Value[0] == 'r') { item.GroupPermissions |= FtpPermission.Read; } if (perms.Groups["group"].Value[1] == 'w') { item.GroupPermissions |= FtpPermission.Write; } if (perms.Groups["group"].Value[2] == 'x' || perms.Groups["group"].Value[2] == 's') { item.GroupPermissions |= FtpPermission.Execute; } if (perms.Groups["group"].Value[2] == 's' || perms.Groups["group"].Value[2] == 'S') { item.SpecialPermissions |= FtpSpecialPermissions.SetGroupID; } } if (perms.Groups["others"].Value.Length == 3) { if (perms.Groups["others"].Value[0] == 'r') { item.OthersPermissions |= FtpPermission.Read; } if (perms.Groups["others"].Value[1] == 'w') { item.OthersPermissions |= FtpPermission.Write; } if (perms.Groups["others"].Value[2] == 'x' || perms.Groups["others"].Value[2] == 't') { item.OthersPermissions |= FtpPermission.Execute; } if (perms.Groups["others"].Value[2] == 't' || perms.Groups["others"].Value[2] == 'T') { item.SpecialPermissions |= FtpSpecialPermissions.Sticky; } } } } return(item); }
/// <summary> /// Parses LIST format listings /// </summary> /// <param name="record">A line from the listing</param> /// <param name="capabilities">Server capabilities</param> /// <returns>FtpListItem if the item is able to be parsed</returns> public static FtpListItem ParseLegacy(string record, List <FtpCapability> capabilities, FtpClient client) { var regex = @"(?<permissions>.+)\s+" + @"(?<objectcount>\d+)\s+" + @"(?<user>.+)\s+" + @"(?<group>.+)\s+" + @"(?<size>\d+)\s+" + @"(?<modify>\w+\s+\d+\s+\d+:\d+|\w+\s+\d+\s+\d+)\s" + @"(?<name>.*)$"; var item = new FtpListItem(); Match m; if (!(m = Regex.Match(record, regex, RegexOptions.IgnoreCase)).Success) { return(null); } // if this field is missing we can't determine // what the object is. if (m.Groups["permissions"].Value.Length == 0) { return(null); } switch (m.Groups["permissions"].Value[0]) { case 'd': item.Type = FtpFileSystemObjectType.Directory; break; case '-': case 's': item.Type = FtpFileSystemObjectType.File; break; case 'l': item.Type = FtpFileSystemObjectType.Link; break; default: return(null); } // if we can't determine a file name then // we are not considering this a successful parsing operation. if (m.Groups["name"].Value.Length < 1) { return(null); } item.Name = m.Groups["name"].Value; switch (item.Type) { case FtpFileSystemObjectType.Directory: // ignore these... if (item.Name == "." || item.Name == "..") { return(null); } break; case FtpFileSystemObjectType.Link: if (!item.Name.Contains(" -> ")) { return(null); } item.LinkTarget = item.Name.Remove(0, item.Name.IndexOf("-> ") + 3).Trim(); item.Name = item.Name.Remove(item.Name.IndexOf(" -> ")); break; } // Ignore the Modify times sent in LIST format for files // when the server has support for the MDTM command // because they will never be as accurate as what can be had // by using the MDTM command. MDTM does not work on directories // so if a modify time was parsed from the listing we will try // to convert it to a DateTime object and use it for directories. //// if ((!capabilities.Contains(FtpCapability.MDTM) || item.Type == FtpFileSystemObjectType.Directory) && m.Groups["modify"].Value.Length > 0) { item.Modified = m.Groups["modify"].Value.GetFtpDate(DateTimeStyles.AssumeLocal); if (item.Modified == DateTime.MinValue) { client.LogStatus(FtpTraceLevel.Warn, "GetFtpDate() failed on " + m.Groups["modify"].Value); } } else { if (m.Groups["modify"].Value.Length == 0) { client.LogStatus(FtpTraceLevel.Warn, "RegEx failed to parse modified date from " + record); } else if (item.Type == FtpFileSystemObjectType.Directory) { client.LogStatus(FtpTraceLevel.Warn, "Modified times of directories are ignored in UNIX long listings."); } else if (capabilities.Contains(FtpCapability.MDTM)) { client.LogStatus(FtpTraceLevel.Warn, "Ignoring modified date because MDTM feature is present. If you aren't already, pass FtpListOption.Modify or FtpListOption.SizeModify to GetListing() to retrieve the modification time."); } } if (m.Groups["size"].Value.Length > 0) { long size; if (long.TryParse(m.Groups["size"].Value, out size)) { item.Size = size; } } if (m.Groups["permissions"].Value.Length > 0) { item.CalculateUnixPermissions(m.Groups["permissions"].Value); } return(item); }
private async Task <List <IUpdateItem> > ProcessDirectory(FtpListItem remoteDir, DirectoryInfo localDir, bool recursive, bool removeNotExisting, Func <FtpListItem, FileInfo, bool> versionEqualsComparer, CancellationToken cancellationToken) { if (remoteDir.Type != FtpFileSystemObjectType.Directory) { throw new DirectoryNotFoundException(); } var results = new List <IUpdateItem>(); var localContents = new List <FileSystemInfo>(); if (localDir.Exists) { localContents.AddRange(localDir.GetFileSystemInfos("*", SearchOption.TopDirectoryOnly)); } foreach (var remoteItem in GetSubNodes(remoteDir)) { cancellationToken.ThrowIfCancellationRequested(); if (remoteItem.Type == FtpFileSystemObjectType.Directory) { if (recursive) { var localItem = localContents.OfType <DirectoryInfo>().FirstOrDefault(x => string.Equals(x.Name, remoteItem.Name, StringComparison.OrdinalIgnoreCase)); if (localItem == null) { localItem = new DirectoryInfo(Path.Combine(localDir.FullName, remoteItem.Name)); } else { localContents.Remove(localItem); } results.AddRange(await ProcessDirectory(remoteItem, localItem, recursive, removeNotExisting, versionEqualsComparer, cancellationToken)); } } else if (remoteItem.Type == FtpFileSystemObjectType.File) { var itemDate = GetDate(remoteItem); if (itemDate > _latestModifiedDate) { _latestModifiedDate = itemDate; } var localFile = localContents.OfType <FileInfo>().FirstOrDefault(x => string.Equals(x.Name, remoteItem.Name, StringComparison.OrdinalIgnoreCase)); if (localFile == null) { localFile = new FileInfo(Path.Combine(localDir.FullName, remoteItem.Name)); } else { localContents.Remove(localFile); } var localIsUpToDate = localFile.Exists && versionEqualsComparer(remoteItem, localFile); if (!localIsUpToDate) { results.Add(new FtpUpdateItem(remoteItem, this, localFile)); } } } cancellationToken.ThrowIfCancellationRequested(); // Remove all files that were not on the remote if (removeNotExisting) { results.AddRange(UpdateSourceManager.FileInfosToDeleteItems(localContents)); } return(results); }
/// <summary> /// Adds a custom file listing parser /// </summary> public static void AddCustomParser() { FtpListItem.AddParser(new FtpListItem.Parser(ParseUnixList)); }
/// <summary> /// Parses Vax/VMS format listings /// </summary> /// <param name="record">A line from the listing</param> /// <returns>FtpListItem if the item is able to be parsed</returns> public static FtpListItem Parse(FtpClient client, string record) { var values = record.SplitString(); // skip blank lines if (values.Length <= 0) { return(null); } // skip line which lists Directory if (values.Length >= 2 && values[0].Equals(HDirectoryMarker)) { return(null); } // skip line which lists Total if (values.Length > 0 && values[0].Equals(TotalMarker)) { return(null); } if (values.Length < MinFieldCount) { return(null); } // first field is name var name = values[0]; // make sure it is the name (ends with ';<INT>') var semiPos = name.LastIndexOf(';'); // check for ; if (semiPos <= 0) { client.LogStatus(FtpTraceLevel.Verbose, "File version number not found in name '" + name + "'"); return(null); } var nameNoVersion = name.Substring(0, semiPos); // check for version after ; var afterSemi = values[0].Substring(semiPos + 1); try { long.Parse(afterSemi); // didn't throw exception yet, must be number // we don't use it currently but we might in future } catch (FormatException) { // don't worry about version number } // test is dir var isDir = false; if (nameNoVersion.EndsWith(DirectoryMarker)) { isDir = true; name = nameNoVersion.Substring(0, nameNoVersion.Length - DirectoryMarker.Length); } if (!FtpListParser.VMSNameHasVersion && !isDir) { name = nameNoVersion; } // 2nd field is size USED/ALLOCATED format, or perhaps just USED var size = ParseFileSize(values[1]); // 3 & 4 fields are date time var lastModified = ParseDateTime(client, values[2], values[3]); // 5th field is [group,owner] string group = null; string owner = null; ParseGroupOwner(values, out group, out owner); // 6th field is permissions e.g. (RWED,RWED,RE,) var permissions = ParsePermissions(values); // create a new list item object with the parsed metadata var file = new FtpListItem(record, name, size, isDir, ref lastModified); file.RawGroup = group; file.RawOwner = owner; file.RawPermissions = permissions; return(file); }
/// <summary> /// Parses IBM z/OS format listings /// </summary> /// <param name="client">The FTP client</param> /// <param name="record">A line from the listing</param> /// <returns>FtpListItem if the item is able to be parsed</returns> public static FtpListItem Parse(FtpClient client, string record, string path) { // Skip title line - all modes have one. // Also set zOSListingRealm to remember the mode we are in // "total nnnn" if (record.Contains("total")) { client.zOSListingRealm = FtpZOSListRealm.Unix; return(null); } // "Volume Unit Referred Ext Used Recfm Lrecl BlkSz Dsorg Dsname" if (record.Contains("Volume Unit")) { client.zOSListingRealm = FtpZOSListRealm.Dataset; return(null); } // " Name VV.MM Created Changed Size Init Mod Id" if (record.Contains("Name VV.MM")) { // This is an opportunity to issue XDSS and get the LRECL, but how? FtpReply reply; string cwd; // Is caller using FtpListOption.NoPath and CWD to the right place? if (path.Length == 0) { cwd = client.GetWorkingDirectory(); } // Caller is not using FtpListOption.NoPath, so the path can be used // but needs modification depending on its ending. Remove the "(...)" else if (path.EndsWith(")'")) { cwd = path.Substring(0, path.IndexOf('(')) + "\'"; } else if (path.EndsWith(")")) { cwd = path.Substring(0, path.IndexOf('(')); } else { cwd = path; } if (!(reply = client.Execute("XDSS " + cwd)).Success) { throw new FtpCommandException(reply); } // SITE PDSTYPE=PDSE RECFM=FB BLKSIZE=16000 DIRECTORY=1 LRECL=80 PRIMARY=3 SECONDARY=110 TRACKS EATTR=SYSTEM string[] words = reply.Message.Split(' '); string[] val = words[5].Split('='); client.zOSListingLRECL = UInt16.Parse(val[1]); client.zOSListingRealm = FtpZOSListRealm.Member; return(null); } // "Name Size TTR Alias-of AC--------- Attributes--------- Amode Rmode" if (record.Contains("Name Size TTR")) { client.zOSListingRealm = FtpZOSListRealm.MemberU; return(null); } if (client.zOSListingRealm == FtpZOSListRealm.Unix) { // unix mode // //total 320 // return(FtpUnixParser.Parse(client, record)); } if (client.zOSListingRealm == FtpZOSListRealm.Dataset) { // PS/PO mode // //Volume Unit Referred Ext Used Recfm Lrecl BlkSz Dsorg Dsname //ANSYBG 3390 2020/01/03 1 15 VB 32756 32760 PS $.ADATA.XAA //ANSYBH 3390 2022/02/18 1+++++ VBS 32767 27966 PS $.BDATA.XBB // // Ignore title line AND also ignore "VSAM", "Not Mounted" and "Error determining attributes" if (record.Substring(51, 4).Trim() == "PO" || record.Substring(51, 4).Trim() == "PS") { string volume = record.Substring(0, 6); string unit = record.Substring(7, 4); string referred = record.Substring(14, 10).Trim(); string ext = record.Substring(25, 2).Trim(); string used = record.Substring(27, 5).Trim(); string recfm = record.Substring(34, 4).Trim(); string lrecl = record.Substring(39, 5).Trim(); string blksz = record.Substring(45, 5).Trim(); string dsorg = record.Substring(51, 4).Trim(); string dsname = record.Remove(0, 56).Trim().Split(' ')[0]; bool isDir = dsorg == "PO"; var lastModifiedStr = referred; if (lastModifiedStr != "**NONE**") { lastModifiedStr += " 00:00"; } var lastModified = ParseDateTime(client, lastModifiedStr); // If "+++++" we could assume maximum "normal" size of 65535 tracks. (3.46GB) // or preferably "large format sequential" of 16777215 tracks (885.38GB) // This is a huge over-estimation in all probability but it cannot be helped. var size = 16777216L * 56664L; if (used != "+++++") { size = long.Parse(used) * 56664L; // 3390 dev bytes per track } var file = new FtpListItem(record, dsname, size, isDir, ref lastModified); return(file); } return(null); } if (client.zOSListingRealm == FtpZOSListRealm.Member) { // Member mode // // Name VV.MM Created Changed Size Init Mod Id //$2CPF1 01.01 2001/10/18 2001/10/18 11:58 29 29 0 QFX3076 // string name = record.Substring(0, 8).Trim(); string changed = string.Empty; string records = "0"; // Member stats may be empty if (record.TrimEnd().Length > 8) { string vvmm = record.Substring(10, 5).Trim(); string created = record.Substring(17, 10).Trim(); changed = record.Substring(27, 16).Trim(); records = record.Substring(44, 5).Trim(); string init = record.Substring(50, 5).Trim(); string mod = record.Substring(56, 5).Trim(); string id = record.Substring(62, 6).Trim(); } bool isDir = false; var lastModifiedStr = changed; var lastModified = ParseDateTime(client, lastModifiedStr); var size = ushort.Parse(records) * client.zOSListingLRECL; var file = new FtpListItem(record, name, size, isDir, ref lastModified); return(file); } if (client.zOSListingRealm == FtpZOSListRealm.MemberU) { // Member Loadlib mode // // Name Size TTR Alias-of AC --------- Attributes --------- Amode Rmode //EAGKCPT 000058 000009 00 FO RN RU 31 ANY //EAGRTPRC 005F48 000011 EAGRTALT 00 FO RN RU 31 ANY // string name = record.Substring(0, 8).Trim(); string changed = string.Empty; string memsize = record.Substring(10, 6); string TTR = record.Substring(19, 6); string Alias = record.Substring(26, 8).Trim(); string Attributes = record.Substring(38, 30); string Amode = record.Substring(70, 2); string Rmode = record.Substring(76, 3); bool isDir = false; var lastModifiedStr = changed; var lastModified = ParseDateTime(client, lastModifiedStr); var size = int.Parse(memsize, System.Globalization.NumberStyles.HexNumber); var file = new FtpListItem(record, name, size, isDir, ref lastModified); return(file); } return(null); }
private void _ftpAddFileFromPath(FtpClient client, string rootPath, string localPath, FtpListItem item) { string newPath = localPath + '/' + item.Name; if (item.Type == FtpFileSystemObjectType.Movie || item.Type == FtpFileSystemObjectType.File) { IMedia newmedia = AddFile(_folder + newPath, item.Modified == default(DateTime) ? item.Created : item.Modified); if (item.Type == FtpFileSystemObjectType.Movie) { newmedia.Duration = item.Size.SMPTEFramesToTimeSpan("50"); // assuming Grass Valley K2 PAL server newmedia.DurationPlay = newmedia.Duration; } } if (IsRecursive && item.Type == FtpFileSystemObjectType.Directory) { foreach (var file in client.GetListing(rootPath + newPath)) { _ftpAddFileFromPath(client, rootPath, newPath, file); } } }
public FtpFileBasicProperties(FtpListItem item) { DateModified = item.RawModified < DateTime.FromFileTimeUtc(0) ? DateTimeOffset.MinValue : item.RawModified; ItemDate = item.RawCreated < DateTime.FromFileTimeUtc(0) ? DateTimeOffset.MinValue : item.RawCreated; Size = (ulong)item.Size; }
/// <summary> /// Get the full path of a given FTP Listing entry /// </summary> public static void CalculateFullFtpPath(this FtpListItem item, FtpClient client, string path) { // EXIT IF NO DIR PATH PROVIDED if (path == null) { // check if the path is absolute if (IsAbsolutePath(item.Name)) { item.FullName = item.Name; item.Name = item.Name.GetFtpFileName(); } return; } // ONLY IF DIR PATH PROVIDED if (client.ServerType == FtpServer.IBMzOSFTP && client.zOSListingRealm != FtpZOSListRealm.Unix) { // The user might be using GetListing("", FtpListOption.NoPath) // or he might be using GetListing("not_fully_qualified_zOS path") // or he might be using GetListing("'fully_qualified_zOS path'") (note the single quotes) // The following examples in the comments assume a current working // directory of 'GEEK.'. // If it is not a FtpZOSListRealm.Dataset, it must be FtpZOSListRealm.Member* // Is caller using FtpListOption.NoPath and CWD to the right place? if (path.Length == 0) { if (client.zOSListingRealm == FtpZOSListRealm.Dataset) { // Path: "" // Fullname: 'GEEK.PROJECTS.LOADLIB' item.FullName = client.GetWorkingDirectory().TrimEnd('\'') + item.Name + "\'"; } else { // Path: "" // Fullname: 'GEEK.PROJECTS.LOADLIB(MYPROG)' item.FullName = client.GetWorkingDirectory().TrimEnd('\'') + "(" + item.Name + ")\'"; } } // Caller is not using FtpListOption.NoPath, so the fullname can be built // depending on the listing realm else if (path[0] == '\'') { if (client.zOSListingRealm == FtpZOSListRealm.Dataset) { // Path: "'GEEK.PROJECTS.LOADLIB'" // Fullname: 'GEEK.PROJECTS.LOADLIB' item.FullName = item.Name; } else { // Path: "'GEEK.PROJECTS.LOADLIB(*)'" // Fullname: 'GEEK.PROJECTS.LOADLIB(MYPROG)' item.FullName = path.Substring(0, path.Length - 4) + "(" + item.Name + ")\'"; } } else { if (client.zOSListingRealm == FtpZOSListRealm.Dataset) { // Path: "PROJECTS.LOADLIB" // Fullname: 'GEEK.PROJECTS.LOADLIB' item.FullName = client.GetWorkingDirectory().TrimEnd('\'') + item.Name + '\''; } else { // Path: "PROJECTS.LOADLIB(*)" // Fullname: 'GEEK.PROJECTS.LOADLIB(MYPROG)' item.FullName = client.GetWorkingDirectory().TrimEnd('\'') + path.Substring(0, path.Length - 3) + "(" + item.Name + ")\'"; } } return; } else if (client.ServerType == FtpServer.OpenVMS && client.ServerOS == FtpOperatingSystem.VMS) { // if this is a vax/openvms file listing // there are no slashes in the path name item.FullName = path + item.Name; } else { //this.client.LogStatus(item.Name); // remove globbing/wildcard from path if (path.GetFtpFileName().Contains("*")) { path = path.GetFtpDirectoryName(); } if (path.Length == 0) { path = client.GetWorkingDirectory(); } if (item.Name != null) { // absolute path? then ignore the path input to this method. if (IsAbsolutePath(item.Name)) { item.FullName = item.Name; item.Name = item.Name.GetFtpFileName(); } else if (path != null) { item.FullName = path.GetFtpPath(item.Name); //.GetFtpPathWithoutGlob(); } else { client.LogStatus(FtpTraceLevel.Warn, "Couldn't determine the full path of this object: " + Environment.NewLine + item.ToString()); } } // if a link target is set and it doesn't include an absolute path // then try to resolve it. if (item.LinkTarget != null && !item.LinkTarget.StartsWith("/")) { if (item.LinkTarget.StartsWith("./")) { item.LinkTarget = path.GetFtpPath(item.LinkTarget.Remove(0, 2)).Trim(); } else { item.LinkTarget = path.GetFtpPath(item.LinkTarget).Trim(); } } } }