summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am2
-rw-r--r--src/internal.h11
-rw-r--r--src/librcc.c128
-rw-r--r--src/librcc.h41
-rw-r--r--src/lngconfig.c16
-rw-r--r--src/plugin.c1
-rw-r--r--src/rccconfig.c7
-rw-r--r--src/rccconfig.h1
-rw-r--r--src/rccdb4.c33
-rw-r--r--src/rccexternal.c19
-rw-r--r--src/rccexternal.h8
-rw-r--r--src/rcchome.c52
-rw-r--r--src/rcchome.h8
-rw-r--r--src/rcclock.c108
-rw-r--r--src/rcclock.h12
-rw-r--r--src/rccspell.c26
-rw-r--r--src/rccspell.h2
-rw-r--r--src/rcctranslate.c4
-rw-r--r--src/rccxml.c15
-rw-r--r--src/recode.c26
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);