forked from enlightenment/efl
parent
d279771011
commit
018b1cae14
|
@ -1,6 +1,6 @@
|
|||
rm -f config.cache
|
||||
|
||||
AC_INIT(efreet, 0.5.0.043, enlightenment-devel@lists.sourceforge.net)
|
||||
AC_INIT(efreet, 0.5.0.044, enlightenment-devel@lists.sourceforge.net)
|
||||
AC_PREREQ(2.52)
|
||||
AC_CONFIG_SRCDIR(configure.in)
|
||||
AC_CANONICAL_BUILD
|
||||
|
@ -69,6 +69,7 @@ AC_OUTPUT([
|
|||
efreet.spec
|
||||
efreet.pc
|
||||
efreet-mime.pc
|
||||
efreet-trash.pc
|
||||
Makefile
|
||||
src/Makefile
|
||||
src/lib/Makefile
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
<table border="0" cellpadding="0" cellspacing="4px">
|
||||
<tr>
|
||||
<td class='nav'><a class='nav' href="index.html">Main Page</a></td>
|
||||
<td class='nav'><a class='nav' href="modules.html">Modules</a></td>
|
||||
<td class="nav"><a class="nav" href="annotated.html">Data Structures</a></td>
|
||||
<td class="nav"><a class="nav" href="classes.html">Index</a></td>
|
||||
</tr>
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
prefix=@prefix@
|
||||
exec_prefix=@exec_prefix@
|
||||
libdir=@libdir@
|
||||
includedir=@includedir@
|
||||
|
||||
Name: efreet-trash
|
||||
Description: Freedesktop Shared Trash implementation for the EFL
|
||||
Requires: @requirements@
|
||||
Version: @VERSION@
|
||||
Libs: -L${libdir} -lefreet_trash
|
||||
Cflags: -I${includedir}/efreet
|
|
@ -0,0 +1,82 @@
|
|||
/* vim: set sw=4 ts=4 sts=4 et: */
|
||||
#ifndef EFREET_TRASH_H
|
||||
#define EFREET_TRASH_H
|
||||
|
||||
/**
|
||||
* @file efreet_trash.h
|
||||
* @brief Contains the methods used to support the FDO trash specification.
|
||||
* @addtogroup Efreet_Trash Efreet_Trash: The XDG Trash Specification
|
||||
* Some better explanation here...
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef EAPI
|
||||
#undef EAPI
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
# ifdef BUILDING_DLL
|
||||
# define EAPI __declspec(dllexport)
|
||||
# else
|
||||
# define EAPI __declspec(dllimport)
|
||||
# endif
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# if __GNUC__ >= 4
|
||||
# define EAPI __attribute__ ((visibility("default")))
|
||||
# else
|
||||
# define EAPI
|
||||
# endif
|
||||
# else
|
||||
# define EAPI
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Efreet_Uri
|
||||
*/
|
||||
typedef struct Efreet_Uri Efreet_Uri;
|
||||
|
||||
/**
|
||||
* Efreet_Uri
|
||||
* @brief Contains a simple rappresentation of an uri. The string don't have
|
||||
* special chars escaped.
|
||||
*/
|
||||
struct Efreet_Uri
|
||||
{
|
||||
const char *protocol; /**< The name of the host if any, or NULL */
|
||||
const char *hostname; /**< The name of the host if any, or NULL */
|
||||
const char *path; /**< The full file path whitout protocol nor host*/
|
||||
};
|
||||
|
||||
|
||||
EAPI const char *efreet_uri_escape(Efreet_Uri *uri);
|
||||
EAPI Efreet_Uri *efreet_uri_parse(const char *val);
|
||||
EAPI void efreet_uri_free(Efreet_Uri *uri);
|
||||
|
||||
EAPI int efreet_trash_init(void);
|
||||
EAPI void efreet_trash_shutdown(void);
|
||||
|
||||
EAPI const char *efreet_trash_dir_get(void);
|
||||
EAPI int efreet_trash_delete_uri(Efreet_Uri *uri, int force_delete);
|
||||
EAPI Ecore_List *efreet_trash_ls(void);
|
||||
EAPI int efreet_trash_is_empty(void);
|
||||
EAPI int efreet_trash_empty_trash(void);
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -6,7 +6,7 @@ AM_CPPFLAGS = \
|
|||
-I$(top_srcdir) \
|
||||
@ECORE_CFLAGS@
|
||||
|
||||
lib_LTLIBRARIES = libefreet.la libefreet_mime.la
|
||||
lib_LTLIBRARIES = libefreet.la libefreet_mime.la libefreet_trash.la
|
||||
|
||||
EFREETHEADERS = \
|
||||
Efreet.h \
|
||||
|
@ -43,10 +43,23 @@ $(EFREETMIMEHEADERS)
|
|||
libefreet_mime_la_SOURCES = \
|
||||
$(EFREETMIMESOURCES)
|
||||
|
||||
|
||||
EFREETTRASHHEADERS = \
|
||||
Efreet_Trash.h
|
||||
|
||||
EFREETTRASHSOURCES = \
|
||||
efreet_trash.c \
|
||||
$(EFREETTRASHHEADERS)
|
||||
|
||||
libefreet_trash_la_SOURCES = \
|
||||
$(EFREETTRASHSOURCES)
|
||||
|
||||
|
||||
installed_headersdir = $(prefix)/include/efreet
|
||||
installed_headers_DATA = $(EFREETHEADERS) $(EFREETMIMEHEADERS)
|
||||
installed_headers_DATA = $(EFREETHEADERS) $(EFREETMIMEHEADERS) $(EFREETTRASHHEADERS)
|
||||
|
||||
libefreet_la_LIBADD = @ECORE_LIBS@
|
||||
libefreet_la_LDFLAGS = -version-info @version_info@
|
||||
|
||||
libefreet_mime_la_LIBADD = @ECORE_LIBS@ libefreet.la
|
||||
libefreet_trash_la_LIBADD = @ECORE_LIBS@ libefreet.la
|
||||
|
|
|
@ -0,0 +1,316 @@
|
|||
/* vim: set sw=4 ts=4 sts=4 et: */
|
||||
#include <errno.h>
|
||||
#include <time.h>
|
||||
#include "Efreet.h"
|
||||
#include "Efreet_Trash.h"
|
||||
#include "efreet_private.h"
|
||||
|
||||
static const char *efreet_trash_dir = NULL;
|
||||
|
||||
/**
|
||||
* @return Returns 1 on success or 0 on failure
|
||||
* @brief Initializes the efreet trash system
|
||||
*/
|
||||
EAPI int
|
||||
efreet_trash_init(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns no value
|
||||
* @brief Cleans up the efreet trash system
|
||||
*/
|
||||
EAPI void
|
||||
efreet_trash_shutdown(void)
|
||||
{
|
||||
IF_RELEASE(efreet_trash_dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the XDG Trash local directory or NULL on errors
|
||||
* @brief Retrieves the XDG Trash local directory
|
||||
*/
|
||||
EAPI const char*
|
||||
efreet_trash_dir_get(void)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
|
||||
if (efreet_trash_dir && ecore_file_exists(efreet_trash_dir))
|
||||
return efreet_trash_dir;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/Trash", efreet_data_home_get());
|
||||
if (!ecore_file_exists(buf) && !ecore_file_mkpath(buf))
|
||||
return NULL;
|
||||
|
||||
IF_RELEASE(efreet_trash_dir);
|
||||
efreet_trash_dir = ecore_string_instance(buf);
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/files", efreet_trash_dir);
|
||||
if (!ecore_file_exists(buf) && !ecore_file_mkpath(buf))
|
||||
return NULL;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/info", efreet_trash_dir);
|
||||
if (!ecore_file_exists(buf) && !ecore_file_mkpath(buf))
|
||||
return NULL;
|
||||
|
||||
return efreet_trash_dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri: The local uri to move in the trash
|
||||
* @param force_delete: If you set this to 1 than files on different filesystems
|
||||
* will be deleted permanently
|
||||
* @return Return 1 on success, 0 on failure or -1 in case the uri is not on the
|
||||
* same filesystem and force_delete is not set.
|
||||
* @brief This function try to move the given uri to the trash. Files on
|
||||
* different filesystem can't be moved to trash. If force_delete
|
||||
* is 0 than non-local files will be ignored and -1 is returned, if you set
|
||||
* force_delete to 1 non-local files will be deleted without asking.
|
||||
*/
|
||||
EAPI int
|
||||
efreet_trash_delete_uri(Efreet_Uri *uri, int force_delete)
|
||||
{
|
||||
char dest[PATH_MAX];
|
||||
char times[64];
|
||||
const char *fname;
|
||||
const char *escaped;
|
||||
int i = 1;
|
||||
time_t now;
|
||||
FILE *f;
|
||||
|
||||
if (!uri || !uri->path || !ecore_file_can_write(uri->path)) return 0;
|
||||
|
||||
fname = ecore_file_file_get(uri->path);
|
||||
snprintf(dest, PATH_MAX, "%s/files/%s", efreet_trash_dir_get(), fname);
|
||||
|
||||
/* search for a free filename */
|
||||
while (ecore_file_exists(dest))
|
||||
snprintf(dest, PATH_MAX, "%s/files/%s$%d",
|
||||
efreet_trash_dir_get(), fname, i++);
|
||||
fname = ecore_file_file_get(dest);
|
||||
|
||||
/* move file to trash dir */
|
||||
if (rename(uri->path, dest))
|
||||
{
|
||||
if (errno == EXDEV)
|
||||
{
|
||||
if (!force_delete) return -1;
|
||||
if (!ecore_file_recursive_rm(uri->path))
|
||||
{
|
||||
printf("EFREET TRASH ERROR: Can't delete file.\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("EFREET TRASH ERROR: Can't move file to trash.\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* create info file */
|
||||
snprintf(dest, PATH_MAX, "%s/info/%s.trashinfo",
|
||||
efreet_trash_dir_get(), fname);
|
||||
|
||||
if (f = fopen(dest, "w"))
|
||||
{
|
||||
fputs("[Trash Info]\n", f); //TODO is '\n' right?? (or \r\c??)
|
||||
|
||||
fputs("Path=", f);
|
||||
escaped = efreet_uri_escape(uri);
|
||||
fputs(escaped + 7, f); // +7 == don't write 'file://'
|
||||
IF_RELEASE(escaped);
|
||||
|
||||
time(&now);
|
||||
strftime(times, sizeof(times), "%Y-%m-%dT%H:%M:%S", localtime(&now));
|
||||
fputs("\nDeletionDate=", f);
|
||||
fputs(times, f);
|
||||
fputs("\n", f);
|
||||
fclose(f);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("EFREET TRASH ERROR: Can't create trash info file.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Return 1 if the trash is empty or 0 if some file are in.
|
||||
* @brief Check if the trash is currently empty
|
||||
*/
|
||||
EAPI int
|
||||
efreet_trash_is_empty(void)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
snprintf(buf, PATH_MAX, "%s/files", efreet_trash_dir_get());
|
||||
|
||||
/* TODO Check also trash in other filesystems */
|
||||
return ecore_file_dir_is_empty(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Return 1 on success or 0 on failure
|
||||
* @brief Delete all the files inside the trash.
|
||||
*/
|
||||
EAPI int
|
||||
efreet_trash_empty_trash(void)
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
|
||||
snprintf(buf, PATH_MAX, "%s/info", efreet_trash_dir_get());
|
||||
if (!ecore_file_recursive_rm(buf)) return 0;
|
||||
ecore_file_mkdir(buf);
|
||||
|
||||
snprintf(buf, PATH_MAX, "%s/files", efreet_trash_dir_get());
|
||||
if (!ecore_file_recursive_rm(buf)) return 0;
|
||||
ecore_file_mkdir(buf);
|
||||
|
||||
/* TODO Empty also trash in other filesystems */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Return a list of strings with filename (remember to free the list
|
||||
* when you don't need anymore)
|
||||
* @brief List all the files and directory currently inside the trash.
|
||||
*/
|
||||
EAPI Ecore_List*
|
||||
efreet_trash_ls(void)
|
||||
{
|
||||
char *infofile;
|
||||
char buf[PATH_MAX];
|
||||
Ecore_List *files;
|
||||
|
||||
// NOTE THIS FUNCTION NOW IS NOT COMPLETE AS I DON'T NEED IT
|
||||
// TODO read the name from the infofile instead of the filename
|
||||
|
||||
snprintf(buf, PATH_MAX, "%s/files", efreet_trash_dir_get());
|
||||
files = ecore_file_ls(buf);
|
||||
|
||||
while (infofile = ecore_list_next(files))
|
||||
{
|
||||
printf("FILE: %s\n", infofile);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param val: a valid uri string to parse
|
||||
* @return Return The corresponding Efreet_Uri structure. Or NULL on errors.
|
||||
* @brief Parse a single uri and return an Efreet_Uri struct. If there's no
|
||||
* hostname in the uri then the hostname parameter is NULL. All the uri escaped
|
||||
* chars will be converted back.
|
||||
*/
|
||||
EAPI Efreet_Uri *
|
||||
efreet_uri_parse(const char *val)
|
||||
{
|
||||
Efreet_Uri *uri;
|
||||
const char *p;
|
||||
char protocol[64], hostname[_POSIX_HOST_NAME_MAX], path[PATH_MAX];
|
||||
int i = 0;
|
||||
|
||||
/* An uri should be in the form <protocol>://<hostname>/<path> */
|
||||
p = strstr(val, "://");
|
||||
if (!p) return NULL;
|
||||
|
||||
memset(protocol, 0, 64);
|
||||
memset(hostname, 0, _POSIX_HOST_NAME_MAX);
|
||||
memset(path, 0, PATH_MAX);
|
||||
|
||||
/* parse protocol */
|
||||
p = val;
|
||||
for (i = 0; *p != ':' && *p != '\0' && i < 64; p++, i++)
|
||||
protocol[i] = *p;
|
||||
protocol[i] = '\0';
|
||||
|
||||
/* parse hostname */
|
||||
p += 3;
|
||||
if (*p != '/')
|
||||
{
|
||||
for (i = 0; *p != '/' && *p != '\0' && i < _POSIX_HOST_NAME_MAX; p++, i++)
|
||||
hostname[i] = *p;
|
||||
hostname[i] = '\0';
|
||||
}
|
||||
else
|
||||
hostname[0] = '\0';
|
||||
|
||||
/* parse path */
|
||||
/* See http://www.faqs.org/rfcs/rfc1738.html for the escaped chars */
|
||||
for (i = 0; *p != '\0' && i < PATH_MAX; i++, p++)
|
||||
{
|
||||
if (*p == '%')
|
||||
{
|
||||
path[i] = *(++p);
|
||||
path[i + 1] = *(++p);
|
||||
path[i] = (char)strtol(&(path[i]), NULL, 16);
|
||||
path[i + 1] = '\0';
|
||||
}
|
||||
else
|
||||
path[i] = *p;
|
||||
}
|
||||
|
||||
uri = NEW(Efreet_Uri, 1);
|
||||
if (!uri) return NULL;
|
||||
|
||||
uri->protocol = ecore_string_instance(protocol);
|
||||
uri->hostname = ecore_string_instance(hostname);
|
||||
uri->path = ecore_string_instance(path);
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri: The uri structure to escape
|
||||
* @return The string rapresentation of an uri (ex: 'file:///home/my%20name')
|
||||
* @brief Get the string rapresentation of the given uri struct escaping
|
||||
* illegal caracters. The resulting string will contain the protocol but not the
|
||||
* hostname, as many apps doesn't handle it.
|
||||
*/
|
||||
EAPI const char *
|
||||
efreet_uri_escape(Efreet_Uri *uri)
|
||||
{
|
||||
char dest[PATH_MAX * 3 + 4];
|
||||
const char *p;
|
||||
int i;
|
||||
|
||||
if (!uri || !uri->path || !uri->protocol) return NULL;
|
||||
memset(dest, 0, PATH_MAX * 3 + 4);
|
||||
snprintf(dest, strlen(uri->protocol) + 4, "%s://", uri->protocol);
|
||||
|
||||
|
||||
/* Most app doesn't handle the hostname in the uri so it's put to NULL */
|
||||
for (i = strlen(uri->protocol) + 3, p = uri->path; *p != '\0'; p++, i++)
|
||||
{
|
||||
if (isalnum(*p) || strchr("/$-_.+!*'()", *p))
|
||||
dest[i] = *p;
|
||||
else
|
||||
{
|
||||
snprintf(&(dest[i]), 4, "%%%02X", *p);
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
return ecore_string_instance(dest);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param uri: The uri to free
|
||||
* @brief Free the given uri structure.
|
||||
*/
|
||||
EAPI void
|
||||
efreet_uri_free(Efreet_Uri *uri)
|
||||
{
|
||||
if (!uri) return;
|
||||
IF_RELEASE(uri->protocol);
|
||||
IF_RELEASE(uri->path);
|
||||
IF_RELEASE(uri->hostname);
|
||||
free(uri);
|
||||
uri = NULL;
|
||||
}
|
Loading…
Reference in New Issue