diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am index 0eea572fd..d7e9d21d0 100644 --- a/src/bin/Makefile.am +++ b/src/bin/Makefile.am @@ -52,7 +52,8 @@ e_bindings.h \ e_moveresize.h \ e_actions.h \ e_popup.h \ -e_ipc_codec.h +e_ipc_codec.h \ +e_prefix.h enlightenment_SOURCES = \ e_main.c \ @@ -98,6 +99,7 @@ e_moveresize.c \ e_actions.c \ e_popup.c \ e_ipc_codec.c \ +e_prefix.c \ $(ENLIGHTENMENTHEADERS) enlightenment_LDFLAGS = -export-dynamic @e_libs@ @dlopen_libs@ diff --git a/src/bin/e_includes.h b/src/bin/e_includes.h index cacadff41..6fb1da01f 100644 --- a/src/bin/e_includes.h +++ b/src/bin/e_includes.h @@ -43,3 +43,4 @@ #include "e_popup.h" #include "e_ipc_codec.h" #include "e_test.h" +#include "e_prefix.h" diff --git a/src/bin/e_intl.c b/src/bin/e_intl.c index 06a31a4ef..74248384f 100644 --- a/src/bin/e_intl.c +++ b/src/bin/e_intl.c @@ -38,6 +38,9 @@ e_intl_init(void) * vs. traditional chinese) we may refer to them as separate languages * entirely. */ + /* FIXME: remove this - hunt locale dirs (a user one in ~/.e/e/ too for + * user installed locale support + */ ADD_LANG(""); ADD_LANG("en_US.UTF-8"); ADD_LANG("ja_JP.UTF-8"); @@ -71,6 +74,7 @@ e_intl_shutdown(void) void e_intl_language_set(const char *lang) { + /* FIXME: determine if in user or system locale dir */ if (_e_intl_language) free(_e_intl_language); if (!lang) lang = getenv("LANG"); if (lang) @@ -104,132 +108,9 @@ e_intl_language_get(void) return _e_intl_language; } -#define IFL(l) if (!strcmp(lang, l)) return -const char * -e_intl_language_name_get(const char *lang) -{ - if (!lang) return "None"; - /* this is a list of DISTINCT languages. some languages have variants that - * are different enough to justify being listed separately as distinct - * languages here. this is intended for use in a gui that lets you select - * a language, with e being able to give a name for the given language - * encoding (once simplfied) - */ - /* FIXME: add as many as we can to this */ - IFL("") "None"; - IFL("C") "None"; - IFL("bg") "Bulgarian"; - IFL("bs") "Bosnian"; - IFL("ca") "Catalan"; - IFL("cs") "Czech"; - IFL("cy") "Welsh"; - IFL("da") "Danish"; - IFL("de") "German"; - IFL("el") "Greek"; - IFL("en") "English"; - IFL("es") "Spanish"; - IFL("eu") "Basque"; - IFL("fa") "Persian"; - IFL("fr") "French"; - IFL("fi") "Finnish"; - IFL("gl") "Galician"; - IFL("hi") "Hindi"; - IFL("hr") "Croatian"; - IFL("hu") "Hungarian"; - IFL("id") "Indonesian"; - IFL("it") "Italian"; - IFL("ja") "Japanese"; - IFL("kr") "Korean"; - IFL("lt") "Lithuanian"; - IFL("lv") "Latvian"; - IFL("nl") "Dutch"; - IFL("no") "Norwegian"; - IFL("nb") "Norwegian Bokmal"; - IFL("nn") "Norwegian Nynorsk"; - IFL("pl") "Polish"; - IFL("pt") "Portuguese"; - IFL("ro") "Romanian"; - IFL("ru") "Russian"; - IFL("sk") "Slovak"; - IFL("sl") "Slovenian"; - IFL("sq") "Albanian"; - IFL("sr") "Serbian"; - IFL("sv") "Swedish"; - IFL("tr") "Tuirkish"; - IFL("uk") "Ukrainian"; - IFL("vi") "Vietnamese"; - /* must keep both - politically sensitive */ - IFL("zh_CN") "Chinese (Simplified)"; - IFL("zh_TW") "Chinese (Traditional)"; - return "Unknown"; -} - -#define ISL(l) (!strcasecmp(buf, l)) -const char * -e_intl_language_simple_get(const char *lang) -{ - static char buf[128]; - char *p; - - if (!lang) return "C"; - /* strip off the charset stuff after any "." eg: "en_US.UTF-8" -> "en_US" */ - strncpy(buf, lang, sizeof(buf) - 1); - p = strchr(buf, '.'); - if (p) *p = 0; - /* do we want to split this inot the different forms of english? - * ie american vs british? or australian? etc. - */ - /* for known specific mappings - do them first here */ - if (ISL("en") || ISL("en_US") || ISL("en_GB") || ISL("en_GB@euro") || - ISL("en_CA") || ISL("en_AU") || ISL("en_NZ") || ISL("en_RN")) - return "en"; - if (ISL("ja") || ISL("ja_JP") || ISL("JP")) - return "ja"; - if (ISL("fr") || ISL("fr_FR") || ISL("FR") || ISL("fr_FR@euro")) - return "fr"; - if (ISL("es") || ISL("es_ES") || ISL("ES") || ISL("es_ES@euro") || - ISL("es_AR") || ISL("AR")) - return "es"; - if (ISL("pt") || ISL("pt_PT") || ISL("PT") || ISL("pt_PT@euro") || - ISL("pt_BR") || ISL("BR")) - return "pt"; - if (ISL("fi") || ISL("fi_FI") || ISL("FI") || ISL("fi_FI@euro")) - return "fi"; - if (ISL("ru") || ISL("ru_RU") || ISL("RU")) - return "ru"; - if (ISL("bg") || ISL("bg_BG") || ISL("BG")) - return "bg"; - if (ISL("de") || ISL("de_DE") || ISL("DE") || ISL("de_DE@euro") || - ISL("de_AT") || ISL("AT") || ISL("de_AT@euro")) - return "de"; - if (ISL("pl") || ISL("pl_PL") || ISL("PL") || ISL("pl_PL@euro")) - return "pl"; - if (ISL("zh") || ISL("zh_CN") || ISL("CN")) - return "zh_CN"; - if (ISL("zh") || ISL("zh_TW") || ISL("TW")) - return "zh_TW"; - if (ISL("hu") || ISL("hu_HU") || ISL("HU")) - return "hu"; - if (ISL("sl") || ISL("sl_SI") || ISL("SI")) - return "sl"; - if (ISL("it") || ISL("it_IT") || ISL("IT")) - return "it"; - /* this is the default fallback - we have no special cases for this lang - * so just strip off anything after and including the _ for country region - * and just return the language encoding - */ - /* strip off anything after a "_" eg: "en_US" -> "en" */ - p = strchr(buf, '_'); - if (p) *p = 0; - /* we can safely retunr buf because its a static - BUT its contents will - * change if we call e_intl_language_simple_get() again - so its only - * intended for immediate use and de-reference, not for storage - */ - return buf; -} - const Evas_List * e_intl_language_list(void) { + /* FIXME: hunt dirs for locales */ return _e_intl_languages; } diff --git a/src/bin/e_intl.h b/src/bin/e_intl.h index bd7b7346c..e5d24a8d2 100644 --- a/src/bin/e_intl.h +++ b/src/bin/e_intl.h @@ -17,8 +17,6 @@ EAPI int e_intl_init(void); EAPI int e_intl_shutdown(void); EAPI void e_intl_language_set(const char *lang); EAPI const char *e_intl_language_get(void); -EAPI const char *e_intl_language_name_get(const char *lang); -EAPI const char *e_intl_language_simple_get(const char *lang); EAPI const Evas_List *e_intl_language_list(void); #endif diff --git a/src/bin/e_main.c b/src/bin/e_main.c index 50d4cdac4..683ee5ec2 100644 --- a/src/bin/e_main.c +++ b/src/bin/e_main.c @@ -69,6 +69,21 @@ main(int argc, char **argv) sigaction(SIGSEGV, &sigsegv_action, NULL); #endif + /* FIXME: this is the init code for letting e be relocatable. right now + * its not used - so i want to see if it can reliably determine its exe + * prefix + */ + if (!e_prefix_determine(argv[0])) + { + fprintf(stderr, + "ERROR: Enlightenment cannot determine its installed\n" + " prefix from the system or argv[0].\n" + " This is because it is not on Linux AND has been\n" + " Executed strangely. This is unusal.\n" + ); + exit(-1); + } + /* for debugging by redirecting stdout of e to a log file to tail */ setvbuf(stdout, NULL, _IONBF, 0); diff --git a/src/bin/e_prefix.c b/src/bin/e_prefix.c new file mode 100644 index 000000000..3d4f21680 --- /dev/null +++ b/src/bin/e_prefix.c @@ -0,0 +1,210 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#include "e.h" + +/* local subsystem functions */ +static int _e_prefix_try_proc(void); +static int _e_prefix_try_argv(char *argv0); + +/* local subsystem globals */ +static char *_exe_path = NULL; +static char *_prefix_path = NULL; + +int +e_prefix_determine(char *argv0) +{ + char *p; + + if (_exe_path) free(_exe_path); + _exe_path = NULL; + if (_prefix_path) free(_prefix_path); + _prefix_path = NULL; + + if (!_e_prefix_try_proc()) + { + if (!_e_prefix_try_argv(argv0)) + return 0; + } + /* _exe_path is now a full absolute path TO this exe - figure out rest */ + /* if + * exe = /blah/whatever/bin/exe + * then + * prefix = /blah/whatever + * bin_dir = /blah/whatever/bin + * data_dir = /blah/whatever/share/enlightenment + * locale_dir = /blah/whatever/share/locale + * lib_dir = /blah/whatever/lib + */ + p = strrchr(_exe_path, '/'); + if (p) + { + p--; + while (p >= _exe_path) + { + if (*p == '/') + { + _prefix_path = malloc(p - _exe_path + 1); + if (_prefix_path) + { + strncpy(_prefix_path, _exe_path, p - _exe_path); + _prefix_path[p - _exe_path] = 0; + printf("DYNAMIC DETERMINED PREFIX: %s\n", _prefix_path); + return 1; + } + else + { + free(_exe_path); + _exe_path = NULL; + return 0; + } + } + p--; + } + } + free(_exe_path); + _exe_path = NULL; + return 0; +} + +const char * +e_prefix_get(void) +{ + return _prefix_path; +} + +/* local subsystem functions */ +static int +_e_prefix_try_proc(void) +{ + FILE *f; + char buf[4096]; + void *func = NULL; + + func = (void *)_e_prefix_try_proc; + f = fopen("/proc/self/maps", "r"); + if (!f) return 0; + while (fgets(buf, sizeof(buf), f)) + { + int len; + char *p, mode[5] = ""; + unsigned long ptr1 = 0, ptr2 = 0; + + len = strlen(buf); + if (buf[len - 1] == '\n') + { + buf[len - 1] = 0; + len--; + } + if (sscanf(buf, "%lx-%lx %4s", &ptr1, &ptr2, mode) == 3) + { + if (!strcmp(mode, "r-xp")) + { + if (((void *)ptr1 <= func) && (func < (void *)ptr2)) + { + p = strchr(buf, '/'); + if (p) + { + if (len > 10) + { + if (!strcmp(buf + len - 10, " (deleted)")) + buf[len - 10] = 0; + } + _exe_path = strdup(p); + fclose(f); + return 1; + } + else + break; + } + } + } + } + fclose(f); + return 0; +} + +static int +_e_prefix_try_argv(char *argv0) +{ + char *path, *p, *cp, *s; + int len, lenexe; +#ifdef PATH_MAX + char buf[PATH_MAX], buf2[PATH_MAX], buf3[PATH_MAX]; +#else + char buf[4096], buf2[4096], buf3[4096]; +#endif + + /* 1. is argv0 abs path? */ + if (argv0[0] == '/') + { + _exe_path = strdup(argv0); + if (access(_exe_path, X_OK) == 0) return 1; + free(_exe_path); + _exe_path = NULL; + return 0; + } + /* 2. relative path */ + if (strchr(argv0, '/')) + { + if (getcwd(buf3, sizeof(buf3))) + { + snprintf(buf2, sizeof(buf2), "%s/%s", buf3, argv0); + if (realpath(buf2, buf)) + { + _exe_path = strdup(buf); + if (access(_exe_path, X_OK) == 0) return 1; + free(_exe_path); + _exe_path = NULL; + } + } + } + /* 3. argv0 no path - look in PATH */ + path = getenv("PATH"); + if (!path) return 0; + p = path; + cp = p; + lenexe = strlen(argv0); + while (p = strchr(cp, ':')) + { + len = p - cp; + s = malloc(len + 1 + lenexe + 1); + if (s) + { + strncpy(s, cp, len); + s[len] = '/'; + strcpy(s + len + 1, argv0); + if (realpath(s, buf)) + { + if (access(buf, X_OK) == 0) + { + _exe_path = strdup(buf); + free(s); + return 1; + } + } + free(s); + } + cp = p + 1; + } + len = strlen(cp); + s = malloc(len + 1 + lenexe + 1); + if (s) + { + strncpy(s, cp, len); + s[len] = '/'; + strcpy(s + len + 1, argv0); + if (realpath(s, buf)) + { + if (access(buf, X_OK) == 0) + { + _exe_path = strdup(buf); + free(s); + return 1; + } + } + free(s); + } + /* 4. big problems. arg[0] != executable - weird execution */ + return 0; +} diff --git a/src/bin/e_prefix.h b/src/bin/e_prefix.h new file mode 100644 index 000000000..186e2d8d7 --- /dev/null +++ b/src/bin/e_prefix.h @@ -0,0 +1,14 @@ +/* + * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2 + */ +#ifdef E_TYPEDEFS + +#else +#ifndef E_PREFIX_H +#define E_PREFIX_H + +EAPI int e_prefix_determine(char *argv0); +EAPI const char *e_prefix_get(void); + +#endif +#endif