/***************************************************************************
 *                                                                         *
 *  FILEUTIL.CPP                                                           *
 *                                                                         *
 *  File search utilities                                                  *
 *                                                                         *
 *                                                  - Paul Roub  08/29/96  *
 *                                                                         *
 ***************************************************************************/

#include  "stdafx.h"
#include  "gcommlib.h"
#include  "fileutil.h"


static CString CurDir();
static BOOL FindExecutables( const CString &fn, const char *ext, BOOL hasPath,
                             CString &cmdPath, CString &cmdRoot, CString &cmdExt
                           );
static void SplitPath( const CString &fn, CString &path, CString &root, CString &ext );


const char *exts[] =               // valid command extensions
{
     ".exe", ".com", ".bat", ".cmd"
};

const int extCount = sizeof( exts ) / sizeof( exts[ 0 ] );


BOOL                               //   TRUE if the file exists
FileExists(                        // check for existence of a file (not a subdir)
const CString &fn)                 //   filename we're looking for
{
     Cffblk    fb;

     return( fnd1st( &fb, fn, 0 ) );
}


BOOL                               //   TRUE if the file exists
DirExists(                        // check for existence of a subdir
const CString &fn)                 //   filename we're looking for
{
     Cffblk    fb;

     if (fnd1st(&fb,fn,0x10)) {
          return((fb.ff_attrib&FAMDIR) != 0);
     }
     return(FALSE);
}


BOOL                               //   TRUE if an executable was found
which(                             // what program would run as the result of...
const CString &cmdLine,            //   cmdline -- the command we're checking
CString &cmdPath,                  //   the path of the executable (returned)
CString &cmdRoot,                  //   the root of the executable (returned)
CString &cmdExt)                   //   the extension of the executable (returned)
{
     CString   fn( cmdLine );      // command name part of cmdLine

     int       space = fn.Find( ' ' );

     if (space >= 0)
     {
          fn = fn.Left( space );
     }

     CString   path, root, ext;

     SplitPath( fn, path, root, ext );

     BOOL      hasPath = path.GetLength() > 0;
     BOOL      hasExt = ext.GetLength() > 0;
     BOOL      found = FALSE;

     if (hasExt)
     {
          found = FindExecutables( path + root, ext, hasPath, cmdPath, cmdRoot, cmdExt );
     }
     else
     {
          for ( int count = 0; count < extCount; ++count )
          {
               found = FindExecutables( path + root, exts[ count ], hasPath, cmdPath, cmdRoot, cmdExt );
               if (found)
               {
                    break;
               }
          }
     }

     return( found );

}


BOOL                               //   TRUE if an executable was found
ExecutableExists(                  // see if a given command is valid
const CString &fn)                 //   command we're checking (e.g. "WGSDRAW")
{
     CString   path, root, ext;

     return( which( fn, path, root, ext ) );
}


static BOOL                        //   TRUE if we found one
FindExecutables(                   // search for executables matching a command
const CString &fn,                 //   [path\\]root of the command name
const char *ext,                   //   extension of the command name
BOOL hasPath,                      //   true if "path\\" part is there
CString &cmdPath,                  //   the path of the executable (returned)
CString &cmdRoot,                  //   the root of the executable (returned)
CString &cmdExt)                   //   the extension of the executable (returned)
{
     BOOL      found = FALSE;

     if (hasPath)
     {
          cmdPath = CurDir();
          cmdRoot = fn;
          cmdExt = ext;
          found = FileExists( fn + ext );
     }
     else
     {
          LPTSTR fnPtr;
          char      fnBuf[ 1024 ];

          found = SearchPath( NULL,
                              fn,
                              ext,
                              sizeof( fnBuf ),
                              fnBuf,
                              &fnPtr
                            ) > 0;

          if (found)
          {
               SplitPath( fnBuf, cmdPath, cmdRoot, cmdExt );
          }
     }

     return( found );
}


static void
SplitPath(                         // get parts of a qualified file name
const CString &fn,                 //   the name we're parsing
CString &path,                     //   path of the file (returned)
CString &root,                     //   root name (returned)
CString &ext)                      //   extension (returned)
{
     int       sepPos = fn.ReverseFind( '\\' );

     if (sepPos < 0)
     {
          sepPos = fn.ReverseFind( '/' );
     }
     if (sepPos < 0)
     {
          sepPos = fn.ReverseFind( ':' );
     }

     if (sepPos >= 0)
     {
          path = fn.Left( sepPos + 1 );
          root = fn.Mid( sepPos + 1 );
     }
     else
     {
          path = "";
          root = fn;
     }

     int       dotPos = root.ReverseFind( '.' );

     if (dotPos >= 0)
     {
          ext = root.Mid( dotPos );
          root = root.Left( dotPos );
     }

     return;
}


static CString                     //   current directory
CurDir()                           // get current working dir
{
     char      dirbuf[ 2048 ];     // 16-bit?  what's that?

     GetCurrentDirectory( sizeof( dirbuf ), dirbuf );

     return( CString( (const char *)dirbuf ) );
}

