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