Indy Homepage

Indy.Sockets (VCL) 

Web Designer Wanted!

   Articles   |  Download   |   F.A.Q.   |   Support   |   Teams   
    Indy Project  »  Indy (VCL)  »  Indy Core Blogs  »  J. Peter Mugaas's Indy Blog
 

About

Bug List

Indy Core
Team Blogs

Knowledge
Base

License 

Website problems?
Contact webmaster.
 

Website


Our builds are

Version control by

Docs made with

 

Fix for WIndows NT FTP Service Directory List parser

Fix for WIndows NT FTP Service Directory List parser

THis is a fix for a parsing problem with file sizes that are greater than 9 digits.

Earlier this morning, Jeff Easton, has posted about a problem with the Windows NT IIS FTP Service list parser class. The parser could not detect that it could handle a file size greater than 9 digits. I confirmed the bug myself and I checked in a fix for it. The fix is a minor reworking for the parser detection routine to be more liberal about numbers in specific string positions.

At the same time, I changed things so the parser would be less tolorant of spaces to the right side of a number. I did that because FTP list parsing is always a mess since there are many formats and if I'm not careful, I can easily do a fix that introduces other problems.

If you are interested, just replace the TIdFTPLPWindowsNT.CheckListing class procedure in the IdFTPListParseWindowsNT unit with this one:

class function TIdFTPLPWindowsNT.CheckListing(AListing: TIdStrings;
  const ASysDescript: String; const ADetails: Boolean): boolean;
var SDir, sSize : String;
  i : Integer;
  SData : String;
begin

  //maybe, we are dealing with this pattern
  //2002-09-02  18:48       <DIR>          DOS dir 2
  //
  //or
  //2002-09-02  19:06                9,730 DOS file 2
  //
  //Those were obtained from soem comments in some FileZilla source-code.
  //FtpListResult.cpp
  //Note that none of that GNU source-code was used.
  //
  //I personally came accross the following when on Microsoft IIS
  //FTP Service on WIndowsXP Pro when I enabled the "FtpDirBrowseShowLongDate"
  //metadata property.
  //
  //02-16-2005  04:16AM       <DIR>          pub

  Result := False;
  for i := 0 to AListing.Count - 1 do
  begin
    if (AListing[i]<>'') and
      (IsSubDirContentsBanner(AListing[i])=False) then
    begin
      SData := Sys.UpperCase(AListing[i]);
      sDir := Copy(SData, 25, 5);
      //maybe this is two spacs off.  We don't use TrimLeft at this point
      //because we can't assume that this is a valid WIndows FTP Service listing.

      if sDir = '  <DI' then    {do not localize}
      begin
        sDir := Copy(SData, 27, 5);
      end;
      sDir := Sys.TrimLeft(sDir);
      //This is a workaround for large file sizes such as:

      //09-08-05  10:22AM            628551680 Test.txt
      //09-08-05  10:23AM            628623360 Test2.txt

      if IsNumeric(Sys.TrimLeft(sDir)) then
      begin
        sDir := '';
      end;
      sSize := Sys.StringReplace(Sys.TrimLeft(Copy(SData, 20, 19)), ',', '');    {Do not Localize}
      //VM/BFS does share the date/time format as MS-DOS for the first two columns
  //    if ((CharIsInSet(SData, 3, ['/', '-'])) and (CharIsInSet(SData, 6, ['/', '-']))) then
      if IsMMDDYY(Copy(SData,1,8),'-') or IsMMDDYY(Copy(SData,1,8),'/') then
      begin
        if (sDir = '<DIR>') then  {do not localize}
        begin
          Result := IsVMBFS(SData)=False;
        end
        else
        begin
          //may be a file - see if we can get the size if sDir is empty
          if ((sDir = '') and    {Do not Localize}
            (Sys.StrToInt64(sSize, -1) <> -1)) then
          begin
            Result := IsVMBFS(SData)=False;
          end;
        end;
      end
      else
      begin

        if IsYYYYMMDD(SData) then
        begin
          if (sDir = '<DIR>') then  {do not localize}
          begin
            Result := IsVMBFS(SData)=False;
          end
          else
          begin
            //may be a file - see if we can get the size if sDir is empty
            if ((sDir = '') and    {Do not Localize}
              (Sys.StrToInt64(sSize, -1) <> -1)) then
            begin
              Result := IsVMBFS(SData)=False;
            end;
          end;
        end
        else
        begin
          if IsMMDDYY(SData,'-') then
          begin
          {
It might be like this:
02-16-2005  04:16AM       <DIR>          pub
02-14-2005  07:22AM              9112103 ethereal-setup-0.10.9.exe

          }
            if (sDir = '<DIR>') then  {do not localize}
            begin
              Result := IsVMBFS(SData)=False;
            end
            else
            begin
              if ((sDir = '') and    {Do not Localize}
               (Sys.StrToInt64(sSize, -1) <> -1)) then
              begin
                Result := IsVMBFS(SData)=False;
              end;
            end;
          end;
        end;
      end;
    end;
  end;
end;

It goes without saying that the ultimate fix to these parsing problems is if all servers and clients support the MLSD/MLST commands.

 << Previous Entry     Next Entry >>

Corporate Sponsors
[Image] [Image]

 

Copyright © 1993 - 2008
Chad Z. Hower (Kudzu)
and the Indy Pit Crew.

Using Indy in your software?
  
Click on the image for more
Indy logos and graphics.