diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/internal.h | 11 | ||||
-rw-r--r-- | src/librcc.c | 128 | ||||
-rw-r--r-- | src/librcc.h | 41 | ||||
-rw-r--r-- | src/lngconfig.c | 16 | ||||
-rw-r--r-- | src/plugin.c | 1 | ||||
-rw-r--r-- | src/rccconfig.c | 7 | ||||
-rw-r--r-- | src/rccconfig.h | 1 | ||||
-rw-r--r-- | src/rccdb4.c | 33 | ||||
-rw-r--r-- | src/rccexternal.c | 19 | ||||
-rw-r--r-- | src/rccexternal.h | 8 | ||||
-rw-r--r-- | src/rcchome.c | 52 | ||||
-rw-r--r-- | src/rcchome.h | 8 | ||||
-rw-r--r-- | src/rcclock.c | 108 | ||||
-rw-r--r-- | src/rcclock.h | 12 | ||||
-rw-r--r-- | src/rccspell.c | 26 | ||||
-rw-r--r-- | src/rccspell.h | 2 | ||||
-rw-r--r-- | src/rcctranslate.c | 4 | ||||
-rw-r--r-- | src/rccxml.c | 15 | ||||
-rw-r--r-- | src/recode.c | 26 |
20 files changed, 336 insertions, 184 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 6d1ca98..79976c6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,5 +1,7 @@ lib_LTLIBRARIES = librcc.la librcc_la_SOURCES = librcc.c \ + rcchome.c rcchome.h \ + rcclock.c rcclock.h \ rcclocale.c rcclocale.h \ lng.c lng.h \ opt.c opt.h \ diff --git a/src/internal.h b/src/internal.h index c5170be..98ef6d7 100644 --- a/src/internal.h +++ b/src/internal.h @@ -5,11 +5,7 @@ # define LIBRCC_DATA_DIR "/usr/lib/rcc" #endif /* LIBRCC_DATA_DIR */ -#ifndef LIBRCC_LOCK_WAIT -# define LIBRCC_LOCK_WAIT 3000 /* ms */ -#endif /* LIBRCC_LOCK_WAIT */ - -#define RCC_MAX_LANGUAGE_PARRENTS 4 +#define RCC_MAX_LANGUAGE_PARENTS 4 #define RCC_MAX_RELATIONS RCC_MAX_LANGUAGES #ifdef HAVE_STRNLEN @@ -38,11 +34,11 @@ #define RCC_MAX_DISABLED_CHARSETS 64 -typedef rcc_language_id rcc_language_parrent_list[RCC_MAX_LANGUAGE_PARRENTS]; +typedef rcc_language_id rcc_language_parent_list[RCC_MAX_LANGUAGE_PARENTS]; struct rcc_language_internal_t { rcc_language language; - rcc_language_id parrents[RCC_MAX_LANGUAGE_PARRENTS + 1]; + rcc_language_id parents[RCC_MAX_LANGUAGE_PARENTS + 1]; unsigned char latin; }; typedef struct rcc_language_internal_t rcc_language_internal; @@ -102,6 +98,5 @@ int rccConfigure(rcc_context ctx); char *rccCreateResult(rcc_context ctx, size_t len); extern rcc_context rcc_default_ctx; -extern char *rcc_home_dir; #endif /* _RCC_INTERNAL_H */ diff --git a/src/librcc.c b/src/librcc.c index 6d3ce24..a39fef2 100644 --- a/src/librcc.c +++ b/src/librcc.c @@ -35,9 +35,10 @@ #include "rccxml.h" #include "rccexternal.h" #include "rcctranslate.h" +#include "rcclock.h" +#include "rcchome.h" static int initialized = 0; -char *rcc_home_dir = NULL; rcc_context rcc_default_ctx = NULL; static rcc_compiled_configuration_s compiled_configuration; @@ -64,27 +65,12 @@ rcc_compiled_configuration rccGetCompiledConfiguration() { int rccInit() { int err; - char *tmp; unsigned long i, rpos; - -#ifdef HAVE_PWD_H - struct passwd *pw; -#endif /* HAVE_PWD_H */ if (initialized) return 0; - tmp = getenv ("HOME"); - if (tmp) rcc_home_dir = strdup (tmp); -#ifdef HAVE_PWD_H - else { - setpwent (); - pw = getpwuid(getuid ()); - endpwent (); - if ((pw)&&(pw->pw_dir)) rcc_home_dir = strdup (pw->pw_dir); - } -#endif /* HAVE_PWD_H */ - if (!rcc_home_dir) rcc_home_dir = strdup("/"); - + rccHomeSet(); + memcpy(rcc_default_languages, rcc_default_languages_embeded, (RCC_MAX_LANGUAGES + 1)*sizeof(rcc_language)); memcpy(rcc_default_aliases, rcc_default_aliases_embeded, (RCC_MAX_ALIASES + 1)*sizeof(rcc_language_alias)); memcpy(rcc_default_relations, rcc_default_relations_embeded, (RCC_MAX_RELATIONS + 1)*sizeof(rcc_language_relation)); @@ -101,10 +87,10 @@ int rccInit() { if (!strcasecmp(rcc_default_languages[i].sn, rcc_english_language_sn)) continue; rcc_default_relations[rpos].lang = rcc_default_languages[i].sn; - rcc_default_relations[rpos++].parrent = rcc_english_language_sn; + rcc_default_relations[rpos++].parent = rcc_english_language_sn; } rcc_default_relations[rpos].lang = NULL; - rcc_default_relations[rpos].parrent = NULL; + rcc_default_relations[rpos].parent = NULL; err = rccPluginInit(); if (!err) err = rccTranslateInit(); @@ -134,97 +120,11 @@ void rccFree() { rccExternalFree(); - if (rcc_home_dir) { - free(rcc_home_dir); - rcc_home_dir = NULL; - } + rccHomeFree(); initialized = 0; } -static int lockfd = -1; - -int rccLock() { -# ifdef HAVE_SYS_FILE_H - int err, i; - int size; - char *stmp; - struct timespec wait = { 0, 10000000 }; - - if (lockfd>=0) return -1; - - size = strlen(rcc_home_dir) + 32; - stmp = (char*)malloc(size*sizeof(char)); - if (!stmp) return -1; - - sprintf(stmp,"%s/.rcc/", rcc_home_dir); - mkdir(stmp, 00755); - - sprintf(stmp,"%s/.rcc/locks/", rcc_home_dir); - mkdir(stmp, 00700); - - sprintf(stmp,"%s/.rcc/locks/rcc.lock", rcc_home_dir); - - lockfd = open(stmp, O_RDWR|O_CREAT, 0644); - if (lockfd >= 0) { - for (err = -1, i = 0; i < (LIBRCC_LOCK_WAIT/10); i++) { - err = flock(lockfd, LOCK_EX|LOCK_NB); - if ((err)&&(errno == EWOULDBLOCK)) nanosleep(&wait, NULL); - else break; - } - - if (err) { - close(lockfd); - - // Removing invalid lock - if (i == (LIBRCC_LOCK_WAIT/10)) { - remove(stmp); - - lockfd = open(stmp, O_RDWR|O_CREAT, 0644); - if (lockfd >= 0) { - for (err = -1, i = 0; i < (LIBRCC_LOCK_WAIT/10); i++) { - err = flock(lockfd, LOCK_EX|LOCK_NB); - if ((err)&&(errno == EWOULDBLOCK)) nanosleep(&wait, NULL); - else break; - } - - if (err) close(lockfd); - else return 0; - } - } - - lockfd = -1; - return -1; - } - - return 0; - } - - return -1; -# else /* HAVE_SYS_FILE_H */ - return 0; -# endif /* HAVE_SYS_FILE_H */ -} - -void rccUnLock() { -#ifdef HAVE_SYS_FILE_H - int size; - char *stmp; - - if (lockfd<0) return; - - size = strlen(rcc_home_dir) + 32; - stmp = (char*)malloc(size*sizeof(char)); - if (!stmp) return; - - sprintf(stmp,"%s/.rcc/locks/rcc.lock", rcc_home_dir); - - flock(lockfd, LOCK_UN); - close(lockfd); - lockfd = -1; -#endif /* HAVE_SYS_FILE_H */ -} - rcc_context rccCreateContext(const char *locale_variable, unsigned int max_languages, unsigned int max_classes, rcc_class_ptr defclasses, rcc_init_flags flags) { unsigned int i; @@ -470,7 +370,7 @@ rcc_language_id rccRegisterLanguage(rcc_context ctx, rcc_language *language) { if (ctx->n_languages == ctx->max_languages) return (rcc_language_id)-1; memcpy(ctx->ilang + ctx->n_languages, language, sizeof(rcc_language)); - ctx->ilang[ctx->n_languages].parrents[0] = (rcc_language_id)-1; + ctx->ilang[ctx->n_languages].parents[0] = (rcc_language_id)-1; ctx->ilang[ctx->n_languages].latin = 0; for (i=0;language->charsets[i];i++) @@ -539,7 +439,7 @@ rcc_relation_id rccRegisterLanguageRelation(rcc_context ctx, rcc_language_relati unsigned int i; rcc_language_id language_id; const char *lang; - const char *parrent; + const char *parent; rcc_language_id *list; if (!ctx) { @@ -549,22 +449,22 @@ rcc_relation_id rccRegisterLanguageRelation(rcc_context ctx, rcc_language_relati if (!relation) return (rcc_relation_id)-1; lang = relation->lang; - parrent = relation->parrent; - if ((!lang)||(!parrent)||(!strcasecmp(lang,parrent))) return (rcc_relation_id)-1; + parent = relation->parent; + if ((!lang)||(!parent)||(!strcasecmp(lang,parent))) return (rcc_relation_id)-1; language_id = rccGetLanguageByName(ctx, lang); if (language_id == (rcc_language_id)-1) return (rcc_relation_id)-1; - list = ((rcc_language_internal*)ctx->languages[language_id])->parrents; + list = ((rcc_language_internal*)ctx->languages[language_id])->parents; - language_id = rccGetLanguageByName(ctx, parrent); + language_id = rccGetLanguageByName(ctx, parent); if (language_id == (rcc_language_id)-1) return (rcc_relation_id)0; for (i=0;list[i]!=(rcc_language_id)-1;i++) if (list[i] == language_id) return (rcc_relation_id)0; - if (i<RCC_MAX_LANGUAGE_PARRENTS) { + if (i<RCC_MAX_LANGUAGE_PARENTS) { list[i++] = language_id; list[i] = (rcc_language_id)-1; } else return (rcc_relation_id)-1; diff --git a/src/librcc.h b/src/librcc.h index 98ca1a6..e5749cd 100644 --- a/src/librcc.h +++ b/src/librcc.h @@ -234,17 +234,17 @@ typedef rcc_language_alias_ptr rcc_language_alias_list[RCC_MAX_ALIASES+1]; /** * Language relations. - * Meaning: sentence in considered language may contain words from all his parrents. This + * Meaning: sentence in considered language may contain words from all his parents. This * knowledge will help Autodetection Engine to guess right language. * - * For example: Russian is parrent language for Ukrainian. This means it is possible + * For example: Russian is parent language for Ukrainian. This means it is possible * to encounter russian words in ukrainian sentence. * * All languages by default are related to english language. */ struct rcc_language_relation_t { const char *lang; /**< Coresponded language ISO-639-1 name */ - const char *parrent; /**< Parrent language */ + const char *parent; /**< Parent language */ }; typedef struct rcc_language_relation_t rcc_language_relation; @@ -349,7 +349,7 @@ typedef const struct rcc_class_default_charset_t rcc_class_default_charset; struct rcc_class_t { const char *name; /**< Short class name */ const rcc_class_type class_type; /**< specifies type of class (Standard, File System, Known) */ - const char *defvalue; /**< locale variable name or parrent name or multibyte encoding name */ + const char *defvalue; /**< locale variable name or parent name or multibyte encoding name */ rcc_class_default_charset *defcharset; /**< default class encodings. Should be specified on per-language basys */ const char *fullname; /**< Full name of the class */ const unsigned long flags; /**< Class flags. (CONST, SKIP_SAVELOAD) */ @@ -430,7 +430,7 @@ typedef enum rcc_option_translate_t { RCC_OPTION_TRANSLATE_TRANSLITERATE, /**< Transliterate data. */ RCC_OPTION_TRANSLATE_TO_ENGLISH, /**< Translate data to english language (Current language don't matter). */ RCC_OPTION_TRANSLATE_SKIP_RELATED, /**< Skip translation of the text's between related languages. */ - RCC_OPTION_TRANSLATE_SKIP_PARRENT, /**< Skip translation of the text's from parrent languages (from english). */ + RCC_OPTION_TRANSLATE_SKIP_PARENT, /**< Skip translation of the text's from parent languages (from english). */ RCC_OPTION_TRANSLATE_FULL /**< Translate whole data to the current language */ } rcc_option_translate; @@ -446,6 +446,7 @@ typedef enum rcc_option_t { RCC_OPTION_AUTODETECT_LANGUAGE, /**< Enables language detection */ RCC_OPTION_TRANSLATE, /**< Translate #rcc_string if it's language differs from current one */ RCC_OPTION_TIMEOUT, /**< Recoding timeout. Currently it is only used to limit translation time */ + RCC_OPTION_OFFLINE, /**< Allows external module to finish it's job in offline after the main program is terminated */ RCC_MAX_OPTIONS, RCC_OPTION_ALL } rcc_option; @@ -887,7 +888,7 @@ const char *rccConfigGetSelectedCharsetName(rcc_language_config config, rcc_clas * Return current encoding_id. The default value will be resolved to paticular encoding id. * The following procedure is used to detect default encoding: * - If Unicode encoding selected for the same class english language. Return this encoding. - * - If the parrent class is defined in #defcharset, - return current encoding of parrent class. + * - If the parent class is defined in #defcharset, - return current encoding of parent class. * - If the locale variable is defined in #defcharset and either config language coincide with locale language or unciode encoding defined, use locale encoding. * - If the default value for config language is defined in #defvalue return that default value. * - If the default value for all languages is defined in #defvalue return that default value. @@ -1146,6 +1147,15 @@ void rccTranslateClose(rcc_translate translate); */ int rccTranslateSetTimeout(rcc_translate translate, unsigned long us); +/* + * Allows translation engine to perform pending task after the main program is + * being terminated + * + * @param translate is translating context + * @return non-zero value is returned in the case of errror + */ +int rccTranslateAllowOfflineMode(rcc_translate translate); + /** * Translate string. * @@ -1168,9 +1178,9 @@ typedef struct rcc_speller_t *rcc_speller; */ typedef enum rcc_speller_result_t { RCC_SPELLER_INCORRECT = 0, /**< Word not found in dictionaries */ - RCC_SPELLER_ALMOST_PARRENT, /**< Similliar word is found in parrents dictionary */ + RCC_SPELLER_ALMOST_PARENT, /**< Similliar word is found in parents dictionary */ RCC_SPELLER_ALMOST_CORRECT, /**< Similliar word is found in dictionary */ - RCC_SPELLER_PARRENT, /**< Word is found in parrent dictionary */ + RCC_SPELLER_PARENT, /**< Word is found in parent dictionary */ RCC_SPELLER_CORRECT /**< Word is found in dictionary */ } rcc_speller_result; @@ -1194,13 +1204,13 @@ rcc_speller rccSpellerCreate(const char *lang); */ void rccSpellerFree(rcc_speller speller); /** - * Add parrent to the spelling context. + * Add parent to the spelling context. * * @param speller is spelling context - * @param parrent is parrent spelling context + * @param parent is parent spelling context * @return non-zero value in the case of error */ -int rccSpellerAddParrent(rcc_speller speller, rcc_speller parrent); +int rccSpellerAddParent(rcc_speller speller, rcc_speller parent); /** * Spell a word. * @@ -1515,6 +1525,15 @@ int rccLocaleGetClassByName(const char *locale); int rccLocaleGetLanguage(char *result, const char *lv, unsigned int n); int rccLocaleGetCharset(char *result, const char *lv, unsigned int n); + +/** + * For compatibilty reasons + */ +#define RCC_OPTION_TRANSLATE_SKIP_PARRENT RCC_OPTION_TRANSLATE_SKIP_PARENT +#define RCC_SPELLER_ALMOST_PARRENT RCC_SPELLER_ALMOST_PARENT +#define RCC_SPELLER_PARRENT RCC_SPELLER_PARENT +#define rccSpellerAddParrent rccSpellerAddParent + #ifdef __cplusplus } #endif diff --git a/src/lngconfig.c b/src/lngconfig.c index 631abd1..67e05c6 100644 --- a/src/lngconfig.c +++ b/src/lngconfig.c @@ -437,7 +437,7 @@ rcc_speller rccConfigGetSpeller(rcc_language_config config) { unsigned int i; rcc_speller speller; rcc_language_config pconfig; - rcc_language_id *parrents; + rcc_language_id *parents; rcc_language_id language_id; if (!config) return NULL; @@ -447,12 +447,12 @@ rcc_speller rccConfigGetSpeller(rcc_language_config config) { if (config->speller) language_id = rccConfigGetLanguage(config); else language_id = (rcc_language_id)-1; - if (language_id != (rcc_language_id)-1) parrents = ((rcc_language_internal*)config->language)->parrents; - else parrents = NULL; + if (language_id != (rcc_language_id)-1) parents = ((rcc_language_internal*)config->language)->parents; + else parents = NULL; - if (parrents) { - for (i = 0; parrents[i]!=(rcc_language_id)-1; i++) { - pconfig = rccGetConfig(config->ctx, parrents[i]); + if (parents) { + for (i = 0; parents[i]!=(rcc_language_id)-1; i++) { + pconfig = rccGetConfig(config->ctx, parents[i]); if (pconfig) { speller = rccConfigGetSpeller(pconfig); rccSpellerAddParrent(config->speller, speller); @@ -467,6 +467,7 @@ rcc_speller rccConfigGetSpeller(rcc_language_config config) { rcc_translate rccConfigGetTranslator(rcc_language_config config, rcc_language_id to) { rcc_option_value timeout; + rcc_option_value offline; if (!config) return NULL; @@ -482,6 +483,9 @@ rcc_translate rccConfigGetTranslator(rcc_language_config config, rcc_language_id config->translang = to; timeout = rccGetOption(config->ctx, RCC_OPTION_TIMEOUT); if (timeout) rccTranslateSetTimeout(config->trans, timeout); + + offline = rccGetOption(config->ctx, RCC_OPTION_OFFLINE); + if (offline) rccTranslateAllowOfflineMode(config->trans); } } rccMutexUnLock(config->mutex); diff --git a/src/plugin.c b/src/plugin.c index b3289b7..c1f0074 100644 --- a/src/plugin.c +++ b/src/plugin.c @@ -3,6 +3,7 @@ #include <string.h> #include "internal.h" +#include "rcchome.h" #include "plugin.h" #ifdef RCC_PLUGINS diff --git a/src/rccconfig.c b/src/rccconfig.c index ae47a63..6723825 100644 --- a/src/rccconfig.c +++ b/src/rccconfig.c @@ -134,7 +134,7 @@ rcc_language rcc_default_languages_embeded[RCC_MAX_LANGUAGES + 1] = { rcc_option_value_name rcc_sn_boolean[] = { "OFF", "ON", NULL }; rcc_option_value_name rcc_sn_learning[] = { "OFF", "ON", "RELEARN", "LEARN", NULL }; rcc_option_value_name rcc_sn_clo[] = { "ALL", "CONFIGURED_AND_AUTO", "CONFIGURED_ONLY", NULL }; -rcc_option_value_name rcc_sn_translate[] = { "OFF", "TRANSLITERATE", "TO_ENGLISH", "SKIP_RELATED", "SKIP_PARRENT", "FULL", NULL }; +rcc_option_value_name rcc_sn_translate[] = { "OFF", "TRANSLITERATE", "TO_ENGLISH", "SKIP_RELATED", "SKIP_PARENT", "FULL", NULL }; rcc_option_description rcc_option_descriptions[RCC_MAX_OPTIONS+1]; rcc_option_description rcc_option_descriptions_embeded[RCC_MAX_OPTIONS+1] = { @@ -162,6 +162,7 @@ rcc_option_description rcc_option_descriptions_embeded[RCC_MAX_OPTIONS+1] = { #else {RCC_OPTION_TIMEOUT, RCC_DEFAULT_RECODING_TIMEOUT, { RCC_OPTION_RANGE_TYPE_RANGE, 0, 5000000, 50000}, RCC_OPTION_TYPE_INVISIBLE, "TIMEOUT", NULL }, #endif /* HAVE_LIBTRANSLATE */ + {RCC_OPTION_OFFLINE, 0, { RCC_OPTION_RANGE_TYPE_BOOLEAN, 0, 0, 0 }, RCC_OPTION_TYPE_INVISIBLE, "OFFLINE_PROCESSING", rcc_sn_boolean}, {RCC_MAX_OPTIONS} }; @@ -215,11 +216,11 @@ unsigned int rccDefaultDropLanguageRelations(const char *lang) { if (strcasecmp(lang, rcc_default_relations[i].lang)) { if (j<i) { rcc_default_relations[j].lang = rcc_default_relations[i].lang; - rcc_default_relations[j++].parrent = rcc_default_relations[i].parrent; + rcc_default_relations[j++].parent = rcc_default_relations[i].parent; } else j++; } } rcc_default_relations[j].lang = NULL; - rcc_default_relations[j].parrent = NULL; + rcc_default_relations[j].parent = NULL; return j; } diff --git a/src/rccconfig.h b/src/rccconfig.h index 8b5ac0d..c84403a 100644 --- a/src/rccconfig.h +++ b/src/rccconfig.h @@ -5,6 +5,7 @@ #undef RCC_DEBUG #undef RCC_DEBUG_LANGDETECT +//#define RCC_DEBUG_LANGDETECT 5 #define RCC_LOCALE_VARIABLE "LC_CTYPE" extern const char rcc_default_all[]; diff --git a/src/rccdb4.c b/src/rccdb4.c index a4e0976..1eb5d44 100644 --- a/src/rccdb4.c +++ b/src/rccdb4.c @@ -5,6 +5,7 @@ #include "../config.h" #include "internal.h" +#include "rcchome.h" #include "rccdb4.h" #define DATABASE "autolearn.db" @@ -15,21 +16,36 @@ db4_context rccDb4CreateContext(const char *dbpath, rcc_db4_flags flags) { #ifdef HAVE_DB_H DB_ENV *dbe; DB *db; - + +# if 0 char stmp[160]; +# endif err = db_env_create(&dbe, 0); if (err) return NULL; +# if 1 + dbe->set_flags(dbe, DB_LOG_AUTOREMOVE, 1); + dbe->set_lg_max(dbe, 131072); + + err = rccLock(); + if (!err) { + err = dbe->open(dbe, dbpath, DB_CREATE|DB_INIT_TXN|DB_USE_ENVIRON|DB_INIT_LOCK|DB_INIT_MPOOL|DB_RECOVER, 00644); + rccUnLock(); + } +# else err = dbe->open(dbe, dbpath, DB_CREATE|DB_INIT_CDB|DB_INIT_MPOOL, 00644); if (err == DB_VERSION_MISMATCH) { - if (!rccLock()) { err = dbe->open(dbe, dbpath, DB_CREATE|DB_INIT_LOCK|DB_INIT_LOG|DB_INIT_MPOOL|DB_INIT_TXN|DB_USE_ENVIRON|DB_PRIVATE|DB_RECOVER, 0); + dbe->close(dbe, 0); + dbe->remove(dbe, dbpath, 0); rccUnLock(); - } else err = -1; - - dbe->close(dbe, 0); + } else { + err = -1; + dbe->close(dbe, 0); + } + if (err) return NULL; if (strlen(dbpath)<128) { @@ -43,8 +59,10 @@ db4_context rccDb4CreateContext(const char *dbpath, rcc_db4_flags flags) { err = dbe->open(dbe, dbpath, DB_CREATE|DB_INIT_CDB|DB_INIT_MPOOL, 00644); } - +# endif + if (err) { +// fprintf(stderr, "BerkelyDB initialization failed: %i (%s)\n", err, db_strerror(err)); dbe->close(dbe, 0); return NULL; } @@ -55,6 +73,7 @@ db4_context rccDb4CreateContext(const char *dbpath, rcc_db4_flags flags) { return NULL; } + err = db->open(db, NULL, DATABASE, NULL, DB_BTREE, DB_CREATE, 0); if (err) { db->close(db, 0); @@ -71,7 +90,7 @@ db4_context rccDb4CreateContext(const char *dbpath, rcc_db4_flags flags) { #endif /* HAVE_DB_H */ return NULL; } - + #ifdef HAVE_DB_H ctx->db = db; ctx->dbe = dbe; diff --git a/src/rccexternal.c b/src/rccexternal.c index be9f97d..58b8a23 100644 --- a/src/rccexternal.c +++ b/src/rccexternal.c @@ -38,6 +38,7 @@ # include <sys/wait.h> #endif /* HAVE_SYS_WAIT_H */ +#include "rcchome.h" #include "rccexternal.h" #include "internal.h" @@ -92,7 +93,7 @@ void rccExternalFree() { res = waitpid(pid, NULL, WNOHANG); if (res) break; - else timeout.tv_nsec*10; + else timeout.tv_nsec*=10; } pid = (pid_t)-1; @@ -225,3 +226,19 @@ void rccExternalClose(int s) { close(s); } } + +int rccExternalAllowOfflineMode() { + int sock; + int err; + rcc_external_option opt = RCC_EXTERNAL_OPTION_OFFLINE; + unsigned long opt_value = 1; + + sock = rccExternalConnect(RCC_EXTERNAL_MODULE_OPTIONS); + if (sock) { + err = rccExternalWrite(sock, (char*)&opt, sizeof(rcc_external_option), 0); + if (!err) err = rccExternalWrite(sock, (char*)&opt_value, sizeof(unsigned long), 0); + rccExternalClose(sock); + return err; + } + return -1; +} diff --git a/src/rccexternal.h b/src/rccexternal.h index 236e2df..1038329 100644 --- a/src/rccexternal.h +++ b/src/rccexternal.h @@ -3,6 +3,7 @@ typedef enum rcc_external_module_t { RCC_EXTERNAL_MODULE_CONTROL = 0, + RCC_EXTERNAL_MODULE_OPTIONS, RCC_EXTERNAL_MODULE_LIBRTRANSLATE, RCC_EXTERNAL_MODULE_MAX } rcc_external_module; @@ -13,6 +14,11 @@ struct rcc_external_info_t { typedef struct rcc_external_info_t rcc_external_info_s; typedef struct rcc_external_info_t *rcc_external_info; +typedef enum rcc_external_option_t { + RCC_EXTERNAL_OPTION_OFFLINE = 0, + RCC_EXTERNAL_OPTION_MAX +} rcc_external_option; + struct rcc_external_command_t { unsigned long size; unsigned char cmd; @@ -25,6 +31,8 @@ typedef struct rcc_external_command_t *rcc_external_command; int rccExternalInit(); void rccExternalFree(); +int rccExternalAllowOfflineMode(); + size_t rccExternalWrite(int s, const char *buffer, ssize_t size, unsigned long timeout); size_t rccExternalRead(int s, char *buffer, ssize_t size, unsigned long timeout); int rccExternalConnect(unsigned char module); diff --git a/src/rcchome.c b/src/rcchome.c new file mode 100644 index 0000000..a88a667 --- /dev/null +++ b/src/rcchome.c @@ -0,0 +1,52 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "../config.h" + + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif /* HAVE_UNISTD_H */ + +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif /* HAVE_SYS_TYPES_H */ +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif /* HAVE_SYS_STAT_H */ + +#ifdef HAVE_PWD_H +# include <pwd.h> +#endif /* HAVE_PWD_H */ + +#include "rcchome.h" + +char *rcc_home_dir = NULL; + +void rccHomeSet() { + char *tmp; + +#ifdef HAVE_PWD_H + struct passwd *pw; +#endif /* HAVE_PWD_H */ + + tmp = getenv ("HOME"); + if (tmp) rcc_home_dir = strdup (tmp); +#ifdef HAVE_PWD_H + else { + setpwent (); + pw = getpwuid(getuid ()); + endpwent (); + if ((pw)&&(pw->pw_dir)) rcc_home_dir = strdup (pw->pw_dir); + } +#endif /* HAVE_PWD_H */ + if (!rcc_home_dir) rcc_home_dir = strdup("/"); +} + +void rccHomeFree() { + if (rcc_home_dir) { + free(rcc_home_dir); + rcc_home_dir = NULL; + } +} diff --git a/src/rcchome.h b/src/rcchome.h new file mode 100644 index 0000000..0712eab --- /dev/null +++ b/src/rcchome.h @@ -0,0 +1,8 @@ +#ifndef _RCC_HOME_H +#define _RCC_HOME_H + +extern char *rcc_home_dir; +void rccHomeSet(); +void rccHomeFree(); + +#endif /* _RCC_HOME_H */ diff --git a/src/rcclock.c b/src/rcclock.c new file mode 100644 index 0000000..b8f0e8f --- /dev/null +++ b/src/rcclock.c @@ -0,0 +1,108 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <time.h> +#include <errno.h> + +#include "../config.h" + +#ifdef HAVE_SYS_FILE_H +# include <sys/file.h> +#endif /* HAVE_SYS_FILE_H */ + +#ifdef HAVE_UNISTD_H +# include <unistd.h> +#endif /* HAVE_UNISTD_H */ + +#ifdef HAVE_SYS_TYPES_H +# include <sys/types.h> +#endif /* HAVE_SYS_TYPES_H */ +#ifdef HAVE_SYS_STAT_H +# include <sys/stat.h> +#endif /* HAVE_SYS_STAT_H */ + +#include "rcchome.h" +#include "rcclock.h" + +static int lockfd = -1; + +int rccLock() { +# ifdef HAVE_SYS_FILE_H + int err, i; + int size; + char *stmp; + struct timespec wait = { 0, 10000000 }; + + if (lockfd>=0) return -1; + + size = strlen(rcc_home_dir) + 32; + stmp = (char*)malloc(size*sizeof(char)); + if (!stmp) return -1; + + sprintf(stmp,"%s/.rcc/", rcc_home_dir); + mkdir(stmp, 00755); + + sprintf(stmp,"%s/.rcc/locks/", rcc_home_dir); + mkdir(stmp, 00700); + + sprintf(stmp,"%s/.rcc/locks/rcc.lock", rcc_home_dir); + + lockfd = open(stmp, O_RDWR|O_CREAT, 0644); + if (lockfd >= 0) { + for (err = -1, i = 0; i < (LIBRCC_LOCK_WAIT/10); i++) { + err = flock(lockfd, LOCK_EX|LOCK_NB); + if ((err)&&(errno == EWOULDBLOCK)) nanosleep(&wait, NULL); + else break; + } + + if (err) { + close(lockfd); + + // Removing invalid lock + if (i == (LIBRCC_LOCK_WAIT/10)) { + remove(stmp); + + lockfd = open(stmp, O_RDWR|O_CREAT, 0644); + if (lockfd >= 0) { + for (err = -1, i = 0; i < (LIBRCC_LOCK_WAIT/10); i++) { + err = flock(lockfd, LOCK_EX|LOCK_NB); + if ((err)&&(errno == EWOULDBLOCK)) nanosleep(&wait, NULL); + else break; + } + + if (err) close(lockfd); + else return 0; + } + } + + lockfd = -1; + return -1; + } + + return 0; + } + + return -1; +# else /* HAVE_SYS_FILE_H */ + return 0; +# endif /* HAVE_SYS_FILE_H */ +} + +void rccUnLock() { +#ifdef HAVE_SYS_FILE_H + int size; + char *stmp; + + if (lockfd<0) return; + + size = strlen(rcc_home_dir) + 32; + stmp = (char*)malloc(size*sizeof(char)); + if (!stmp) return; + + sprintf(stmp,"%s/.rcc/locks/rcc.lock", rcc_home_dir); + + flock(lockfd, LOCK_UN); + close(lockfd); + lockfd = -1; +#endif /* HAVE_SYS_FILE_H */ +} diff --git a/src/rcclock.h b/src/rcclock.h new file mode 100644 index 0000000..e043150 --- /dev/null +++ b/src/rcclock.h @@ -0,0 +1,12 @@ +#ifndef _RCC_LOCK_H +#define _RCC_LOCK_H + +#ifndef LIBRCC_LOCK_WAIT +# define LIBRCC_LOCK_WAIT 3000 /* ms */ +#endif /* LIBRCC_LOCK_WAIT */ + +int rccLock(); +void rccUnLock(); + +#endif /* _RCC_LOCK_H */ + diff --git a/src/rccspell.c b/src/rccspell.c index da5e4d1..19b5abc 100644 --- a/src/rccspell.c +++ b/src/rccspell.c @@ -29,7 +29,7 @@ rcc_speller rccSpellerCreate(const char *lang) { } rccspeller->speller = speller; - rccspeller->parrents[0] = NULL; + rccspeller->parents[0] = NULL; return rccspeller; #else return NULL; @@ -49,14 +49,14 @@ int rccSpellerGetError(rcc_speller rccspeller) { return 0; } -int rccSpellerAddParrent(rcc_speller speller, rcc_speller parrent) { +int rccSpellerAddParent(rcc_speller speller, rcc_speller parent) { unsigned int i; - if ((!speller)||(!parrent)) return -1; + if ((!speller)||(!parent)) return -1; - for (i=0;speller->parrents[i];i++); - if (i >= RCC_MAX_LANGUAGE_PARRENTS) return -1; - speller->parrents[i++] = parrent; - speller->parrents[i] = NULL; + for (i=0;speller->parents[i];i++); + if (i >= RCC_MAX_LANGUAGE_PARENTS) return -1; + speller->parents[i++] = parent; + speller->parents[i] = NULL; return 0; } @@ -70,10 +70,10 @@ rcc_speller_result rccSpellerSized(rcc_speller speller, const char *word, size_t if (rccSpellerGetError(speller)) return (rcc_speller_result)RCC_SPELLER_INCORRECT; if (recursion) { - for (i=0; speller->parrents[i]; i++) { - result = rccSpellerSized(speller->parrents[i], word, len, 0); - if ((result == RCC_SPELLER_CORRECT)||(result == RCC_SPELLER_PARRENT)) return RCC_SPELLER_PARRENT; - if ((result == RCC_SPELLER_ALMOST_CORRECT)||(result == RCC_SPELLER_ALMOST_PARRENT)) saved_result = RCC_SPELLER_ALMOST_PARRENT; + for (i=0; speller->parents[i]; i++) { + result = rccSpellerSized(speller->parents[i], word, len, 0); + if ((result == RCC_SPELLER_CORRECT)||(result == RCC_SPELLER_PARENT)) return RCC_SPELLER_PARENT; + if ((result == RCC_SPELLER_ALMOST_CORRECT)||(result == RCC_SPELLER_ALMOST_PARENT)) saved_result = RCC_SPELLER_ALMOST_PARENT; } } @@ -95,12 +95,12 @@ int rccSpellerResultIsOwn(rcc_speller_result res) { } int rccSpellerResultIsPrecise(rcc_speller_result res) { - if ((res == RCC_SPELLER_PARRENT)||(res == RCC_SPELLER_CORRECT)) return 1; + if ((res == RCC_SPELLER_PARENT)||(res == RCC_SPELLER_CORRECT)) return 1; return 0; } int rccSpellerResultIsCorrect(rcc_speller_result res) { if ((res == RCC_SPELLER_ALMOST_CORRECT)||(res == RCC_SPELLER_CORRECT)) return 1; - if ((res == RCC_SPELLER_ALMOST_PARRENT)||(res == RCC_SPELLER_PARRENT)) return 1; + if ((res == RCC_SPELLER_ALMOST_PARENT)||(res == RCC_SPELLER_PARENT)) return 1; return 0; } diff --git a/src/rccspell.h b/src/rccspell.h index 49d5c99..4943e93 100644 --- a/src/rccspell.h +++ b/src/rccspell.h @@ -15,7 +15,7 @@ struct rcc_speller_t { #else void *speller; #endif /* HAVE_ASPELL */ - rcc_speller parrents[RCC_MAX_LANGUAGE_PARRENTS+1]; + rcc_speller parents[RCC_MAX_LANGUAGE_PARENTS+1]; }; typedef struct rcc_speller_t rcc_speller_s; diff --git a/src/rcctranslate.c b/src/rcctranslate.c index 37f0f01..98c0f1b 100644 --- a/src/rcctranslate.c +++ b/src/rcctranslate.c @@ -83,6 +83,10 @@ int rccTranslateSetTimeout(rcc_translate translate, unsigned long us) { return 0; } +int rccTranslateAllowOfflineMode(rcc_translate translate) { + return rccExternalAllowOfflineMode(); +} + #define RCC_UNLOCK_W 1 #define RCC_UNLOCK_R 2 #define RCC_UNLOCK_RW 3 diff --git a/src/rccxml.c b/src/rccxml.c index db13750..e5283af 100644 --- a/src/rccxml.c +++ b/src/rccxml.c @@ -31,6 +31,7 @@ #include "internal.h" #include "rccconfig.h" #include "plugin.h" +#include "rcchome.h" #define MAX_HOME_CHARS 96 #define XPATH_LANGUAGE "//Language[@name]" @@ -58,7 +59,7 @@ int rccXmlInit(int LoadConfiguration) { xmlAttrPtr attr; const char *lang, *engine_name; unsigned int pos, lpos, epos, cpos; - const char *alias, *parrent; + const char *alias, *parent; unsigned int j, apos, rpos; rcc_engine *engine; @@ -115,9 +116,9 @@ int rccXmlInit(int LoadConfiguration) { if (pos == (rcc_language_id)-1) { for (rpos=0;rcc_default_relations[rpos].lang;rpos++); if (rpos < RCC_MAX_RELATIONS) { - rcc_default_relations[rpos].parrent = rcc_english_language_sn; + rcc_default_relations[rpos].parent = rcc_english_language_sn; rcc_default_relations[rpos++].lang = lang; - rcc_default_relations[rpos].parrent = NULL; + rcc_default_relations[rpos].parent = NULL; rcc_default_relations[rpos].lang = NULL; } @@ -172,11 +173,11 @@ int rccXmlInit(int LoadConfiguration) { for (enode=node->children;enode;enode=enode->next) { if (enode->type != XML_ELEMENT_NODE) continue; if ((!xmlStrcmp(enode->name, "Parrent"))&&(rpos<RCC_MAX_RELATIONS)) { - parrent = rccXmlGetText(enode); - if (!parrent) continue; - rcc_default_relations[rpos].parrent = parrent; + parent = rccXmlGetText(enode); + if (!parent) continue; + rcc_default_relations[rpos].parent = parent; rcc_default_relations[rpos++].lang = lang; - rcc_default_relations[rpos].parrent = NULL; + rcc_default_relations[rpos].parent = NULL; rcc_default_relations[rpos].lang = NULL; } } diff --git a/src/recode.c b/src/recode.c index 8c6cc40..e1e8e81 100644 --- a/src/recode.c +++ b/src/recode.c @@ -53,7 +53,7 @@ static rcc_language_id rccDetectLanguageInternal(rcc_context ctx, rcc_class_id c char *best_string = NULL; rcc_language_id bestfixlang = (rcc_language_id)-1; unsigned long k; - rcc_language_id *parrents; + rcc_language_id *parents; size_t chars = 0; char llang[RCC_MAX_LANGUAGE_CHARS]; rcc_language_id locale_lang; @@ -109,11 +109,11 @@ static rcc_language_id rccDetectLanguageInternal(rcc_context ctx, rcc_class_id c if (bestfixlang != (rcc_language_id)-1) { - parrents = ((rcc_language_internal*)config->language)->parrents; - for (k = 0;parrents[k] != (rcc_language_id)-1;k++) - if (parrents[k] == bestfixlang) break; + parents = ((rcc_language_internal*)config->language)->parents; + for (k = 0;parents[k] != (rcc_language_id)-1;k++) + if (parents[k] == bestfixlang) break; - if (parrents[k] != bestfixlang) continue; + if (parents[k] != bestfixlang) continue; } speller = rccConfigGetSpeller(config); @@ -281,17 +281,17 @@ rcc_language_id rccDetectLanguage(rcc_context ctx, rcc_class_id class_id, const } -static int rccIsParrentLanguage(rcc_language_config config, rcc_language_id parrent) { +static int rccIsParrentLanguage(rcc_language_config config, rcc_language_id parent) { unsigned int i; rcc_language_id language; rcc_language_id *list; language = rccConfigGetLanguage(config); - if (parrent == language) return 1; + if (parent == language) return 1; - list = ((rcc_language_internal*)config->language)->parrents; + list = ((rcc_language_internal*)config->language)->parents; for (i=0;list[i] != (rcc_language_id)-1;i++) - if (list[i] == parrent) return 1; + if (list[i] == parent) return 1; return 0; } @@ -349,7 +349,7 @@ static char *rccRecodeTranslate(rcc_language_config *config, rcc_class_id class_ } else current_language_id = rccGetCurrentLanguage(ctx); } - + if (current_language_id == (rcc_language_id)-1) return NULL; if (language_id == current_language_id) return NULL; @@ -357,7 +357,7 @@ static char *rccRecodeTranslate(rcc_language_config *config, rcc_class_id class_ if (!curconfig) return NULL; if (rccConfigConfigure(curconfig)) return NULL; - + if (translate == RCC_OPTION_TRANSLATE_TRANSLITERATE) { if (!strcasecmp((*config)->language->sn, rcc_russian_language_sn)) { translated = rccSizedRecodeCharsets(ctx, "UTF-8", "KOI8-R", utfstring, 0, NULL); @@ -405,7 +405,7 @@ static char *rccRecodeTranslate(rcc_language_config *config, rcc_class_id class_ if (rccAreRelatedLanguages(curconfig, *config)) return NULL; } - if (translate == RCC_OPTION_TRANSLATE_SKIP_PARRENT) { + if (translate == RCC_OPTION_TRANSLATE_SKIP_PARENT) { if (rccIsParrentLanguage(curconfig, language_id)) return NULL; } @@ -770,7 +770,7 @@ char *rccSizedToCharset(rcc_context ctx, const char *charset, rcc_const_string b res = rccStringCheck(buf); if (!res) return NULL; - + icnv = rccIConvOpen(charset, "UTF-8"); if (icnv) { rccMutexLock(ctx->mutex); |