Beispiel #1
0
static Eina_File *
check_bc(Eina_File *of, const char *fname, Eina_Bool *bc)
{
   if (of)
     {
        struct stat bc_stat, sc_stat;
        /* original file doesn't exist, only bytecode does, use bytecode */
        if (stat(fname, &sc_stat) < 0)
          return of;
        if (stat(eina_file_filename_get(of), &bc_stat) < 0)
          {
             /* what? */
             eina_file_close(of);
             goto generate;
          }
        /* bytecode is newer than original file, use bytecode */
        if (bc_stat.st_mtime > sc_stat.st_mtime)
          return of;
        /* bytecode is not new enough; trigger regeneration */
        eina_file_close(of);
     }
generate:
   *bc = EINA_TRUE;
   return eina_file_open(fname, EINA_FALSE);
}
Beispiel #2
0
static Eina_Bool
_etui_epub_mimetype_is_valid(Etui_Provider_Data *pd)
{
    char buf[PATH_MAX];
    Eina_File *f;
    void *data;

    snprintf(buf, sizeof(buf), "%s/%s", pd->doc.path, "mimetype");
    buf[sizeof(buf) - 1] = '\0';
    f = eina_file_open(buf, EINA_FALSE);
    if (!f)
        return EINA_FALSE;

    data = eina_file_map_all(f, EINA_FILE_POPULATE);
    if (!data)
    {
        eina_file_close(f);
        return EINA_FALSE;
    }

    if (strcmp(data, "application/epub+zip") != 0)
    {
        eina_file_close(f);
        return EINA_FALSE;
    }

    eina_file_close(f);

    return EINA_TRUE;
}
Beispiel #3
0
static Eina_Bool
_etui_epub_opf_is_valid(Etui_Provider_Data *pd)
{
    char buf[PATH_MAX];
    Eina_File *f;

    snprintf(buf, sizeof(buf), "%s/%s", pd->doc.path, pd->container.content_file);
    buf[sizeof(buf) - 1] = '\0';
    f = eina_file_open(buf, EINA_FALSE);
    if (!f)
        return EINA_FALSE;

    if (!eina_simple_xml_parse((const char *)eina_file_map_all(f, EINA_FILE_POPULATE),
                               eina_file_size_get(f),
                               EINA_TRUE,
                               _etui_epub_opf_parse_cb, pd))
    {
        eina_file_close(f);
        return EINA_FALSE;
    }

    eina_file_close(f);

    return EINA_TRUE;
}
Beispiel #4
0
void 
_evas_xcb_xdefaults_shutdown(void) 
{
   if (!_evas_xcb_xdefaults_file) return;
   if (_evas_xcb_xdefaults_data) 
     eina_file_map_free(_evas_xcb_xdefaults_file, _evas_xcb_xdefaults_data);
   if (_evas_xcb_xdefaults_file) eina_file_close(_evas_xcb_xdefaults_file);
}
Beispiel #5
0
static Eina_Bool
_etui_epub_ncx_is_valid(Etui_Provider_Data *pd)
{
    char buf[PATH_MAX];
    Etui_Epub_Opf_Manifest_Item *item;
    Eina_File *f;
    char *oebps_dir;

    if (!pd->opf.toc_id)
        return EINA_FALSE;

    item = eina_hash_find(pd->opf.manifest, pd->opf.toc_id);
    if (!item)
        return EINA_FALSE;

    oebps_dir = strdup(pd->container.content_file);
    if (!oebps_dir)
        return EINA_FALSE;

    snprintf(buf, sizeof(buf), "%s/%s/%s", pd->doc.path, dirname(oebps_dir), item->href);
    buf[sizeof(buf) - 1] = '\0';
    free(oebps_dir);
    f = eina_file_open(buf, EINA_FALSE);
    if (!f)
    {
        return EINA_FALSE;
    }

    pd->ncx.current_depth = -1;

    if (!eina_simple_xml_parse((const char *)eina_file_map_all(f, EINA_FILE_POPULATE),
                               eina_file_size_get(f),
                               EINA_TRUE,
                               _etui_epub_ncx_parse_cb, pd))
    {
        eina_file_close(f);
        return EINA_FALSE;
    }

    eina_file_close(f);

    return EINA_TRUE;
}
Beispiel #6
0
Eina_Bool
shotgun_emoticon_custom_add(Shotgun_Auth *auth, const char *file, const char *text, const char *type)
{
   Shotgun_Custom_Emoticon *emo;
   char *data_base64,
         tmp_cid[63];
   size_t len,
          len64;
   const char *sha1;
   Eina_File *fh;
   const unsigned char *data;

   EINA_SAFETY_ON_NULL_RETURN_VAL(auth, EINA_FALSE);
   EINA_SAFETY_ON_NULL_RETURN_VAL(file, EINA_FALSE);
   EINA_SAFETY_ON_NULL_RETURN_VAL(text, EINA_FALSE);
   EINA_SAFETY_ON_NULL_RETURN_VAL(type, EINA_FALSE);


   fh = eina_file_open(file, EINA_FALSE);
   if (!fh)
     {
        ERR("Couldnt open file %s", file);
        return EINA_FALSE;
     }

   len = eina_file_size_get(fh);

   data = (const unsigned char *)eina_file_map_all(fh, EINA_FILE_SEQUENTIAL);

   DBG("data[%p] len=%ld", data, len);
   DBG("data[1] = %c", data[1]);
   sha1 = sha1_buffer(data, len);

   data_base64 = shotgun_base64_encode(data, len, &len64);
   eina_file_map_free(fh, (void *)data);
   eina_file_close(fh);

   emo = calloc(1, sizeof(Shotgun_Custom_Emoticon));
   if (!emo) return EINA_FALSE;

   emo->file = eina_stringshare_add(file);
   emo->text = strdup(text);
   emo->type = strdup(type);
   emo->data_base64 = data_base64;
   sprintf(tmp_cid, "cid:sha1+%[email protected]", sha1);
   emo->cid = strdup(tmp_cid);

   auth->custom_emoticons = eina_inlist_append(auth->custom_emoticons, EINA_INLIST_GET(emo));
   return EINA_TRUE;
}
Beispiel #7
0
static void
read_watch_file(const char *file)
{
   Eina_File *f;
   Eina_Iterator *it;
   Eina_File_Line *ln;
   Eio_Monitor *mon;
   Eina_List *r = NULL;

   f = eina_file_open(file, EINA_FALSE);
   if (!f) return ;

   it = eina_file_map_lines(f);
   if (!it) goto err;

   EINA_ITERATOR_FOREACH(it, ln)
     {
        const char *path;
        Eina_Bool do_append = EINA_TRUE;

	if (ln->length < 4) continue ;
        if (anotate)
          {
             path = eina_stringshare_add_length(ln->start + 3, ln->length - 3);
             fprintf(stdout, "%c: %s\n", *ln->start, path);
             if (*ln->start == 'O')
               do_append = EINA_FALSE;
          }
        else
          {
             path = eina_stringshare_add_length(ln->start, ln->length);
          }
        if (do_append)
	  r = eina_list_append(r, eio_monitor_add(path));
        eina_stringshare_del(path);
     }
   eina_iterator_free(it);

   EINA_LIST_FREE(watching, mon)
     eio_monitor_del(mon);
   watching = r;

 err:
   eina_file_close(f);
}
Beispiel #8
0
static void
_loaded_handle(Image_Entry *ie, const Msg_Loaded *msg)
{
   Data_Entry *dentry = ie->data2;
   const char *shmpath;

   shmpath = ((const char *)msg) + sizeof(*msg);

   // dentry->shm.path = strdup(shmpath);
   dentry->shm.mmap_offset = msg->shm.mmap_offset;
   dentry->shm.use_offset = msg->shm.use_offset;
   dentry->shm.mmap_size = msg->shm.mmap_size;
   dentry->shm.image_size = msg->shm.image_size;

   dentry->shm.f = eina_file_open(shmpath, EINA_TRUE);
   if (!dentry->shm.f)
     {
        free(dentry);
        ie->data2 = NULL;
        return;
     }

   dentry->shm.data = eina_file_map_new(dentry->shm.f, EINA_FILE_WILLNEED,
                                        dentry->shm.mmap_offset,
                                        dentry->shm.mmap_size);

   if (!dentry->shm.data)
     {
        eina_file_close(dentry->shm.f);
        free(dentry);
        ie->data2 = NULL;
     }

   if (ie->data2)
     {
        RGBA_Image *im = (RGBA_Image *)ie;
        im->image.data = evas_cserve2_image_data_get(ie);
        ie->flags.alpha_sparse = msg->alpha_sparse;
        ie->flags.loaded = EINA_TRUE;
        im->image.no_free = 1;
     }
}
Beispiel #9
0
/**
 * @internal
 * @param file The file to parse
 * @return Returns an Eina_Hash with the contents of @a file, or NULL if the
 *         file fails to parse or if the file doesn't exist
 * @brief Parses the ini file @a file into an Eina_Hash
 */
