Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

334 lines
7.1 KiB

#include <cache.hxx>
#include <conmgr.hxx>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
extern int errno;
/* Code swiped from cachecfg.cxx */
static BOOL _NormalisePath(LPCTSTR pszPath, LPCTSTR pszEnvVar,
LPTSTR pszResult, UINT cbResult)
{
TCHAR szEnvVar[MAX_PATH];
// don't count the NULL
ExpandEnvironmentStrings(pszEnvVar, szEnvVar, sizeof(szEnvVar)-1);
DWORD dwEnvVar = lstrlen(szEnvVar);
if (CompareString(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, szEnvVar,
dwEnvVar, pszPath, dwEnvVar) == 2)
{
if (lstrlen(pszPath) + dwEnvVar < cbResult)
{
strncpy(pszResult, pszEnvVar, MAX_PATH);
strncat(pszResult, pszPath + dwEnvVar, MAX_PATH);
return TRUE;
}
}
return FALSE;
}
void UnixNormalisePath(LPTSTR pszOrigPath, LPCTSTR pszEnvVar)
{
TCHAR szScratch[MAX_PATH];
if (_NormalisePath(pszOrigPath,pszEnvVar,szScratch,sizeof(szScratch)))
strncpy(pszOrigPath,szScratch,MAX_PATH);
}
void UnixNormaliseIfCachePath(LPTSTR pszOrigPath, LPCTSTR pszEnvVar,
LPCTSTR pszKeyName)
{
if (!strncmp(pszKeyName,CACHE_PATH_VALUE,lstrlen(CACHE_PATH_VALUE)))
UnixNormalisePath(pszOrigPath,pszEnvVar);
}
int UnixPathExists(LPCTSTR pszPath)
{
struct stat statbuf;
if (stat(pszPath, &statbuf) < 0)
{
/* If path does not exist */
if (errno == ENOENT)
return 0;
else
return -1;
}
/* TODO */
/* Make sure path points to a directory */
return 1;
}
void UnixGetValidParentPath(LPTSTR szDevice)
{
TCHAR szDeviceExists[MAX_PATH];
PTSTR pszDeviceExists = NULL;
PTSTR pszEnd = NULL;
if (!szDevice)
return;
lstrcpy(szDeviceExists, szDevice);
pszDeviceExists = szDeviceExists;
pszEnd = szDeviceExists + lstrlen(szDeviceExists);
for(;;)
{
int fPathExists;
if (pszEnd == pszDeviceExists)
break;
fPathExists = UnixPathExists(pszDeviceExists);
if (fPathExists == -1)
{
/* Error */
break;
}
else
if (fPathExists == 0)
{
/* Path does not exist */
while (*pszEnd != DIR_SEPARATOR_CHAR &&
pszEnd != pszDeviceExists)
pszEnd--;
*pszEnd = '\0';
continue;
}
else
{
/* Path exists */
lstrcpy(szDevice, pszDeviceExists);
break;
}
}
}
/* CopyDir */
static int DoCopy();
static int UnixCopyCacheFile(const char* file_src,
const char* file_dest,
mode_t fmode);
static int UnixCreateCacheFolder( const char* dir_dest, mode_t fmode);
#ifndef BUFSIZ
#define BUFSIZ 4096
#endif /* BUFSIZ */
#define CUR_DIR "."
#define PREV_DIR ".."
static char* pathdir1 = NULL;
static char* pathdir2 = NULL;
int CopyDir(const char* dirname1, const char* dirname2)
{
int Error = 0;
struct stat statdir1, statdir2;
if (!dirname1 || !dirname2)
{
goto Cleanup;
}
/* We are assuming that dirname1 and dirname2 are absolute paths */
if (stat(dirname1, &statdir1) < 0)
{
Error = errno;
goto Cleanup;
}
else
if (!S_ISDIR(statdir1.st_mode))
{
Error = -1; /* source is not directory */
goto Cleanup;
}
if (stat(dirname2, &statdir2) < 0)
{
if (errno != ENOENT)
{
Error = errno;
goto Cleanup;
}
/* It is fine if the destination dir does not exist
* provided all directories above the leaf dir exist
*/
}
else
if (!S_ISDIR(statdir2.st_mode))
{
Error = -1; /* destination is not directory */
goto Cleanup;
}
pathdir1 = (char*)malloc((MAX_PATH+1)*sizeof(char));
pathdir2 = (char*)malloc((MAX_PATH+1)*sizeof(char));
lstrcpy(pathdir1, dirname1);
lstrcpy(pathdir2, dirname2);
Error = DoCopy();
Cleanup:
if (pathdir1)
free(pathdir1);
if (pathdir2)
free(pathdir2);
pathdir1 = pathdir2 = NULL;
return Error;
}
int DoCopy()
{
struct stat statbuf;
struct dirent *dirp;
DIR *dp;
int Error;
char *ptr1, *ptr2;
if (stat(pathdir1, &statbuf) < 0)
{
Error = errno;
goto Cleanup;
}
/* Check if this is a regular file */
if ((statbuf.st_mode & S_IFMT) == S_IFREG)
{
Error = UnixCopyCacheFile(pathdir1, pathdir2, statbuf.st_mode);
goto Cleanup;
}
/* Now, we are dealing with a directory */
if ((Error = UnixCreateCacheFolder(pathdir2, statbuf.st_mode)))
goto Cleanup;
ptr1 = pathdir1 + lstrlen(pathdir1);
*ptr1++ = '/';
*ptr1 = 0;
ptr2 = pathdir2 + lstrlen(pathdir2);
*ptr2++ = '/';
*ptr2 = 0;
if ((dp = opendir(pathdir1)) == NULL)
{
Error = errno;
goto Cleanup;
}
while ((dirp = readdir(dp)) != NULL)
{
if (!lstrcmp(dirp->d_name, CUR_DIR) ||
!lstrcmp(dirp->d_name, PREV_DIR))
continue;
lstrcpy(ptr1, dirp->d_name);
lstrcpy(ptr2, dirp->d_name);
if ((Error = DoCopy()))
break;
}
ptr1[-1] = 0;
ptr2[-1] = 0;
/* If this fails, ignore this error */
closedir(dp);
Cleanup:
return Error;
}
static int UnixCreateCacheFolder( const char* path_dest, mode_t mode_src)
{
int Error = 0;
struct stat statbuf2;
if (stat(path_dest, &statbuf2) < 0)
{
if (errno == ENOENT)
{
if (mkdir(path_dest, mode_src) < 0)
{
Error = errno;
goto Cleanup;
}
}
else
{
Error = errno;
goto Cleanup;
}
}
else
if (!S_ISDIR(statbuf2.st_mode))
Error = -1; /* we are expecting a directory */
Cleanup:
return Error;
}
int UnixCopyCacheFile(const char* file_src, const char* file_dest, mode_t fmode)
{
int Error = 0;
int fd1, fd2;
char buf[BUFSIZ];
int nread, nwrite;
if ((fd1 = open(file_src, O_RDONLY)) < 0)
{
Error = errno;
goto Cleanup;
}
if ((fd2 = open(file_dest, O_CREAT|O_TRUNC|O_WRONLY, fmode)) < 0)
{
Error = errno;
goto Cleanup;
}
while((nread = read(fd1, buf, BUFSIZ)) > 0)
{
if ((nwrite = write(fd2, buf, nread)) != nread)
{
Error = errno;
goto Cleanup;
}
}
Error = 0;
Cleanup:
if (fd1 > 0)
close(fd1);
if (fd2 > 0)
close(fd2);
return Error;
}