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