⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 idftplistparseunix.pas

📁 photo.163.com 相册下载器 多线程下载
💻 PAS
📖 第 1 页 / 共 2 页
字号:
    Result := Result + ' '+LB;
  end;

Begin
  LI := AItem as TIdUnixFTPListItem;
  // Get defaults for modified date/time
  ADate := Now;
  DecodeDate(ADate, wYear, wMonth, wDay);
  DecodeTime(ADate, wHour, wMin, wSec, wMSec);
  LData := AItem.Data;
  LStep := pusinode;
  while NOT (LStep = pusDone) do begin
    case LStep of
     pusinode: begin
        //we do it this way because the column for inode is right justified
        //and we don't want to create a problem if the -i parameter was never used

         LTmp := TrimLeft(LData);
         LTmp := Fetch(LTmp);
         if IsValidUnixPerms(LTmp) then
         begin
           LStep := pusPerm;
         end
         else
         begin
         //the inode column is right justified
           LData := TrimLeft(LData);
           LTmp := Fetch(LData);
           LData := TrimLeft(LData);
           LInode := LTmp;
           LStep := pusBlocks;
         end;
      end;
    pusBlocks: begin
    //Note that there is an ambigioutity because this value could
    //be the inode if only the -i switch was used.
         LTmp := Fetch(LData,' ',False);
         if IsValidUnixPerms(LTmp)=False then
         begin
           LTmp := Fetch(LData);
           LData := TrimLeft(LData);
           LBlocks := LTmp;
         end;
         LStep := pusPerm;
      end;
    pusPerm: begin//1.-rw-rw-rw-
      LTmp := Fetch(LData);
      LData := TrimLeft(LData);
      // Copy the predictable pieces
      LDir := UpperCase(Copy(LTmp, 1, 1));
      LOPerm := Copy(LTmp, 2, 3);
      LGPerm := Copy(LTmp, 5, 3);
      LUPerm := Copy(LTmp, 8, 3);
      LStep := pusCount;
    end;
    pusCount: begin
      LData := TrimLeft(LData);
      LTmp := Fetch(LData);
      LData := TrimLeft(LData);

      //Patch for NetPresenz
      // "-------r--         326  1391972  1392298 Nov 22  1995 MegaPhone.sit" */
      // "drwxrwxr-x               folder        2 May 10  1996 network" */
      if TextIsSame(LTmp, 'folder') then begin  {do not localize}
        LStep := pusSize;
   //     LStep := pusMonth;
      end
      //APR
      //Patch for overflow -r--r--r--   0526478   128  Dec 30 2002  DE292000
      else begin
        if (Length(LTmp) > 3) and (LTmp[1] = '0') then begin
          LData := Copy(LTmp, 2, MaxInt) + ' ' + LData;
          LCount := '0';
        end
        else begin
          LCount := LTmp;
        end;
        //this check is necessary if both the owner and group were surpressed.
        if IsGOSwitches(AItem.Data) then
        begin
          LStep := pusSize;
        end
        else
        begin
          LStep := pusOwner;
        end;
      end;
      LData := TrimLeft(LData);
    end;
    pusOwner: begin
      LTmp := Fetch(LData);
      LData := TrimLeft(LData);
      LOwner := LTmp;