static Eina_Hash *
efreet_ini_parse(const char *file)
{
    Eina_Hash *data = NULL, *section = NULL;
    Eina_Iterator *it = NULL;
    Eina_File_Line *line;
    Eina_File *f;

    EINA_SAFETY_ON_NULL_RETURN_VAL(file, NULL);
    f = eina_file_open(file, EINA_FALSE);
    if (!f)
        return NULL;

    data = eina_hash_string_small_new(EINA_FREE_CB(eina_hash_free));
    if (!data) goto error;

    /* let's make mmap safe and just get 0 pages for IO erro */
    eina_mmap_safety_enabled_set(EINA_TRUE);

    it = eina_file_map_lines(f);
    if (!it) goto error;
    EINA_ITERATOR_FOREACH(it, line)
    {
        const char *eq;
        unsigned int start = 0;

        /* skip empty lines */
        if (line->length == 0) continue;
        /* skip white space at start of line */
        while ((start < line->length) && (isspace((unsigned char)line->start[start])))
            start++;
        /* skip empty lines */
        if (start == line->length) continue;
        /* skip comments */
        if (line->start[start] == '#') continue;

        /* new section */
        if (line->start[start] == '[')
        {
            const char *head_start;
            const char *head_end;

            head_start = &(line->start[start]) + 1;
            head_end = memchr(line->start, ']', line->length);

            if (head_end)
            {
                char *header;
                size_t len;

                len = head_end - head_start + 1;
                header = alloca(len);

                memcpy(header, head_start, len - 1);
                header[len - 1] = '\0';

                section = eina_hash_string_small_new(EINA_FREE_CB(eina_stringshare_del));

                eina_hash_del_by_key(data, header);
                eina_hash_add(data, header, section);
            }
            else
            {
                /* invalid file - skip line? or refuse to parse file? */
                /* just printf for now till we figure out what to do */
//                ERR("Invalid file (%s) (missing ] on group name)", file);
            }
            continue;
        }

        if (!section)
        {
            INF("Invalid file (%s) (missing section)", file);
            goto error;
        }

        eq = memchr(line->start, '=', line->length);

        if (eq)
        {
            const char *key_start, *key_end;
            const char *value_start, *value_end;
            char *key, *value;
            size_t len;

            key_start = &(line->start[start]);
            key_end = eq - 1;

            /* trim whitespace from end of key */
            while ((isspace((unsigned char)*key_end)) && (key_end > key_start))
                key_end--;
            key_end++;

            /* make sure we have a key */
            if (key_start == key_end) continue;

            value_start = eq + 1;
            value_end = line->end;

            /* line->end points to char after '\n' or '\r' */
            value_end--;
            /* trim whitespace from end of value */
            while ((isspace((unsigned char)*value_end)) && (value_end > value_start))
                value_end--;
            value_end++;

            /* trim whitespace from start of value */
            while ((isspace((unsigned char)*value_start)) && (value_start < value_end))
                value_start++;

            len = key_end - key_start + 1;
            key = alloca(len);

            memcpy(key, key_start, len - 1);
            key[len - 1] = '\0';

            /* empty value allowed */
            if (value_end == value_start)
            {
                eina_hash_del_by_key(section, key);
                eina_hash_add(section, key, "");
            }
            else
            {
                len = value_end - value_start + 1;
                value = alloca(len);
                memcpy(value, value_start, len - 1);
                value[len - 1] = '\0';

                eina_hash_del_by_key(section, key);
                eina_hash_add(section, key, efreet_ini_unescape(value));
            }
        }
        else
        {
            /* invalid file... */
            INF("Invalid file (%s) (missing = from key=value pair)", file);
            goto error;
        }
    }
    eina_iterator_free(it);
    eina_file_close(f);

#if 0
    if (!eina_hash_population(data))
    {
        eina_hash_free(data);
        return NULL;
    }
#endif
    return data;
error:
    if (data) eina_hash_free(data);
    if (it) eina_iterator_free(it);

    eina_file_close(f);
    return NULL;
}
Beispiel #10
0
EAPI Eet_Key *
eet_identity_open(const char               *certificate_file,
                  const char               *private_key_file,
                  Eet_Key_Password_Callback cb)
{
#ifdef HAVE_SIGNATURE
   /* Signature declarations */
   Eet_Key *key = NULL;
# ifdef HAVE_GNUTLS
   /* Gnutls private declarations */
   Eina_File *f = NULL;
   void *data = NULL;
   gnutls_datum_t load_file = { NULL, 0 };
   char pass[1024];

   if (!emile_cipher_init()) return NULL;

   /* Init */
   if (!(key = malloc(sizeof(Eet_Key))))
     goto on_error;

   key->references = 1;

   if (gnutls_x509_crt_init(&(key->certificate)))
     goto on_error;

   if (gnutls_x509_privkey_init(&(key->private_key)))
     goto on_error;

   /* Mmap certificate_file */
   f = eina_file_open(certificate_file, 0);
   if (!f)
     goto on_error;

   /* let's make mmap safe and just get 0 pages for IO erro */
   eina_mmap_safety_enabled_set(EINA_TRUE);

   data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
   if (!data) goto on_error;

   /* Import the certificate in Eet_Key structure */
   load_file.data = data;
   load_file.size = eina_file_size_get(f);
   if (gnutls_x509_crt_import(key->certificate, &load_file,
                              GNUTLS_X509_FMT_PEM) < 0)
     goto on_error;

   eina_file_map_free(f, data);

   /* Reset values */
   eina_file_close(f);
   f = NULL;
   data = NULL;
   load_file.data = NULL;
   load_file.size = 0;

   /* Mmap private_key_file */
   f = eina_file_open(private_key_file, 0);
   if (!f)
     goto on_error;

   /* let's make mmap safe and just get 0 pages for IO erro */
   eina_mmap_safety_enabled_set(EINA_TRUE);

   data = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
   if (!data)
     goto on_error;

   /* Import the private key in Eet_Key structure */
   load_file.data = data;
   load_file.size = eina_file_size_get(f);
   /* Try to directly import the PEM encoded private key */
   if (gnutls_x509_privkey_import(key->private_key, &load_file,
                                  GNUTLS_X509_FMT_PEM) < 0)
     {
        /* Else ask for the private key pass */
         if (cb && cb(pass, 1024, 0, NULL))
           {
     /* If pass then try to decode the pkcs 8 private key */
               if (gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file,
                                                    GNUTLS_X509_FMT_PEM, pass, 0))
                 goto on_error;
           }
         else
         /* Else try to import the pkcs 8 private key without pass */
         if (gnutls_x509_privkey_import_pkcs8(key->private_key, &load_file,
                                              GNUTLS_X509_FMT_PEM, NULL, 1))
           goto on_error;
     }

   eina_file_map_free(f, data);
   eina_file_close(f);

   return key;

