Exemplo n.º 1
0
/**
 * 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;
}
Exemplo n.º 2
0
/**
 * 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;
}