/** * Fill parsed parameters into fileargs struct and expand regular expression * based filename if requested. * * @param gbmfilearg Struct that initially has the argin parameter set and * will be completed by the function. * * @param filename Filename array (can contain regular expressions) * * @param options Options (optional if NULL or "" is provided) * * @param expandRegEx The filename can contain regular expression that are * supported by the platform file system, for instance * or ?. * * @retval GBM_ERR_OK Argument successfully parsed. * @retval GBM_ERR_MEM Out of memory. * @retval GBM_ERR_BAD_ARG Argument could not be parsed. */ static GBM_ERR fill_arguments(GBMTOOL_FILEARG * gbmfilearg, const char * filename, const char * options, const BOOLEAN expandRegEx) { gbmfilearg->files = NULL; gbmfilearg->filecount = 0; gbmfilearg->options = NULL; if (filename == NULL) { return GBM_ERR_BAD_ARG; } /* check for illegal " in the filename */ if (strchr(filename, '"') != NULL) { return GBM_ERR_BAD_ARG; } /* allocate options */ if (options != NULL) { gbmfilearg->options = (char *) malloc(strlen(options) + 1); } else { gbmfilearg->options = (char *) malloc(1); } if (gbmfilearg->options == NULL) { return GBM_ERR_MEM; } /* fill in options */ strcpy(gbmfilearg->options, (options != NULL) ? options : ""); /* check for illegal " in the options */ if (strchr(gbmfilearg->options, '"') != NULL) { free(gbmfilearg->options); gbmfilearg->options = NULL; return GBM_ERR_BAD_ARG; } /* expand filename template */ if (expandRegEx) { #ifndef FILENAME_EXPANSION_MODE free(gbmfilearg->options); gbmfilearg->options = NULL; return GBM_ERR_BAD_ARG; #else /* dispatch to platform specific handlers (must use C library memory management) */ if (! gbmtool_findFiles(filename, &gbmfilearg->files, &gbmfilearg->filecount)) { gbmfilearg->filecount = 0; free(gbmfilearg->options); gbmfilearg->options = NULL; return GBM_ERR_BAD_ARG; } #endif /* FILENAME_EXPANSION_MODE */ } else { /* no filename template expansion */ gbmfilearg->files = gbmtool_createFileNode(filename); if (gbmfilearg->files == NULL) { free(gbmfilearg->options); gbmfilearg->options = NULL; return GBM_ERR_MEM; } gbmfilearg->filecount = 1; } return GBM_ERR_OK; }
/** * Implements extension for resolving filename with regular expressions. * * @param filename Filename (can contain regular expressions) * * @param filearray Resolved filename array, will be allocated. * For the number of entries see filearray_length. * The client has to take care of freeing it with * the C library free() function. * * @param filearray_length Number of filenames contained in filearray. * * @retval GBM_TRUE Success. * @retval GBM_FALSE An error occured. */ gbm_boolean gbmtool_findFiles(const char * filename, GBMTOOL_FILE ** files, unsigned int * filecount) { HDIR hdirFindHandle = HDIR_CREATE; FILEFINDBUF3 findBuffer = {0}; /* Returned from FindFirst/Next */ ULONG ulResultBufLen = sizeof(FILEFINDBUF3); ULONG ulFindCount = 1; /* Look for 1 file at a time */ APIRET rc = NO_ERROR; /* Return code */ char buffer[1025] = { 0 }; char * path = NULL; #ifndef NDEBUG int pathlength = 0; #endif GBMTOOL_FILE * firstNode = NULL; GBMTOOL_FILE * currentNode = NULL; *filecount = 0; *files = NULL; if (! getPathFromFullFilename(filename, &path)) { return GBM_FALSE; } #ifndef NDEBUG pathlength = strlen(path); #endif rc = DosFindFirst((char *)filename, /* File pattern */ &hdirFindHandle, /* Directory search handle */ FILE_NORMAL, /* Search attribute */ &findBuffer, /* Result buffer */ ulResultBufLen, /* Result buffer length */ &ulFindCount, /* Number of entries to find */ FIL_STANDARD); /* Return Level 1 file info */ if ((rc != NO_ERROR) || (ulFindCount != 1)) { DosFindClose(hdirFindHandle); free(path); return GBM_FALSE; } /* add first found filename */ assert(pathlength + strlen(findBuffer.achName) + 1 <= sizeof(buffer)); sprintf(buffer, "%s%s", path, findBuffer.achName); *filecount = 0; *files = gbmtool_createFileNode(buffer); if (*files == NULL) { DosFindClose(hdirFindHandle); free(path); return GBM_FALSE; } *filecount += ulFindCount; firstNode = *files; currentNode = firstNode; /* Keep finding the next file until there are no more files */ while (rc != ERROR_NO_MORE_FILES) { ulFindCount = 1; /* Reset find count. */ rc = DosFindNext(hdirFindHandle, /* Directory handle */ &findBuffer, /* Result buffer */ ulResultBufLen, /* Result buffer length */ &ulFindCount); /* Number of entries to find */ if ((rc != NO_ERROR && rc != ERROR_NO_MORE_FILES) || (ulFindCount > 1)) { unsigned int count; gbmtool_free_all_subnodes(firstNode, &count); *filecount -= count; gbmtool_free_node(firstNode); (*filecount)--; DosFindClose(hdirFindHandle); free(path); return GBM_FALSE; } if ((rc != ERROR_NO_MORE_FILES) && (ulFindCount == 1)) { /* add found filename */ assert(pathlength + strlen(findBuffer.achName) + 1 <= sizeof(buffer)); sprintf(buffer, "%s%s", path, findBuffer.achName); currentNode->next = gbmtool_createFileNode(buffer); if (currentNode->next == NULL) { unsigned int count; gbmtool_free_all_subnodes(firstNode, &count); *filecount -= count; gbmtool_free_node(firstNode); (*filecount)--; DosFindClose(hdirFindHandle); free(path); return GBM_FALSE; } *filecount += ulFindCount; currentNode = currentNode->next; } } /* endwhile */ DosFindClose(hdirFindHandle); /* Close our directory handle */ free(path); return GBM_TRUE; }