307 lines
8.7 KiB
C
307 lines
8.7 KiB
C
/****************************************************************************
|
|
*
|
|
* SciTech OS Portability Manager Library
|
|
*
|
|
* ========================================================================
|
|
*
|
|
* The contents of this file are subject to the SciTech MGL Public
|
|
* License Version 1.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.scitechsoft.com/mgl-license.txt
|
|
*
|
|
* Software distributed under the License is distributed on an
|
|
* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
|
|
*
|
|
* The Initial Developer of the Original Code is SciTech Software, Inc.
|
|
* All Rights Reserved.
|
|
*
|
|
* ========================================================================
|
|
*
|
|
* Language: ANSI C
|
|
* Environment: Any
|
|
*
|
|
* Description: Module containing Unix I/O functions.
|
|
*
|
|
****************************************************************************/
|
|
|
|
#include "pmapi.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#include <dirent.h>
|
|
|
|
/*----------------------------- Implementation ----------------------------*/
|
|
|
|
/* {secret} */
|
|
typedef struct {
|
|
DIR *d;
|
|
char path[PM_MAX_PATH];
|
|
char mask[PM_MAX_PATH];
|
|
} PM_findHandle;
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Internal function to convert the find data to the generic interface.
|
|
****************************************************************************/
|
|
static void convertFindData(
|
|
PM_findData *findData,
|
|
struct dirent *blk,
|
|
const char *path)
|
|
{
|
|
ulong dwSize = findData->dwSize;
|
|
struct stat st;
|
|
char filename[PM_MAX_PATH];
|
|
|
|
memset(findData,0,findData->dwSize);
|
|
findData->dwSize = dwSize;
|
|
strcpy(filename,path);
|
|
PM_backslash(filename);
|
|
strcat(filename,blk->d_name);
|
|
stat(filename,&st);
|
|
if (!(st.st_mode & S_IWRITE))
|
|
findData->attrib |= PM_FILE_READONLY;
|
|
if (st.st_mode & S_IFDIR)
|
|
findData->attrib |= PM_FILE_DIRECTORY;
|
|
findData->sizeLo = st.st_size;
|
|
findData->sizeHi = 0;
|
|
strncpy(findData->name,blk->d_name,PM_MAX_PATH);
|
|
findData->name[PM_MAX_PATH-1] = 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Determines if a file name matches the passed in pattern.
|
|
****************************************************************************/
|
|
static ibool filematch(
|
|
char *pattern,
|
|
char *dirpath,
|
|
struct dirent *dire)
|
|
{
|
|
struct stat st;
|
|
int i = 0,j = 0,lastchar = '\0';
|
|
char fullpath[PM_MAX_PATH];
|
|
|
|
strcpy(fullpath,dirpath);
|
|
PM_backslash(fullpath);
|
|
strcat(fullpath, dire->d_name);
|
|
if (stat(fullpath, &st) != 0)
|
|
return false;
|
|
for (; i < (int)strlen(dire->d_name) && j < (int)strlen(pattern); i++, j++) {
|
|
if (pattern[j] == '*' && lastchar != '\\') {
|
|
if (pattern[j+1] == '\0')
|
|
return true;
|
|
while (dire->d_name[i++] != pattern[j+1]) {
|
|
if (dire->d_name[i] == '\0')
|
|
return false;
|
|
}
|
|
i -= 2;
|
|
}
|
|
else if (dire->d_name[i] != pattern[j] &&
|
|
!(pattern[j] == '?' && lastchar != '\\'))
|
|
return false;
|
|
lastchar = pattern[i];
|
|
}
|
|
if (j == (int)strlen(pattern) && i == (int)strlen(dire->d_name))
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to find the first file matching a search criteria in a directory.
|
|
****************************************************************************/
|
|
void * PMAPI PM_findFirstFile(
|
|
const char *filename,
|
|
PM_findData *findData)
|
|
{
|
|
PM_findHandle *d;
|
|
struct dirent *dire;
|
|
char name[PM_MAX_PATH];
|
|
char ext[PM_MAX_PATH];
|
|
|
|
if ((d = PM_malloc(sizeof(*d))) == NULL)
|
|
return PM_FILE_INVALID;
|
|
PM_splitpath(filename,NULL,d->path,name,ext);
|
|
strcpy(d->mask,name);
|
|
strcat(d->mask,ext);
|
|
if (strlen(d->path) == 0)
|
|
strcpy(d->path, ".");
|
|
if (d->path[strlen(d->path)-1] == '/')
|
|
d->path[strlen(d->path)-1] = 0;
|
|
if ((d->d = opendir(d->path)) != NULL) {
|
|
while ((dire = readdir(d->d)) != NULL) {
|
|
if (filematch(d->mask,d->path,dire)) {
|
|
convertFindData(findData,dire,d->path);
|
|
return d;
|
|
}
|
|
}
|
|
closedir(d->d);
|
|
}
|
|
PM_free(d);
|
|
return PM_FILE_INVALID;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to find the next file matching a search criteria in a directory.
|
|
****************************************************************************/
|
|
ibool PMAPI PM_findNextFile(
|
|
void *handle,
|
|
PM_findData *findData)
|
|
{
|
|
PM_findHandle *d = handle;
|
|
struct dirent *dire;
|
|
|
|
while ((dire = readdir(d->d)) != NULL) {
|
|
if (filematch(d->mask,d->path,dire)) {
|
|
convertFindData(findData,dire,d->path);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to close the find process
|
|
****************************************************************************/
|
|
void PMAPI PM_findClose(
|
|
void *handle)
|
|
{
|
|
PM_findHandle *d = handle;
|
|
|
|
closedir(d->d);
|
|
free(d);
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to determine if a drive is a valid drive or not. Under Unix this
|
|
function will return false for anything except a value of 3 (considered
|
|
the root drive, and equivalent to C: for non-Unix systems). The drive
|
|
numbering is:
|
|
|
|
1 - Drive A:
|
|
2 - Drive B:
|
|
3 - Drive C:
|
|
etc
|
|
|
|
****************************************************************************/
|
|
ibool PMAPI PM_driveValid(
|
|
char drive)
|
|
{
|
|
if (drive == 3)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to get the current working directory for the specififed drive.
|
|
Under Unix this will always return the current working directory regardless
|
|
of what the value of 'drive' is.
|
|
****************************************************************************/
|
|
void PMAPI PM_getdcwd(
|
|
int drive,
|
|
char *dir,
|
|
int len)
|
|
{
|
|
(void)drive;
|
|
getcwd(dir,len);
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to change the file attributes for a specific file.
|
|
****************************************************************************/
|
|
void PMAPI PM_setFileAttr(
|
|
const char *filename,
|
|
uint attrib)
|
|
{
|
|
struct stat st;
|
|
mode_t mode;
|
|
|
|
stat(filename,&st);
|
|
mode = st.st_mode;
|
|
if (attrib & PM_FILE_READONLY)
|
|
mode &= ~S_IWRITE;
|
|
else
|
|
mode |= S_IWRITE;
|
|
chmod(filename,mode);
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to get the file attributes for a specific file.
|
|
****************************************************************************/
|
|
uint PMAPI PM_getFileAttr(
|
|
const char *filename)
|
|
{
|
|
struct stat st;
|
|
|
|
stat(filename,&st);
|
|
if (st.st_mode & S_IWRITE)
|
|
return 0;
|
|
return PM_FILE_READONLY;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to create a directory.
|
|
****************************************************************************/
|
|
ibool PMAPI PM_mkdir(
|
|
const char *filename)
|
|
{
|
|
return mkdir(filename,0x1FF) == 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to remove a directory.
|
|
****************************************************************************/
|
|
ibool PMAPI PM_rmdir(
|
|
const char *filename)
|
|
{
|
|
return rmdir(filename) == 0;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to get the file time and date for a specific file.
|
|
****************************************************************************/
|
|
ibool PMAPI PM_getFileTime(
|
|
const char *filename,
|
|
ibool gmTime,
|
|
PM_time *time)
|
|
{
|
|
/* TODO: Implement this! */
|
|
(void)filename;
|
|
(void)gmTime;
|
|
(void)time;
|
|
PM_fatalError("PM_getFileTime not implemented yet!");
|
|
return false;
|
|
}
|
|
|
|
/****************************************************************************
|
|
REMARKS:
|
|
Function to set the file time and date for a specific file.
|
|
****************************************************************************/
|
|
ibool PMAPI PM_setFileTime(
|
|
const char *filename,
|
|
ibool gmTime,
|
|
PM_time *time)
|
|
{
|
|
/* TODO: Implement this! */
|
|
(void)filename;
|
|
(void)gmTime;
|
|
(void)time;
|
|
PM_fatalError("PM_setFileTime not implemented yet!");
|
|
return false;
|
|
}
|