#include <fcntl.h>
#include <zlib.h>
-#ifndef _MSC_VER
+#ifdef HAVE_UNISTD_H
# include <unistd.h>
-#endif /* ifndef _MSC_VER */
+#endif /* ifdef HAVE_UNISTD_H */
#ifdef HAVE_NETINET_IN_H
# include <netinet/in.h>
# include <Evil.h>
#endif /* ifdef HAVE_EVIL */
+#include <Eina.h>
+
#ifdef HAVE_GNUTLS
# include <gnutls/gnutls.h>
# include <gcrypt.h>
# include <openssl/evp.h>
#endif /* ifdef HAVE_OPENSSL */
-#ifdef EFL_HAVE_POSIX_THREADS
-# include <pthread.h>
+#ifdef EINA_HAVE_THREADS
# ifdef HAVE_GNUTLS
GCRY_THREAD_OPTION_PTHREAD_IMPL;
# endif /* ifdef HAVE_GNUTLS */
-#endif /* ifdef EFL_HAVE_POSIX_THREADS */
-
-#include <Eina.h>
+#endif /* ifdef EINA_HAVE_THREADS */
#include "Eet.h"
#include "Eet_private.h"
struct _Eet_File
{
char *path;
- FILE *readfp;
+ Eina_File *readfp;
Eet_File_Header *header;
Eet_Dictionary *ed;
Eet_Key *key;
int magic;
int references;
- int data_size;
+ unsigned long int data_size;
int x509_length;
unsigned int signature_length;
int sha1_length;
- time_t mtime;
-
-#ifdef EFL_HAVE_THREADS
-# ifdef EFL_HAVE_POSIX_THREADS
- pthread_mutex_t file_lock;
-# else /* ifdef EFL_HAVE_POSIX_THREADS */
- HANDLE file_lock;
-# endif /* ifdef EFL_HAVE_POSIX_THREADS */
-#endif /* ifdef EFL_HAVE_THREADS */
+ Eina_Lock file_lock;
unsigned char writes_pending : 1;
unsigned char delete_me_now : 1;
void *data;
Eet_File_Node *next; /* FIXME: make buckets linked lists */
- int offset;
- int dictionary_offset;
- int name_offset;
+ unsigned long int offset;
+ unsigned long int dictionary_offset;
+ unsigned long int name_offset;
- int name_size;
- int size;
- int data_size;
+ unsigned int name_size;
+ unsigned int size;
+ unsigned int data_size;
unsigned char free_name : 1;
unsigned char compression : 1;
static Eet_Error eet_internal_close(Eet_File *ef, Eina_Bool locked);
-#ifdef EFL_HAVE_THREADS
-
-# ifdef EFL_HAVE_POSIX_THREADS
-
-static pthread_mutex_t eet_cache_lock = PTHREAD_MUTEX_INITIALIZER;
-
-# define LOCK_CACHE pthread_mutex_lock(&eet_cache_lock)
-# define UNLOCK_CACHE pthread_mutex_unlock(&eet_cache_lock)
-
-# define INIT_FILE(File) pthread_mutex_init(&File->file_lock, NULL)
-# define LOCK_FILE(File) pthread_mutex_lock(&File->file_lock)
-# define UNLOCK_FILE(File) pthread_mutex_unlock(&File->file_lock)
-# define DESTROY_FILE(File) pthread_mutex_destroy(&File->file_lock)
-
-# else /* EFL_HAVE_WIN32_THREADS */
-
-static HANDLE eet_cache_lock = NULL;
-
-# define LOCK_CACHE WaitForSingleObject(eet_cache_lock, INFINITE)
-# define UNLOCK_CACHE ReleaseMutex(eet_cache_lock)
-
-# define INIT_FILE(File) File->file_lock = CreateMutex(NULL, FALSE, NULL)
-# define LOCK_FILE(File) WaitForSingleObject(File->file_lock, INFINITE)
-# define UNLOCK_FILE(File) ReleaseMutex(File->file_lock)
-# define DESTROY_FILE(File) CloseHandle(File->file_lock)
+static Eina_Lock eet_cache_lock;
-# endif /* EFL_HAVE_WIN32_THREADS */
+#define LOCK_CACHE eina_lock_take(&eet_cache_lock)
+#define UNLOCK_CACHE eina_lock_release(&eet_cache_lock)
-#else /* ifdef EFL_HAVE_THREADS */
-
-# define LOCK_CACHE do {} while (0)
-# define UNLOCK_CACHE do {} while (0)
-
-# define INIT_FILE(File) do {} while (0)
-# define LOCK_FILE(File) do {} while (0)
-# define UNLOCK_FILE(File) do {} while (0)
-# define DESTROY_FILE(File) do {} while (0)
-
-#endif /* EFL_HAVE_THREADS */
+#define INIT_FILE(File) eina_lock_new(&File->file_lock)
+#define LOCK_FILE(File) eina_lock_take(&File->file_lock)
+#define UNLOCK_FILE(File) eina_lock_release(&File->file_lock)
+#define DESTROY_FILE(File) eina_lock_free(&File->file_lock)
/* cache. i don't expect this to ever be large, so arrays will do */
static int eet_writers_num = 0;
goto shutdown_eina;
}
+ eina_lock_new(&eet_cache_lock);
+
if (!eet_node_init())
{
EINA_LOG_ERR("Eet: Eet_Node mempool creation failed");
"BIG FAT WARNING: I AM UNABLE TO REQUEST SECMEM, Cryptographic operation are at risk !");
}
-# ifdef EFL_HAVE_POSIX_THREADS
+# ifdef EINA_HAVE_THREADS
if (gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread))
WRN(
"YOU ARE USING PTHREADS, BUT I CANNOT INITIALIZE THREADSAFE GCRYPT OPERATIONS!");
-# endif /* ifdef EFL_HAVE_POSIX_THREADS */
+# endif /* ifdef EINA_HAVE_THREADS */
if (gnutls_global_init())
goto shutdown_eet;
#ifdef HAVE_GNUTLS
shutdown_eet:
-#endif
+#endif
eet_node_shutdown();
unregister_log_domain:
eina_log_domain_unregister(_eet_log_dom_global);
eet_clearcache();
eet_node_shutdown();
+
+ eina_lock_free(&eet_cache_lock);
+
#ifdef HAVE_GNUTLS
gnutls_global_deinit();
#endif /* ifdef HAVE_GNUTLS */
const int *data = (const int *)ef->data;
const char *start = (const char *)ef->data;
int idx = 0;
- int num_directory_entries;
- int bytes_directory_entries;
- int num_dictionary_entries;
- int bytes_dictionary_entries;
- int signature_base_offset;
- int i;
+ unsigned long int bytes_directory_entries;
+ unsigned long int bytes_dictionary_entries;
+ unsigned long int signature_base_offset;
+ unsigned long int num_directory_entries;
+ unsigned long int num_dictionary_entries;
+ unsigned int i;
idx += sizeof(int);
if (eet_test_close((int)ntohl(*data) != EET_MAGIC_FILE2, ef))
{
const char *name;
Eet_File_Node *efn;
- int name_offset;
- int name_size;
+ unsigned long int name_offset;
+ unsigned long int name_size;
int hash;
int flag;
for (j = 0; j < ef->ed->count; ++j)
{
+ unsigned int offset;
int hash;
- int offset;
GET_INT(hash, dico, idx);
GET_INT(offset, dico, idx);
{
const unsigned char *dyn_buf = NULL;
const unsigned char *p = NULL;
+ unsigned long int byte_entries;
+ unsigned long int num_entries;
+ unsigned int i;
int idx = 0;
- int num_entries;
- int byte_entries;
- int i;
WRN(
"EET file format of '%s' is deprecated. You should just open it one time with mode == EET_FILE_MODE_READ_WRITE to solve this issue.",
ef->references--;
/* if its still referenced - dont go any further */
if (ef->references > 0)
- goto on_error; /* flush any writes */
+ {
+ /* flush any writes */
+ if ((ef->mode == EET_FILE_MODE_WRITE) ||
+ (ef->mode == EET_FILE_MODE_READ_WRITE))
+ eet_sync(ef);
+ goto on_error;
+ }
err = eet_flush2(ef);
if (ef->mode == EET_FILE_MODE_READ)
eet_cache_del(ef, &eet_readers, &eet_readers_num, &eet_readers_alloc);
else if ((ef->mode == EET_FILE_MODE_WRITE) ||
- (
- ef
- ->
- mode == EET_FILE_MODE_READ_WRITE))
+ (ef->mode == EET_FILE_MODE_READ_WRITE))
eet_cache_del(ef, &eet_writers, &eet_writers_num, &eet_writers_alloc);
/* we can unlock the cache now */
eet_dictionary_free(ef->ed);
if (ef->sha1)
- free(ef->sha1);
-
- if (ef->data)
- munmap((void *)ef->data, ef->data_size);
+ free(ef->sha1);
if (ef->readfp)
- fclose(ef->readfp);
+ {
+ if (ef->data)
+ eina_file_map_free(ef->readfp, (void *) ef->data);
+
+ eina_file_close(ef->readfp);
+ }
/* zero out ram for struct - caution tactic against stale memory use */
memset(ef, 0, sizeof(Eet_File));
ef->references = 1;
ef->mode = EET_FILE_MODE_READ;
ef->header = NULL;
- ef->mtime = 0;
ef->delete_me_now = 1;
ef->readfp = NULL;
ef->data = data;
eet_open(const char *file,
Eet_File_Mode mode)
{
- FILE *fp;
+ Eina_File *fp;
Eet_File *ef;
int file_len;
- struct stat file_stat;
+ unsigned long int size;
if (!file)
return NULL;
if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE))
{
/* Prevent garbage in futur comparison. */
- file_stat.st_mtime = 0;
-
- fp = fopen(file, "rb");
+ fp = eina_file_open(file, EINA_FALSE);
if (!fp)
goto open_error;
- if (fstat(fileno(fp), &file_stat))
- {
- fclose(fp);
- fp = NULL;
-
- memset(&file_stat, 0, sizeof(file_stat));
+ size = eina_file_size_get(fp);
- goto open_error;
- }
-
- if (file_stat.st_size < ((int)sizeof(int) * 3))
+ if (size < ((int)sizeof(int) * 3))
{
- fclose(fp);
+ eina_file_close(fp);
fp = NULL;
- memset(&file_stat, 0, sizeof(file_stat));
+ size = 0;
goto open_error;
}
if (mode != EET_FILE_MODE_WRITE)
return NULL;
- memset(&file_stat, 0, sizeof(file_stat));
+ size = 0;
fp = NULL;
}
/* We found one */
- if (ef &&
- ((file_stat.st_mtime != ef->mtime) ||
- (file_stat.st_size != ef->data_size)))
+ if (ef && ef->readfp != fp)
{
ef->delete_me_now = 1;
ef->references++;
{
/* reference it up and return it */
if (fp)
- fclose(fp);
+ eina_file_close(fp);
ef->references++;
UNLOCK_CACHE;
ef->references = 1;
ef->mode = mode;
ef->header = NULL;
- ef->mtime = file_stat.st_mtime;
ef->writes_pending = 0;
ef->delete_me_now = 0;
ef->data = NULL;
if (eet_test_close(!ef->readfp, ef))
goto on_error;
- fcntl(fileno(ef->readfp), F_SETFD, FD_CLOEXEC);
/* if we opened for read or read-write */
if ((mode == EET_FILE_MODE_READ) || (mode == EET_FILE_MODE_READ_WRITE))
{
- ef->data_size = file_stat.st_size;
- ef->data = mmap(NULL, ef->data_size, PROT_READ,
- MAP_SHARED, fileno(ef->readfp), 0);
- if (eet_test_close((ef->data == MAP_FAILED), ef))
+ ef->data_size = size;
+ ef->data = eina_file_map_all(fp, EINA_FILE_SEQUENTIAL);
+ if (eet_test_close((ef->data == NULL), ef))
goto on_error;
ef = eet_internal_read(ef);
if (ef->references == 1)
{
if (ef->mode == EET_FILE_MODE_READ)
- eet_cache_add(ef, &eet_readers, &eet_readers_num, &eet_readers_alloc);
- else
- if ((ef->mode == EET_FILE_MODE_WRITE) ||
- (ef->mode == EET_FILE_MODE_READ_WRITE))
- eet_cache_add(ef, &eet_writers, &eet_writers_num, &eet_writers_alloc);
+ eet_cache_add(ef, &eet_readers, &eet_readers_num, &eet_readers_alloc);
+ else if ((ef->mode == EET_FILE_MODE_WRITE) ||
+ (ef->mode == EET_FILE_MODE_READ_WRITE))
+ eet_cache_add(ef, &eet_writers, &eet_writers_num, &eet_writers_alloc);
}
UNLOCK_CACHE;
{
Eet_File_Node *efn;
char *data = NULL;
- int size = 0;
+ unsigned long int size = 0;
if (size_ret)
*size_ret = 0;
if (!efn)
goto on_error;
- if (efn->offset < 0 && !efn->data)
+ /* trick to detect data in memory instead of mmaped from disk */
+ if (efn->offset > ef->data_size && !efn->data)
goto on_error;
/* get size (uncompressed, if compressed at all) */
efn->size = data_size;
efn->data_size = strlen(destination) + 1;
efn->data = data2;
- efn->offset = -1;
+ /* Put the offset above the limit to avoid direct access */
+ efn->offset = ef->data_size + 1;
exists_already = EINA_TRUE;
+
break;
}
}
efn->next = ef->header->directory->nodes[hash];
ef->header->directory->nodes[hash] = efn;
- efn->offset = -1;
+ /* Put the offset above the limit to avoid direct access */
+ efn->offset = ef->data_size + 1;
efn->alias = 1;
efn->ciphered = 0;
efn->compression = !!comp;
efn->size = data_size;
efn->data_size = size;
efn->data = data2;
- efn->offset = -1;
+ /* Put the offset above the limit to avoid direct access */
+ efn->offset = ef->data_size + 1;
exists_already = 1;
break;
}
efn->next = ef->header->directory->nodes[hash];
ef->header->directory->nodes[hash] = efn;
- efn->offset = -1;
+ /* Put the offset above the limit to avoid direct access */
+ efn->offset = ef->data_size + 1;
efn->alias = 0;
efn->ciphered = cipher_key ? 1 : 0;
efn->compression = !!comp;
void *buf,
int len)
{
- if (efn->offset < 0)
+ if (efn->offset > ef->data_size)
return 0;
- if (ef->data)
- {
- if ((efn->offset + len) > ef->data_size)
- return 0;
-
- memcpy(buf, ef->data + efn->offset, len);
- }
- else
- {
- if (!ef->readfp)
- return 0;
+ if (!ef->data)
+ return 0;
- /* seek to data location */
- if (fseek(ef->readfp, efn->offset, SEEK_SET) < 0)
- return 0;
+ if ((efn->offset + len) > ef->data_size)
+ return 0;
- /* read it */
- len = fread(buf, len, 1, ef->readfp);
- }
+ memcpy(buf, ef->data + efn->offset, len);
return len;
} /* read_data_from_disk */