| /**************************************************************************** | |
| * | |
| * 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; | |
| } |