Logo Search packages:      
Sourcecode: wcd version File versions  Download package

wcddir.c

/*
   filename: wcddir.c

   WCD - Chdir for Dos and Unix.

Author: Erwin Waterlander

======================================================================
= Copyright                                                          =
======================================================================
Copyright (C) 2002-2003 Erwin Waterlander

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

=======================================================================
*/

/* set tabstop=3 */

/* This file contains wrapper functions that operate on directories.
      These are needed to use the WIN32 API functions. WIN32 API functions
      are needed to get support for UNC paths.
*/

#if !(defined(MSDOS) && defined(__LCC__))
#  include <sys/types.h>
#  include <dirent.h>
#endif
#if defined(UNIX) || defined(DJGPP)
# include <unistd.h>
#endif
#include "dosdir.h"

#if (defined(WIN32) && !defined(__CYGWIN__))

/* WIN32, but not CYGWIN.
 * Use WIN32 API. */
#include "std_macro.h"
#include "structures.h"
#include "Text.h"
#include "nameset.h"
#include "wfixpath.h"
#include "dosdir.h"
#include <string.h>
#include <windows.h>

/* Make use of the Windows APIs so we can support UNC paths. */


/* 
      int wcd_isServerPath (char* path) 
      check if path is a possible UNC server path
      like \\servername
   RETURNS  1 if true
   RETURNS  0 if false
 */
int wcd_isServerPath (char* path)
{
      if ((strlen(path) > 2) && (wcd_is_slash(*path)) && (wcd_is_slash(*(path+1))) &&
             (strchr(path+2,'/') == NULL) && (strchr(path+2,'\\') == NULL))
            return(1);
      else
            return(0);
}

void exterr( void )
{
      /* This function was taken from Felix Kasza's Win32 Samples page
            at MVPS.ORG.  http://www.mvps.org/win32/
            */
      char errbuf[2048], namebuf[2048];
      DWORD err;

      errbuf[0] = namebuf[0] = '\0';
      if ( WNetGetLastError( &err, errbuf, sizeof errbuf, namebuf, sizeof namebuf ) == NO_ERROR )
            printf( "Wcd: Error %lu (\"%s\") reported by \"%s\".\n",
                  err, errbuf, namebuf );
      return;
}

#define MAX_NR_BUF 1000

int doEnum( int level, NETRESOURCE *pnr, nameset n )
{
      /* This function was taken from Felix Kasza's Win32 Samples page
            at MVPS.ORG.  http://www.mvps.org/win32/
            */
      DWORD rc, rc2;
      HANDLE hEnum;
      DWORD count, bufsize, ui;
      NETRESOURCE buf[MAX_NR_BUF];
      const char *type;
      char path[DD_MAXDIR];

      rc = WNetOpenEnum( RESOURCE_GLOBALNET, RESOURCETYPE_DISK, 0, pnr, &hEnum );
      if ( rc == ERROR_ACCESS_DENIED )
      {
            /* printf( "%-6.6s %-4.4s%*s  Error 5 -- access denied\n", "", "", level * 2, "" ); */
            printf( "Wcd: access denied.\n");
            return 1;
      }

      if ( rc )
      {
      rc2 = GetLastError();
            /* printf( "WNOE(): rc = %lu, gle = %lu\n", rc, rc2 ); */
            if ( rc2 == ERROR_EXTENDED_ERROR )
                  exterr();
            return 0;
      }

      while ( 1 )
      {
            count = (DWORD) -1L;
            bufsize = sizeof buf;
            rc = WNetEnumResource( hEnum, &count, buf, &bufsize );
            if ( rc != NO_ERROR )
                  break;
            for ( ui = 0; (ui < count); ++ ui )
            {
                  switch ( buf[ui].dwDisplayType )
                  {
                        case RESOURCEDISPLAYTYPE_DOMAIN:
                              type = "domain"; break;
                        case RESOURCEDISPLAYTYPE_GENERIC:
                              type = "generic"; break;
                        case RESOURCEDISPLAYTYPE_SERVER:
                              type = "server"; break;
                        case RESOURCEDISPLAYTYPE_SHARE:
                              type = "share"; 
                        printf( "Wcd: %s\n", buf[ui].lpRemoteName );
                              strncpy(path, buf[ui].lpRemoteName, DD_MAXDIR);
                              wcd_fixpath(path, DD_MAXDIR);
               addToNamesetArray(textNew(path), n);
                              break;
                        default:
                              type = "unknown"; break;
                  }
                  // now we recurse if it's a container
                  if ( buf[ui].dwUsage & RESOURCEUSAGE_CONTAINER )
                        doEnum( level + 1, &buf[ui], n );
            }
      }

      if ( rc != ERROR_NO_MORE_ITEMS )  // bad things
      {
      rc2 = GetLastError();
            /* printf( "WNER(): rc = %lu, gle = %lu\n", rc, rc2 ); */
            if ( rc2 == ERROR_EXTENDED_ERROR )
                  exterr();
      }

      WNetCloseEnum( hEnum );
      return 1;
}


