Пример #1
0
static void *file_archive_open(const char *path)
{
    file_archive_file_data_t *data = (file_archive_file_data_t*)calloc(1, sizeof(*data));

    if (!data)
        return NULL;

    data->fd = open(path, O_RDONLY);

    /* Failed to open archive. */
    if (data->fd < 0)
        goto error;

    data->size = path_get_size(path);
    if (!data->size)
        return data;

    data->data = mmap(NULL, data->size, PROT_READ, MAP_SHARED, data->fd, 0);
    if (data->data == MAP_FAILED)
    {
        data->data = NULL;

        /* Failed to mmap() file */
        goto error;
    }

    return data;

error:
    file_archive_free(data);
    return NULL;
}
Пример #2
0
int file_archive_parse_file_iterate(
    file_archive_transfer_t *state,
    bool *returnerr,
    const char *file,
    const char *valid_exts,
    file_archive_file_cb file_cb,
    void *userdata)
{
    if (!state)
        return -1;

    switch (state->type)
    {
    case ZLIB_TRANSFER_NONE:
        break;
    case ZLIB_TRANSFER_INIT:
        if (file_archive_parse_file_init(state, file) == 0)
            state->type = ZLIB_TRANSFER_ITERATE;
        else
            state->type = ZLIB_TRANSFER_DEINIT_ERROR;
        break;
    case ZLIB_TRANSFER_ITERATE:
    {
        int ret = file_archive_parse_file_iterate_step(state,
                  valid_exts, userdata, file_cb);
        if (ret != 1)
            state->type = ZLIB_TRANSFER_DEINIT;
        if (ret == -1)
            state->type = ZLIB_TRANSFER_DEINIT_ERROR;
    }
    break;
    case ZLIB_TRANSFER_DEINIT_ERROR:
        *returnerr = false;
    case ZLIB_TRANSFER_DEINIT:
        if (state->handle)
            file_archive_free(state->handle);
        state->handle = NULL;
        break;
    }

    if (state->type == ZLIB_TRANSFER_DEINIT ||
            state->type == ZLIB_TRANSFER_DEINIT_ERROR)
        return -1;

    return 0;
}
Пример #3
0
static void *file_archive_open(const char *path)
{
    ssize_t ret            = -1;
    bool read_from_file    = false;
    file_archive_file_data_t *data = (file_archive_file_data_t*)
                                     calloc(1, sizeof(*data));

    if (!data)
        return NULL;

    read_from_file = filestream_read_file(path, &data->data, &ret);

    /* Failed to open archive? */
    if (!read_from_file || ret < 0)
        goto error;

    data->size = ret;
    return data;

error:
    file_archive_free(data);
    return NULL;
}
Пример #4
0
int file_archive_parse_file_iterate(
      file_archive_transfer_t *state,
      bool *returnerr,
      const char *file,
      const char *valid_exts,
      file_archive_file_cb file_cb,
      struct archive_extract_userdata *userdata)
{
   if (!state)
      return -1;

   switch (state->type)
   {
      case ARCHIVE_TRANSFER_NONE:
         break;
      case ARCHIVE_TRANSFER_INIT:
         if (file_archive_parse_file_init(state, file) == 0)
         {
            if (userdata)
            {
               userdata->context = state->stream;
               strlcpy(userdata->archive_path, file,
                     sizeof(userdata->archive_path));
            }
            state->type = ARCHIVE_TRANSFER_ITERATE;
         }
         else
            state->type = ARCHIVE_TRANSFER_DEINIT_ERROR;
         break;
      case ARCHIVE_TRANSFER_ITERATE:
         if (file_archive_get_file_backend(file))
         {
            const struct file_archive_file_backend *backend =
               file_archive_get_file_backend(file);
            int ret                                         = 
               backend->archive_parse_file_iterate_step(state,
                  valid_exts, userdata, file_cb);

            if (ret != 1)
               state->type = ARCHIVE_TRANSFER_DEINIT;
            if (ret == -1)
               state->type = ARCHIVE_TRANSFER_DEINIT_ERROR;

            /* early return to prevent deinit from never firing */
            return 0;
         }
         return -1;
      case ARCHIVE_TRANSFER_DEINIT_ERROR:
         *returnerr = false;
      case ARCHIVE_TRANSFER_DEINIT:
         if (state->handle)
         {
            file_archive_free(state->handle);
            state->handle = NULL;
         }

         if (state->stream && state->backend)
         {
            if (state->backend->stream_free)
               state->backend->stream_free(state->stream);

            if (state->stream)
               free(state->stream);

            state->stream = NULL;

            if (userdata)
               userdata->context = NULL;
         }
         break;
   }

   if (  state->type == ARCHIVE_TRANSFER_DEINIT ||
         state->type == ARCHIVE_TRANSFER_DEINIT_ERROR)
      return -1;

   return 0;
}