Lazarus

Programming => General => Topic started by: glubbish on June 13, 2018, 05:03:34 am

Title: [SOLVED] issues traversing directory tree
Post by: glubbish on June 13, 2018, 05:03:34 am
Have a program that backs up selected directories.

The issue is that I have a file that starts with a single quote '48 (its an ebook so dont really want to rename it to get around this problem)
When using findfirst it usually gets . and .. first, but in this case it gets '48

So:
Code: Pascal  [Select]
  1.  Result := FindFirst(SourcePrefix+'\'+RootDir + '\*.*', FaAnyFile, sr);
  2.   if Result <> 0 then
  3.   begin
  4.     SysUtils.findclose(sr);
  5.     ShowMessage('CopyUpdate: ' + SysUtils.SysErrorMessage(SysUtils.GetLastOSError) + ' ' + RootDir);
  6.     Halt;
  7.     exit;
  8.   end;
  9.   findnext(sr);  {skip . and ..}
  10.   while findnext(sr) = 0 do...

ends up having .. and recursively goes to infinity.

Where:
Code: Pascal  [Select]
  1.   if  FindFirst(RootDir + '*.*', FaAnyFile, sr) = 0 then
  2.   begin
  3.     repeat
  4.     if sr.Name = '.' then findnext(sr);
  5.     if sr.Name = '..' then findnext(sr);
  6.     ...

Works fine for '48 but fails where there is an empty directory somewhere in the tree (recursively off to infinity again).

Is there a way to account for both?

Thanks Derek

Title: Re: issues traversing directory tree
Post by: marcov on June 13, 2018, 01:16:45 pm
use Fanyfile-fadirectory in findfirst.
Title: Re: issues traversing directory tree
Post by: Bart on June 13, 2018, 03:43:42 pm
Or simply do nothing if you find '.' or '..'
Code: Pascal  [Select]
  1.   if  FindFirst(RootDir + '*.*', FaAnyFile, sr) = 0 then
  2.   begin
  3.     repeat
  4.       if not ((SR.Name='.') or (SR.Name='..')) then
  5.       begin
  6.         ...
  7.      end;
  8.    until FindNext(SR) <> 0;
  9.   end;
  10.  

Bart
Title: Re: issues traversing directory tree
Post by: glubbish on June 13, 2018, 11:19:22 pm
marcov: I need the directories to traverse the tree.

Bart: Thanks for the idea. I did it this way:

Code: Pascal  [Select]
  1.   if (((sr.attr and fadirectory) > 0) and (sr.name <> '.') and (sr.name <> '..')) then CopyUpdate(RootDir + sr.FindData.cFileName+'/');
  2.   if ((sr.attr and fadirectory)) = 0 then
  3.     begin ...

With thousands of files and the error showing as {dirname}/../../../../../../../../ etc then another file name (not '48) it took quite a while to find the problem.
Adding the check for . and .. directories before recursing fixed this issue.

Thanks Derek