/*************************************************************
  *
  *  wcd_getshares(char *path, nameset n)
  *
  *  In case path points to a server this function will
  *  search for shared directories on that server and add
  *  the shared directory names to n.
  *************************************************************/
void wcd_getshares(char* path, nameset n)
{
      NETRESOURCE  nr;

      if ((path == NULL) || (n == NULL))
            return;
      
      if (wcd_isServerPath(path))
      {
            /* an UNC path, possibly pointing to a server */
            /* WIN32 API needs backslashes. */
            *path = '\\';
            *(path+1) = '\\';

            printf("Wcd: Searching for shared directories on server %s\n", path);
            
            nr.dwScope       = RESOURCE_GLOBALNET;
            nr.dwType        = RESOURCETYPE_ANY;
            nr.dwDisplayType = RESOURCEDISPLAYTYPE_SERVER;
            nr.dwUsage       = RESOURCEUSAGE_CONTAINER;
            nr.lpLocalName   = NULL;
            nr.lpRemoteName  = path ;
            nr.lpProvider    = NULL;
            
            doEnum( 0, &nr, n );
      }
      printf("Wcd: Found %d shared directories on server %s\n", getSizeOfNamesetArray(n), path);
}

char *wcd_getcwd(char *buf, int size)
{
      BOOL err;

   err = GetCurrentDirectory(size, buf);

      if (err == 0)
            return(NULL);  /* fail */
      else
            return(buf);   /* success */
}

int wcd_chdir(char *buf)
{
      BOOL err;
      
      err = SetCurrentDirectory(buf); 

      if (err == 0)
            return(1);   /* fail */
      else
            return(0);   /* success */
}

int wcd_mkdir(char *buf)
{
      BOOL err;

      err = CreateDirectory(buf, NULL);

      if (err == TRUE)
            return(0);  /* success */
      else
            return(1);  /* fail */
}

int wcd_rmdir(char *buf)
{
      BOOL err;

      err = RemoveDirectory(buf);

      if (err == TRUE)
            return(0);  /* success */
      else
            return(1);  /* fail */
}


#else   /************************************************************/

  /*  Use POSIX API  */

#if defined(UNIX) || defined(DJGPP)

int wcd_mkdir(char *buf, mode_t m)
{
      return(mkdir(buf, m));
}

#else

int wcd_mkdir(char *buf)
{
      return(mkdir(buf));
}

#endif

char *wcd_getcwd(char *buf, int size)
{
   return(getcwd(buf, size));
}

int wcd_chdir(char *buf)
{
      return(chdir(buf)); 
}

int wcd_rmdir(char *buf)
{
      return(rmdir(buf)); 
}


#endif

/******************************************************************
 *
 * int wcd_isdir(char *dir)
 *
 * test if *dir points to a directory.
 *
 * returns 0 on success, -1 when it fails.
 *
 * This function was introduced for portability:
 *
 * - The following method using POSIX API fails on UNC paths
 *   on a MS-Windows system (at least with MinGW 1.1).
 *
 *                stat(path, &buf) ;
 *                if (S_ISDIR(buf.st_mode)) { ... }
 *
 * - The function 'opendir()' works on all systems, 
 *   also on Windows UNC paths.
 * - LCC 3.7 for windows does not have <dirent.h> with function
 *   'opendir()' to test for a directory
 ******************************************************************/
int wcd_isdir(char *dir)
{
#if (defined(MSDOS) && defined(__LCC__))
      /* LCC windows compiler */
      char tmp[DD_MAXDIR];

      wcd_getcwd(tmp, sizeof(tmp)); /* remember current dir */

   if (wcd_chdir(dir) == 0) /* just try to change to dir */
   {
     wcd_chdir(tmp); /* go back */
     return(0);
   }
   else
      return(-1);
#else

      DIR* dirp; /* GJM */

      if((dirp=opendir(dir)) != NULL)
      {
            closedir(dirp); /* GJM */
      return(0);
      }
   else
      return(-1);

#endif
}




Generated by  Doxygen 1.6.0   Back to index