307 lines
8.6 KiB
C
307 lines
8.6 KiB
C
#include "mrklib_priv.h"
|
|
|
|
static int
|
|
write_file(Eet_File *ef, const char *key, const char *file)
|
|
{
|
|
FILE *f;
|
|
void *mem;
|
|
int size;
|
|
char *s;
|
|
|
|
mem = eet_read(ef, key, &size);
|
|
if (mem)
|
|
{
|
|
s = ecore_file_dir_get(file);
|
|
if (s)
|
|
{
|
|
ecore_file_mkpath(s);
|
|
free(s);
|
|
}
|
|
f = fopen(file, "wb");
|
|
if (f)
|
|
{
|
|
fwrite(mem, size, 1, f);
|
|
fclose(f);
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
mrk_package_src_extract(const char *file, const char *dst)
|
|
{
|
|
Eet_File *ef = NULL;
|
|
char tmp[4096];
|
|
|
|
ef = eet_open(file, EET_FILE_MODE_READ);
|
|
if (ef)
|
|
{
|
|
int i, num = 0;
|
|
char **keys = eet_list(ef, "src/*", &num);
|
|
|
|
if (keys)
|
|
{
|
|
for (i = 0; i < num; i++)
|
|
{
|
|
if (!strncmp(keys[i], "src/", 4))
|
|
{
|
|
if (!_mrk_util_plain_path_check(&(keys[i][4])))
|
|
continue;
|
|
snprintf(tmp, sizeof(tmp), "%s/%s", dst, &(keys[i][4]));
|
|
if (!write_file(ef, keys[i], tmp))
|
|
{
|
|
free(keys);
|
|
goto error;
|
|
}
|
|
}
|
|
}
|
|
free(keys);
|
|
}
|
|
snprintf(tmp, sizeof(tmp), "%s/%s", dst, "Marrakesh.mrk");
|
|
if (!write_file(ef, "buildinfo", tmp)) goto error;
|
|
eet_close(ef);
|
|
return EINA_TRUE;
|
|
}
|
|
error:
|
|
if (ef) eet_close(ef);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
static char *
|
|
read_string(Eet_File *ef, const char *key)
|
|
{
|
|
int size = 0;
|
|
char *str;
|
|
char *s = eet_read(ef, key, &size);
|
|
if (!s) return NULL;
|
|
str = malloc(size + 1);
|
|
if (!str)
|
|
{
|
|
free(s);
|
|
return NULL;
|
|
}
|
|
memcpy(str, s, size);
|
|
str[size] = 0;
|
|
free(s);
|
|
return str;
|
|
}
|
|
|
|
static void
|
|
clean_symlinks(const char *dir)
|
|
{
|
|
Eina_List *files;
|
|
char *s, *ss;
|
|
char tmp[4096];
|
|
|
|
files = ecore_file_ls(dir);
|
|
EINA_LIST_FREE(files, s)
|
|
{
|
|
snprintf(tmp, sizeof(tmp), "%s/%s", dir, s);
|
|
ss = ecore_file_readlink(tmp);
|
|
if (ss)
|
|
{
|
|
free(ss);
|
|
if (!ecore_file_exists(tmp))
|
|
{
|
|
printf("clean '%s'\n", tmp);
|
|
ecore_file_unlink(tmp);
|
|
}
|
|
}
|
|
free(s);
|
|
}
|
|
}
|
|
|
|
static int
|
|
field_copy(Eet_File *ef, Eet_File *ef2, const char *key)
|
|
{
|
|
int size = 0;
|
|
char *s = eet_read(ef, key, &size);
|
|
if (s)
|
|
{
|
|
eet_write(ef2, key, s, size, EET_COMPRESSION_VERYFAST);
|
|
free(s);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static const char *
|
|
get_home(void)
|
|
{
|
|
static char buf[4096] = "";
|
|
const char *tmps, *home;
|
|
|
|
if (buf[0]) return buf;
|
|
tmps = getenv("XDG_DATA_HOME");
|
|
home = getenv("HOME");
|
|
if (!home) home = "/tmp";
|
|
if (tmps) snprintf(buf, sizeof(buf), "%s", tmps);
|
|
else snprintf(buf, sizeof(buf), "%s", home);
|
|
return buf;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
mrk_package_bin_clean(void)
|
|
{
|
|
char tmp[4096];
|
|
|
|
snprintf(tmp, sizeof(tmp), "%s/.local/share/icons", get_home());
|
|
clean_symlinks(tmp);
|
|
snprintf(tmp, sizeof(tmp), "%s/.local/share/applications", get_home());
|
|
clean_symlinks(tmp);
|
|
snprintf(tmp, sizeof(tmp), "%s/Applications/.bin", get_home());
|
|
clean_symlinks(tmp);
|
|
return 1;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
mrk_package_verify(const char *file, const char *key_cert_file)
|
|
{
|
|
Eet_File *ef;
|
|
Eina_Bool ok = EINA_FALSE;
|
|
|
|
ef = eet_open(file, EET_FILE_MODE_READ);
|
|
if (!ef) return EINA_FALSE;
|
|
if (eet_identity_verify(ef, key_cert_file)) ok = EINA_TRUE;
|
|
eet_close(ef);
|
|
return ok;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
mrk_package_bin_install(const char *file, const char *os, const char *arch)
|
|
{
|
|
Eet_File *ef, *ef2;
|
|
#define err(reason) do { fprintf(stderr, "%s\n", reason); goto error; } while (0)
|
|
|
|
ef = eet_open(file, EET_FILE_MODE_READ);
|
|
if (ef)
|
|
{
|
|
int i, num = 0;
|
|
char **keys = eet_list(ef, "bin/*", &num);
|
|
char inst[4096];
|
|
char dir[4096];
|
|
char tmp[4096];
|
|
char tmp2[4096];
|
|
char *s;
|
|
Eina_List *files;
|
|
char *name;
|
|
char *str;
|
|
|
|
str = read_string(ef, "arch");
|
|
if (!str) err("no arch");
|
|
snprintf(tmp, sizeof(tmp), "%s-%s", os, arch);
|
|
if (strcmp(tmp, str))
|
|
{
|
|
free(str);
|
|
err("arch mismatch\n");
|
|
}
|
|
free(str);
|
|
name = read_string(ef, "name");
|
|
if (!name) err("no name");
|
|
if (!_mrk_util_plain_file_check(name)) err("name failed sanity check");
|
|
snprintf(tmp, sizeof(tmp), "%s/Applications/.bin", get_home());
|
|
ecore_file_mkpath(tmp);
|
|
snprintf(inst, sizeof(inst), "%s/Applications/%s", get_home(), name);
|
|
if (ecore_file_exists(inst)) err("destination already exists");
|
|
ecore_file_mkpath(inst);
|
|
if (keys)
|
|
{
|
|
for (i = 0; i < num; i++)
|
|
{
|
|
if (!strncmp(keys[i], "bin/", 4))
|
|
{
|
|
if (!_mrk_util_plain_path_check(&(keys[i][6]))) continue;
|
|
snprintf(tmp, sizeof(tmp), "%s/%s", inst, &(keys[i][6]));
|
|
write_file(ef, keys[i], tmp);
|
|
if (keys[i][4] == 'X')
|
|
{
|
|
printf("+x '%s'\n", &(keys[i][6]));
|
|
chmod(tmp, 00500);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
snprintf(dir, sizeof(dir), "%s/share/icons", inst);
|
|
files = ecore_file_ls(dir);
|
|
EINA_LIST_FREE(files, s)
|
|
{
|
|
if (!strcmp(s, ".")) continue;
|
|
else if (!strcmp(s, "..")) continue;
|
|
snprintf(tmp, sizeof(tmp), "../../../Applications/%s/share/icons/%s", name, s);
|
|
snprintf(tmp2, sizeof(tmp2), "%s/.local/share/icons/%s", get_home(), s);
|
|
if (ecore_file_exists(tmp2)) err("icon file symlink already exists");
|
|
ecore_file_symlink(tmp, tmp2);
|
|
free(s);
|
|
}
|
|
snprintf(dir, sizeof(dir), "%s/share/applications", inst);
|
|
files = ecore_file_ls(dir);
|
|
EINA_LIST_FREE(files, s)
|
|
{
|
|
if (!strcmp(s, ".")) continue;
|
|
else if (!strcmp(s, "..")) continue;
|
|
snprintf(tmp, sizeof(tmp), "../../../Applications/%s/share/applications/%s", name, s);
|
|
snprintf(tmp2, sizeof(tmp2), "%s/.local/share/applications/%s", get_home(), s);
|
|
if (ecore_file_exists(tmp2)) err("desktop file symlink already exists");
|
|
ecore_file_symlink(tmp, tmp2);
|
|
free(s);
|
|
}
|
|
snprintf(dir, sizeof(dir), "%s/bin", inst);
|
|
files = ecore_file_ls(dir);
|
|
EINA_LIST_FREE(files, s)
|
|
{
|
|
if (!strcmp(s, ".")) continue;
|
|
else if (!strcmp(s, "..")) continue;
|
|
snprintf(tmp, sizeof(tmp), "../%s/bin/%s", name, s);
|
|
snprintf(tmp2, sizeof(tmp2), "%s/Applications/.bin/%s", get_home(), s);
|
|
if (ecore_file_exists(tmp2)) err("bin file symlink already exists");
|
|
ecore_file_symlink(tmp, tmp2);
|
|
free(s);
|
|
}
|
|
snprintf(tmp, sizeof(tmp), "%s/Applications/%s/.icon.png", get_home(), name);
|
|
write_file(ef, "icon", tmp);
|
|
snprintf(tmp, sizeof(tmp), "%s/Applications/%s/.splash.png", get_home(), name);
|
|
write_file(ef, "splash", tmp);
|
|
snprintf(tmp, sizeof(tmp), "%s/Applications/%s/.info.mki", get_home(), name);
|
|
ef2 = eet_open(tmp, EET_FILE_MODE_WRITE);
|
|
free(name);
|
|
if (ef2)
|
|
{
|
|
field_copy(ef, ef2, "name");
|
|
field_copy(ef, ef2, "brief");
|
|
field_copy(ef, ef2, "version");
|
|
field_copy(ef, ef2, "license");
|
|
field_copy(ef, ef2, "repo");
|
|
field_copy(ef, ef2, "devrepo");
|
|
field_copy(ef, ef2, "contact");
|
|
field_copy(ef, ef2, "needs");
|
|
for (i = 0; i < 9999; i++)
|
|
{
|
|
snprintf(tmp, sizeof(tmp), "tag/%i", i);
|
|
if (!field_copy(ef, ef2, tmp)) break;
|
|
}
|
|
for (i = 0; i < 9999; i++)
|
|
{
|
|
snprintf(tmp, sizeof(tmp), "category/%i", i);
|
|
if (!field_copy(ef, ef2, tmp)) break;
|
|
}
|
|
eet_close(ef2);
|
|
}
|
|
eet_close(ef);
|
|
return EINA_TRUE;
|
|
}
|
|
error:
|
|
if (ef) eet_close(ef);
|
|
return EINA_FALSE;
|
|
}
|
|
|
|
EAPI Eina_Bool
|
|
mrk_package_bin_remove(const char *name)
|
|
{
|
|
char tmp[4096];
|
|
|
|
snprintf(tmp, sizeof(tmp), "%s/Applications/%s", get_home(), name);
|
|
if (!ecore_file_recursive_rm(tmp)) return EINA_FALSE;
|
|
return EINA_TRUE;
|
|
}
|