blob: c3a66a7c14d57fb83cd71ba48d8f742d74bd2ac7 [file] [log] [blame]
/****************************************************************************
*
* 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;
}