on_error:
   if (data) eina_file_map_free(f, data);
   if (f) eina_file_close(f);

   if (key)
     {
        if (key->certificate)
          gnutls_x509_crt_deinit(key->certificate);

        if (key->private_key)
          gnutls_x509_privkey_deinit(key->private_key);

        free(key);
     }

# else /* ifdef HAVE_GNUTLS */
   /* Openssl private declarations */
   FILE *fp;
   EVP_PKEY *pkey = NULL;
   X509 *cert = NULL;

   if (!emile_cipher_init()) return NULL;

   /* Load the X509 certificate in memory. */
   fp = fopen(certificate_file, "rb");
   if (!fp)
     return NULL;

   cert = PEM_read_X509(fp, NULL, NULL, NULL);
   fclose(fp);
   if (!cert)
     goto on_error;

   /* Check the presence of the public key. Just in case. */
   pkey = X509_get_pubkey(cert);
   if (!pkey)
     goto on_error;

   /* Load the private key in memory. */
   fp = fopen(private_key_file, "rb");
   if (!fp)
     goto on_error;

   pkey = PEM_read_PrivateKey(fp, NULL, cb, NULL);
   fclose(fp);
   if (!pkey)
     goto on_error;

   /* Load the certificate and the private key in Eet_Key structure */
   key = malloc(sizeof(Eet_Key));
   if (!key)
     goto on_error;

   key->references = 1;
   key->certificate = cert;
   key->private_key = pkey;

   return key;

