'===========================================================================
' Subject: LIST ALL FILES ON DRIVE            Date: 04-06-99 (16:06)       
'  Author: Donald R. Darden                   Code: PB                     
'  Origin: oldefoxx@earthlink.net           Packet: PB.ABC
'===========================================================================
$if 0
LIST ALL FILES - a program to list ALL the files on a single drive.
by Donald R. Darden, April 1999.

This is a FREEWARE PowerBASIC Snippet.

The program is easily modifiable, for instance you can replace the "C:\"
with any drive letter, possibly as part of a FOR loop:

           FOR drive=asc("C") to asc("Z")
             a$=chr$(drive)+":\"
             if dir$(a$+"*.*",23)="" then iterate for
             ydir$(1)=zz$+a$
             ...
           NEXT

Additionally, you can search for specific files by conditioning the ?a$b$
line like so:
               ...
               if instr(b$,".BAK") then ?a$b$

Or instead of ?a$b$, you could use:

               ...
               if instr(b$,".BAK") then kill a$b$

(Be careful whenever you attempt to automate any KILL process, as you
might inadvertantly delete needed files!  Best test your code with the PRINT
command first)

Ahother alternative might be to write the output to another file to use
for other processes later, such as:

               Open "filename.lst" for output as #2

or if you want to add to an existing file:

               Open "filename.lst: for append as #2

then when you find the right file(s):

               if instr(b$,".LOG") then ?a$b$:?#2a$b$

Note that the current DIM statement assumes that you only have a maximum
of 1,000 total directories\subdirectories on the drive.  When doing
multiple drives, you must include an ERASE command to clear the ydir$()
array before going to the next drive.  If 1,000 is too small a number, you
can make it larger.  Each ydir$() entry consists of a 2-byte MKI$(index)+
"<NAME>", where the index points to the next higher entry in the tree and
the <NAME> is assigned to the current directory.  This makes for a simple
program with limited storage required to track the tree, as files are not
added to it.  Attempting to open a directory as a file produces the Error
75 code, which makes it easy to determine if a file or directory was
returned by the DIR$ command.  The DIR$ attribute of 23 ensures that all
files and directories are returned, but not the volume label.

If you are first searching for a directory, then want to work with all the
files in that particular directory, you can either (1) DIM another array
to track the file names, as was done directories by ydir$(),  (2) Erase
ydir$() and reuse it (or create another array), keeping only the directory
reference (a$ here), or (3) Pack the filenames into a string as was done
with c$, as a temporary means of storing the filenames without requiring
an array. (Notice the use of the nul character (0) to separate one file
name from the next. You could use any character that is not considered
valid in a file name, such as slash (/), backslash (\), asterick (*),
question mark (?), or semi-colon (;).  Actually, a chr$(0) COULD appear
in a filename, but I never resort to non-printable characters for a file
or directory name, so in my case the chr$(0) is a good separator).

This program does not directly support file attributes, date, or size, or
the use of long file names as allowed under Windows9x/NT.  However, you
should be able to extended this code to accomodate them as well.  Look at
DIRUNIT.BAS and DOSUNIT.BAS that comes with PowerBASIC as to what it takes
to work with file attributes, date, and size, then look for mention of
Long File Names (LFN) on the PowerBASIC PBXtra code disk (or elsewhere,
including the InterNet via a search engine such as www.snap.com,
www.lycos.com, www.hotbot.com, www.altavista.digital.com, or others).

What could you use this snippet for?  Aside from finding all *.BAK files
and erasing them, you might:

         o   Compare files by name, or size and date, then
             content, to determine if they are duplicates

         o   Look for all zero-length files, with the possibility
             of deleting them

         o   Create a Map of how your drive is layed out

         o   Create a cross-index of all files by extension (type)

         o   copy or move all files of a type (i.e., *.ZIP) into
             a designated directory on a designated drive

         o   Identify all system, hidden, and read-only files on
             your system

         o   Identify all system, hidden, and read-only directories

         o   search for specific files or file types

         o   use these tools to write your own file manager

         o   use these tools to write your own backup/restore program

$endif

$stack 8192
$compile exe

defint a-z
dim ydir(0 to 1000) as string
yidx=1
xidx=0
z$=chr$(0)
zz$=chr$(0,0)
color 15,1
cls
ydir$(1)=zz$+"C:\"
do while xidx<yidx
  incr xidx
  a$=ydir$(xidx)
  do
    a=cvi(a$)
    if a=0 then exit do
    a$=ydir$(a)+mid$(a$,3)
  loop
  a$=mid$(a$,3)
  b$=dir$(a$+"*.*",23)
  c$=""
  do while b$>""
    c$=c$+b$+z$
    b$=dir$
  loop
  do
    a=instr(c$,z$)
    if a=0 then exit do
    b$=left$(c$,a-1)
    c$=mid$(c$,a+1)
    bad=0
    on error goto override
    open a$+b$ for input as #1
    on error goto 0
    if bad=75 then
      incr yidx
      ydir$(yidx)=mki$(xidx)+b$+"\"
    elseif bad then
      stop
    else
      ?a$b$
    end if
    close 1
  loop
loop
?"Done!"
end

override:
bad=err
if bad=0 then bad=-1
resume next
