/// <summary> /// Dereference a FtpListItem object /// </summary> /// <param name="item">The item to dereference</param> /// <param name="recMax">Maximum recursive calls</param> /// <param name="count">Counter</param> /// <param name="token">The token that can be used to cancel the entire process</param> /// <returns>FtpListItem, null if the link can't be dereferenced</returns> private async Task <FtpListItem> DereferenceLinkAsync(FtpListItem item, int recMax, IntRef count, CancellationToken token = default(CancellationToken)) { if (item.Type != FtpFileSystemObjectType.Link) { throw new FtpException("You can only dereference a symbolic link. Please verify the item type is Link."); } if (item.LinkTarget == null) { throw new FtpException("The link target was null. Please check this before trying to dereference the link."); } var listing = await GetListingAsync(item.LinkTarget.GetFtpDirectoryName(), token); foreach (FtpListItem obj in listing) { if (item.LinkTarget == obj.FullName) { if (obj.Type == FtpFileSystemObjectType.Link) { if (++count.Value == recMax) { return(null); } return(await DereferenceLinkAsync(obj, recMax, count, token)); } if (HasFeature(FtpCapability.MDTM)) { var modify = GetModifiedTime(obj.FullName); if (modify != DateTime.MinValue) { obj.Modified = modify; } } if (obj.Type == FtpFileSystemObjectType.File && obj.Size < 0 && HasFeature(FtpCapability.SIZE)) { obj.Size = GetFileSize(obj.FullName); } return(obj); } } return(null); }