on_error:
   if (cert)
     X509_free(cert);

   if (pkey)
     EVP_PKEY_free(pkey);

# endif /* ifdef HAVE_GNUTLS */
#else
   (void) certificate_file;
   (void) private_key_file;
   (void) cb;
#endif /* ifdef HAVE_SIGNATURE */
   return NULL;
}
Beispiel #11
0
static Error_Type
image_load(const char *file, const char *key, const char *shmfile,
           Slave_Msg_Image_Load *params, Slave_Msg_Image_Loaded *result,
           const char *loader)
{
   Evas_Module *module;
   Eina_File *fd;
   Evas_Image_Load_Func *funcs = NULL;
   Evas_Image_Load_Opts *opts = &params->opts;
   Evas_Image_Property property;
   Evas_Image_Animated animated;
   Error_Type ret = CSERVE2_GENERIC;
   void *loader_data = NULL;
   Eina_Bool ok;
   Eina_Stringshare *skey = NULL;
   int error;

   fd = eina_file_open(file, EINA_FALSE);
   if (!fd)
     {
        return CSERVE2_DOES_NOT_EXIST; // FIXME: maybe check errno
     }

   char *map = _cserve2_shm_map(shmfile, params->shm.mmap_size,
                                params->shm.mmap_offset);
   if (map == MAP_FAILED)
     {
        eina_file_close(fd);
        return CSERVE2_RESOURCE_ALLOCATION_FAILED;
     }

   module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
   if (!module)
     {
        printf("LOAD failed at %s:%d: no module found for loader %s\n",
               __FUNCTION__, __LINE__, loader);
        goto done;
     }

   memset(&property, 0, sizeof (property));
   property.w = params->w;
   property.h = params->h;

   skey = eina_stringshare_add(key);
   loader_data = _image_file_open(fd, skey, opts, module, &property, &animated, &funcs);
   if (!loader_data)
     {
        printf("LOAD failed at %s:%d: could not open image %s:%s\n",
               __FUNCTION__, __LINE__, file, skey);
        goto done;
     }

   ok = funcs->file_data(loader_data, &property, map, &error);
   if (!ok || (error != EVAS_LOAD_ERROR_NONE))
     {
        printf("LOAD failed at %s:%d: file_data failed for loader %s: error %d\n",
               __FUNCTION__, __LINE__, loader, error);
        goto done;
     }

   result->w = property.w;
   result->h = property.h;

   if (property.alpha)
     {
        result->alpha_sparse = evas_cserve2_image_premul_data((unsigned int *) map,
                                                              result->w * result->h);
     }

   //printf("LOAD successful: %dx%d alpha_sparse %d\n",
   //       result->w, result->h, result->alpha_sparse);

   ret = CSERVE2_NONE;

done:
   eina_file_close(fd);
   _cserve2_shm_unmap(map, params->shm.mmap_size);
   if (funcs)
     {
        if (loader_data)
          funcs->file_close(loader_data);
        evas_module_unload(module);
     }
   eina_stringshare_del(skey);

   return ret;
}
Beispiel #12
0
static Error_Type
image_open(const char *file, const char *key,
           Slave_Msg_Image_Opened *result, const char **use_loader)
{
   Evas_Module *module;
   Eina_File *fd;
   const char *loader = NULL;
   const int filelen = strlen(file);
   unsigned int i;
   Error_Type ret = CSERVE2_NONE;
   Eina_Stringshare *skey = eina_stringshare_add(key);
   Evas_Image_Load_Opts load_opts;

   memset(&load_opts, 0, sizeof(load_opts));

   fd = eina_file_open(file, EINA_FALSE);
   if (!fd)
     {
        return CSERVE2_DOES_NOT_EXIST; // FIXME: maybe check errno
     }

   if (!*use_loader)
     goto try_extension;

   loader = *use_loader;
   module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
   if (module)
     {
        if (_image_file_header(fd, skey, &load_opts, result, module))
          goto success;
     }

try_extension:
   loader = NULL;
   for (i = 0; i < sizeof(map_loaders) / sizeof(map_loaders[0]); i++)
     {
        int extlen = strlen(map_loaders[i].extension);
        if (extlen > filelen) continue;
        if (!strcasecmp(map_loaders[i].extension, file + filelen - extlen))
          {
             loader = map_loaders[i].loader;
             break;
          }
     }

   if (loader)
     {
        module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
        if (_image_file_header(fd, skey, &load_opts, result, module))
          goto success;
        loader = NULL;
        module = NULL;
     }

   // Try all known modules
   for (i = 0; i < sizeof(loaders_name) / sizeof(loaders_name[0]); i++)
     {
        loader = loaders_name[i];
        module = evas_module_find_type(EVAS_MODULE_TYPE_IMAGE_LOADER, loader);
        if (!module) continue;
        if (_image_file_header(fd, skey, &load_opts, result, module))
          goto success;
     }

   ret = CSERVE2_UNKNOWN_FORMAT;
   goto end;

success:
   ret = CSERVE2_NONE;
   *use_loader = loader;

   // FIXME: Do we really need to unload the module now?
   evas_module_unload(module);

end:
   eina_file_close(fd);
   eina_stringshare_del(skey);
   return ret;
}
Beispiel #13
0
int
main(int argc, char **argv)
{
   Eina_File *f;
   Eina_Iterator *it;
   Eina_File_Line *l;
   GeoIP *geo;
   Community_Country *country;
   unsigned long long correct = 0;
   unsigned long long lines = 0;
   int i;

   if (argc != 2) return -1;

   eina_init();

   community = eina_hash_stringshared_new(NULL);
   days = eina_hash_new(_community_day_key_length,
                             _community_day_key_cmp,
                             _community_day_key_hash,
                             NULL, 5);
   countries = eina_hash_string_superfast_new(NULL);
   geo = GeoIP_new(GEOIP_STANDARD);
   memset(months, 0, sizeof (months));

   /* Read real name country to tld file */
   f = eina_file_open("country_tld.csv", EINA_FALSE);
   if (!f) return -1;

   it = eina_file_map_lines(f);
   EINA_ITERATOR_FOREACH(it, l)
     {
        const char *s;
        int i;

        s = memchr(l->start, ',', l->length);
        if (!s) continue ;

        country = calloc(1, sizeof (Community_Country));
        country->tld = _eina_stringshare_up(l->start, s - l->start);
        country->country = _eina_stringshare_up(s + 1, l->length - (s - l->start + 1));
        country->access = eina_hash_stringshared_new(NULL);

        eina_hash_direct_add(countries, country->tld, country);
     }
   eina_iterator_free(it);
   eina_file_close(f);

   /* Read population information */
   f = eina_file_open("country_population.csv", EINA_FALSE);
   if (!f) return -1;

   it = eina_file_map_lines(f);
   EINA_ITERATOR_FOREACH(it, l)
     {
        Eina_Iterator *it2;
        const char *s;
        const char *country_name;
        const char *r;

        for (s = l->start; s < l->end; s++)
          {
             const char *convert = VIGRID_NUMBER_SEARCH;

             r = strchr(convert, *s);
             if (r) break ;
          }

        if (!r) continue;

        country = NULL;
        country_name = _eina_stringshare_up(l->start, s - l->start - 1);

        it2 = eina_hash_iterator_data_new(countries);
        EINA_ITERATOR_FOREACH(it2, country)
          {
             if (country->country == country_name)
               {
                  unsigned long long offset = s - l->start;

                  country->population = _eina_file_int_get(l, &offset);
                  break;
               }
          }
        eina_iterator_free(it2);
     }
Beispiel #14
0
static Eina_Bool
evas_image_load_file_head_ico(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error)
{
   Eina_File *f;
   void *map = NULL;
   size_t position = 0;
   unsigned short word;
   unsigned char byte;
   int wanted_w = 0, wanted_h = 0, w, h, cols, i, planes = 0,
      bpp = 0, pdelta, search = -1, have_choice = 0,
      hasa = 1;
   unsigned int bmoffset, bmsize, fsize;
   unsigned short reserved, type, count;
   struct {
      int pdelta;
      int w, h;
      int cols;
      int bpp, planes;
      int hot_x, hot_y;
      unsigned int bmoffset, bmsize;
   } chosen = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

   f = eina_file_open(file, EINA_FALSE);
   if (!f)
     {
	*error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
	return EINA_FALSE;
     }

   *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
   fsize = eina_file_size_get(f);
   if (fsize < (6 + 16 + 40)) goto close_file;

   map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL);
   if (!map) goto close_file;

   // key:
   //   NULL == highest res
   //   biggest == highest res
   //   smallest == lowest res
   //
   //   smaller == next size SMALLER than load opts WxH (if possible)
   //   bigger == next size BIGGER than load opts WxH (if possible)
   //   more ?

   search = BIGGEST;
   if ((ilp->opts.w > 0) && (ilp->opts.h > 0))
     {
        wanted_w = ilp->opts.w;
        wanted_h = ilp->opts.h;
        search = SMALLER;
     }

   if (!read_ushort(map, fsize, &position, &reserved)) goto close_file;
   if (!read_ushort(map, fsize, &position, &type)) goto close_file;
   if (!read_ushort(map, fsize, &position, &count)) goto close_file;
   if (!((reserved == 0) && 
         ((type == ICON) || (type == CURSOR)) && (count > 0)))
      goto close_file;
   *error = EVAS_LOAD_ERROR_CORRUPT_FILE;

   if (key)
     {
        if (!strcmp(key, "biggest"))
          {
             wanted_w = 0;
             wanted_h = 0;
             search = BIGGEST;
             chosen.pdelta = 0;
          }
        else if (!strcmp(key, "smallest"))
          {
             wanted_w = 1;
             wanted_h = 1;
             search = SMALLEST;
             chosen.pdelta = 0x7fffffff;
          }
        else if (!strcmp(key, "smaller"))
          {
             chosen.pdelta = 0x7fffffff;
             search = SMALLER;
          }
        else if (!strcmp(key, "bigger"))
          {
             chosen.pdelta = 0x7fffffff;
             search = BIGGER;
          }
     }
   for (i = 0; i < count; i++)
     {
        unsigned char tw = 0, th = 0, tcols = 0;
        if (!read_uchar(map, fsize, &position, &tw)) goto close_file;
        w = tw;
        if (w <= 0) w = 256;
        if (!read_uchar(map, fsize, &position, &th)) goto close_file;
        h = th;
        if (h <= 0) h = 256;
        if (!read_uchar(map, fsize, &position, &tcols)) goto close_file;
        cols = tcols;
        if (cols <= 0) cols = 256;
        if (!read_uchar(map, fsize, &position, &byte)) goto close_file;
        if (!read_ushort(map, fsize, &position, &word)) goto close_file;
        if (type == CURSOR) planes = word;
        //else hot_x = word;
        if (!read_ushort(map, fsize, &position, &word)) goto close_file;
        if (type == CURSOR) bpp = word;
        //else hot_y = word;
        if (!read_uint(map, fsize, &position, &bmsize)) goto close_file;
        if (!read_uint(map, fsize, &position, &bmoffset)) goto close_file;
        if ((bmsize <= 0) || (bmoffset <= 0) || (bmoffset >= fsize)) goto close_file;
        if (search == BIGGEST)
          {
             pdelta = w * h;
             if ((!have_choice) ||
                 ((pdelta >= chosen.pdelta) &&
                     (((bpp >= 3) && (bpp >= chosen.bpp)) ||
                         ((bpp < 3) && (cols >= chosen.cols)))))
               {
                  have_choice = 1;
                  chosen.pdelta = pdelta;
                  chosen.w = w;
                  chosen.h = h;
                  chosen.cols = cols;
                  chosen.bpp = bpp;
                  chosen.planes = planes;
                  chosen.bmsize = bmsize;
                  chosen.bmoffset = bmoffset;
               }
          }
        else
          {
             if (search == SMALLEST)
               {
                  pdelta = w * h;
                  if ((!have_choice) ||
                       ((pdelta <= chosen.pdelta) &&
                           (((bpp >= 3) && (bpp >= chosen.bpp)) ||
                               ((bpp < 3) && (cols >= chosen.cols)))))
                    {
                       have_choice = 1;
                       chosen.pdelta = pdelta;
                       chosen.w = w;
                       chosen.h = h;
                       chosen.cols = cols;
                       chosen.bpp = bpp;
                       chosen.planes = planes;
                       chosen.bmsize = bmsize;
                       chosen.bmoffset = bmoffset;
                    }
               }
             else if (search == SMALLER)
               {
                  pdelta = (wanted_w * wanted_h) - (w * h);
                  if ((!have_choice) ||
                      ((w <= wanted_w) && (h <= wanted_h) &&
                          (pdelta <= chosen.pdelta) &&
                          (((bpp >= 3) && (bpp >= chosen.bpp)) ||
                              ((bpp < 3) && (cols >= chosen.cols)))))
                     {
                        have_choice = 1;
                        if (pdelta < 0) pdelta = 0x7fffffff;
                        chosen.pdelta = pdelta;
                        chosen.w = w;
                        chosen.h = h;
                        chosen.cols = cols;
                        chosen.bpp = bpp;
                        chosen.planes = planes;
                        chosen.bmsize = bmsize;
                        chosen.bmoffset = bmoffset;
                    }
               }
             else if (search == BIGGER)
               {
                  pdelta = (w * h) - (wanted_w * wanted_h);
                  if ((!have_choice) ||
                      ((w >= wanted_w) && (h >= wanted_h) &&
                          (pdelta <= chosen.pdelta) &&
                          (((bpp >= 3) && (bpp >= chosen.bpp)) ||
                              ((bpp < 3) && (cols >= chosen.cols)))))
                     {
                        have_choice = 1;
                        if (pdelta < 0) pdelta = 0x7fffffff;
                        chosen.pdelta = pdelta;
                        chosen.w = w;
                        chosen.h = h;
                        chosen.cols = cols;
                        chosen.bpp = bpp;
                        chosen.planes = planes;
                        chosen.bmsize = bmsize;
                        chosen.bmoffset = bmoffset;
                    }
               }
          }
     }
   if (chosen.bmoffset == 0) goto close_file;
   position = chosen.bmoffset;

   w = chosen.w;
   h = chosen.h;
   if ((w > 256) || (h > 256)) goto close_file;
   if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
       IMG_TOO_BIG(w, h))
     {
        if (IMG_TOO_BIG(w, h))
           *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
        else
           *error = EVAS_LOAD_ERROR_GENERIC;
        goto close_file;
     }

   ilp->w = w;
   ilp->h = h;
   if (hasa) ilp->alpha = 1;

   eina_file_map_free(f, map);
   eina_file_close(f);

   *error = EVAS_LOAD_ERROR_NONE;
   return EINA_TRUE;

 close_file:
   if (map) eina_file_map_free(f, map);
   eina_file_close(f);
   return EINA_FALSE;
}