(*    if (SL[4] > '') and    {Do not Localize}
     //Ericsson Switch FTP returns empty owner.
     (SL[4][1] in ['A'..'Z','a'..'z']) then begin    {Do not Localize}
      SL.Insert(2, '');    {Do not Localize}
    end; *)
      LStep := pusGroup;
    end;
    pusGroup: begin
      LTmp := Fetch(LData);
      LData := TrimLeft(LData);
      LGroup := LTmp;
      LStep := pusSize;
    end;
    pusSize: begin
      //Ericsson - Switch FTP returns empty owner
      //Do not apply Ericson patch to Unitree
      if (CharIsInSet(LData, 1, ['A'..'Z','a'..'z']))
       and (GetIdent <> UNITREE) then begin
        LSize := LGroup;
        LGroup := LOwner;
        LOwner := '';
        //we do this just after the erickson patch because
        //a few servers might return additional columns.
        //
        //e.g.
        //
        //drwx------  1          BUILTIN     NT AUTHORITY          0 Dec  7  2001 System Volume Information
        if (IsNumeric(LSize)=False) then
        begin
          //undo the Ericson patch
          LOwner := LGroup;
          LGroup := '';
          repeat
            LGroup := LGroup + ' '+LSize;
            LOwner := LGroup;
            LData := TrimLeft(LData);
            LSize := Fetch(LData);
          until (IsNumeric(LSize));
          //delete the initial space we had added in the repeat loop
          IdDelete(LGroup,1,1);
        end;
      end
      else begin
        LTmp := Fetch(LData);
        //This is necessary for cases where are char device is listed
        //e.g.
        //crw-rw-rw-   1 0        1         11, 42 Aug  8  2000 tcp
        //
        //Note sure what 11, 42 is so size is not returned.
        if IndyPos(',',LTmp)>0 then
        begin
          LData := TrimLeft(LData);
          Fetch(LData);
          LData := TrimLeft(LData);
          LSize := '';
        end
        else
        begin
          LSize := LTmp;
        end;
        LData := TrimLeft(LData);
        case PosInStrArray(LSize,UnitreeStoreTypes) of
          0 :  //AR - archived to tape - migrated
          begin
            if AItem is TIdUnitreeFTPListItem then
            begin
              (LI as TIdUnitreeFTPListItem).Migrated := True;
              (LI as TIdUnitreeFTPListItem).FileFamily := Fetch(LData);
            end;
            LData := TrimLeft(LData);
            LSize := Fetch(LData);
            LData := TrimLeft(LData);
          end;
          1 : //DK - disk
          begin
            if AItem is TIdUnitreeFTPListItem then
            begin
              (LI as TIdUnitreeFTPListItem).FileFamily := Fetch(LData);
            end;
            LData := TrimLeft(LData);
            LSize := Fetch(LData);
            LData := TrimLeft(LData);
          end;
        end;
      end;
      LStep := pusMonth;
    end;
    pusMonth: begin // Scan modified MMM
      //fix up a bonked date such as:
      //-rw-r--r--   1 root     other        531 09-26 13:45 README3
      LData := FixBonkedYear(LData);
        //we do this in case there's a space
      LTmp := Fetch(LData);
      if Length(LTmp)>3 then
      begin
        //must be a year
        wYear := StrToIntDef(LTmp,wYear);
        LTmp := Fetch(LData);
      end;
      LData := TrimLeft(LData);
      if IsNumeric(LTmp) then
      begin
        wMonth := StrToIntDef(LTmp,wMonth);
        if (wMonth>12) then
        begin
          wDay := wMonth;
          LTmp := Fetch(LData);
          LData := TrimLeft(LData);
          wMonth := StrToIntDef(LTmp,wMonth);
          LStep := pusYear;
        end
        else
        begin
          LStep := pusDay;
        end;
      end
      else
      begin
        wMonth := StrToMonth(LTmp);
        LStep := pusDay;
      end;
    end;
    pusDay: begin // Scan DD
      LTmp := Fetch(LData);
      LData := TrimLeft(LData);
      wDay := StrToIntDef(LTmp, wDay);
      LStep := pusYear;
    end;
    pusYear: begin
      LTmp := Fetch(LData);
      // Not time info, scan year
      if IndyPos(':', LTmp) = 0 then begin    {Do not Localize}
        wYear := StrToIntDef(LTmp, wYear);
        // Set time info to 00:00:00.999
        wHour := 0;
        wMin := 0;
        wSec := 0;
        wMSec := 999;
        LStep := pusName;
      end//if IndyPos(':', SL[7])=0    {Do not Localize}
      else begin // Time info, scan hour, min
        LStep := pusTime;
      end;
    end;
    pusTime: begin
      // correct year and Scan hour
      wYear := AddMissingYear(wDay,wMonth);
      wHour:= StrToIntDef(Fetch(LTmp,':'), 0);    {Do not Localize}
      // Set sec and ms to 0.999 except for Serv-U or FreeBSD with the -T parameter
      //with the -T parameter, Serve-U returns something like this:
      //
      //drwxrwxrwx   1 user     group           0 Mar  3 04:49:59 2003 upload
      //
      //instead of:
      //
      //drwxrwxrwx   1 user     group           0 Mar  3 04:49 upload
      if (IndyPos(':',LTmp)>0) and (IsNumeric(Fetch(LData,' ',False))) then
      begin
        // Scan minutes
        wMin := StrToIntDef(Fetch(LTmp,':'), 0);
        wSec := StrToIntDef(Fetch(LTmp,':'), 0);
        wMSec := StrToIntDef(Fetch(LTmp,':'),999);
        LTmp := Fetch(LData);
        wYear := StrToIntDef(LTmp, wYear);
      end
      else
      begin
      // Scan minutes
        wMin := StrToIntDef(Fetch(LTmp,':'), 0);
        wSec := StrToIntDef(Fetch(LTmp,':'), 0);
        wMSec := StrToIntDef(Fetch(LTmp),999);
      end;
      LStep := pusName;
    end;
    pusName: begin
      LName := LData;
      LStep := pusDone;
    end;
    end;//case LStep
  end;//while
    AItem.ItemType := ditFile;
    if LDir<>'' then
    begin
      case LDir[1] of
        'D' : AItem.ItemType := ditDirectory;  {Do not Localize}
        'L' : AItem.ItemType := ditSymbolicLink; {Do not Localize}
        'B' : AItem.ItemType := ditBlockDev; {Do not Localize}
        'C' : AItem.ItemType := ditCharDev; {Do not Localize}
        'P' : AItem.ItemType := ditFIFO;  {Do not Localize}
        'S' : AItem.ItemType := ditSocket;   {Do not Localize}
      end;
    end;
    LI.UnixOwnerPermissions := LOPerm;
    LI.UnixGroupPermissions := LGPerm;
    LI.UnixOtherPermissions := LUPerm;
    LI.LinkCount := StrToIntDef(LCount, 0);
    LI.OwnerName := LOwner;
    LI.GroupName := LGroup;
    LI.Size := StrToInt64Def(LSize, 0);
    LI.ModifiedDate := EncodeDate(wYear, wMonth, wDay) + EncodeTime(wHour, wMin, wSec, wMSec);

    if LI.ItemType = ditSymbolicLink then begin
      i := IndyPos(UNIX_LINKTO_SYM, LName);    {Do not Localize}
      LLinkTo := Copy(LName, i + 4, Length(LName) - i - 3);
      LName := Copy(LName, 1, i - 1);
      //with ls -F (DIR -F in FTP, you will sometimes symbolic links with the linked
      //to item file name ending with a /.  That indicates that the item being pointed to
      //is a directory
      if (LLinkTo <> '') and (LLinkTo[Length(LLinkTo)]=PATH_FILENAME_SEP_UNIX) then
      begin
        LI.ItemType := ditSymbolicLinkDir;
        LLinkTo := Copy(LLinkTo,1,Length(LLinkTo)-1);
      end;
      LI.LinkedItemName := LLinkTo;
    end;
    LI.NumberBlocks := StrToIntDef(LBlocks,0);
    LI.Inode := StrToIntDef(linode,0);
    //with servers using ls -F, / is returned after the name of dir names and a *
    //will be returned at the end of a file name for an executable program.
    //Based on info at http://www.skypoint.com/help/tipgettingaround.html
    //Note that many FTP servers obtain their DIR lists by piping output from the /bin/ls -l command.
    //The -F parameter does work with ftp.netscape.com and I have also tested a NcFTP server
    //which simulates the output of the ls command.
    if (CharIsInSet(LName, Length(LName), [PATH_FILENAME_SEP_UNIX,'*'])) then
    begin
      LName := Copy(LName,1,Length(LName)-1);
    end;

  if APath<>'' then
  begin
  // a path can sometimes come into the form of:
  //  pub:
  // or
  //  ./pub
  //
  //Deal with both cases
    LI.LocalFileName := LName;
    LName := APath + PATH_FILENAME_SEP_UNIX + LName;
    if Copy(LName,1,Length(UNIX_CURDIR))=UNIX_CURDIR then
    begin
      IdDelete(LName,1,Length(PATH_FILENAME_SEP_UNIX));
      if Copy(LName,1,Length(PATH_FILENAME_SEP_UNIX))=PATH_FILENAME_SEP_UNIX then
      begin
        IdDelete(LName,1,Length(PATH_FILENAME_SEP_UNIX));
      end;
    end;
  end;
  LI.FileName := LName;
  Result := True;
end;

class function TIdFTPLPUnix.ParseListing(AListing: TIdStrings;
  ADir: TIdFTPListItems): boolean;
var i : Integer;
  LPathSpec : String;
  LItem : TIdFTPListItem;
begin
  for i := 0 to AListing.Count -1 do
  begin
    if (AListing[i] ='') or IsTotalLine(AListing[i]) or IsUnixLsErr(AListing[i])
    or (IsUnitreeBanner(AListing[i])) then
    begin
    end
    else
    begin
       //workaround for the XBox MediaCenter FTP Server
      //which returns something like this:
      //
      //dr-xr-xr-x    1 ftp      ftp            1 Feb 23 00:00 D:
      //and the trailing : is falsely assuming that a ":" means
      //a subdirectory entry in a recursive list.
      if (not InternelChkUnix(AListing[i])) and IsSubDirContentsBanner(AListing[i]) then
      begin
        LPathSpec := Copy(AListing[i],1,Length(AListing[i])-1);
      end
      else
      begin
        LItem := MakeNewItem(ADir);
        LItem.Data := AListing[i];
        ParseLine(LItem, LPathSpec);
      end;
    end;
  end;
  Result := True;
end;

{ TIdFTPLPUnitree }

class function TIdFTPLPUnitree.GetIdent: String;
begin
  Result := UNITREE;
end;

class function TIdFTPLPUnitree.MakeNewItem(
  AOwner: TIdFTPListItems): TIdFTPListItem;
begin
  Result := TIdUnitreeFTPListItem.Create(AOwner);
end;

initialization
  RegisterFTPListParser(TIdFTPLPUnix);
  RegisterFTPListParser(TIdFTPLPUnitree);
finalization
  UnRegisterFTPListParser(TIdFTPLPUnix);
  UnRegisterFTPListParser(TIdFTPLPUnitree);
end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -