summaryrefslogtreecommitdiffstats
path: root/external
diff options
context:
space:
mode:
Diffstat (limited to 'external')
-rw-r--r--external/Makefile.am12
-rw-r--r--external/rccexternal.c117
-rw-r--r--external/rcclibtranslate.c286
-rw-r--r--external/rcclibtranslate.h9
4 files changed, 424 insertions, 0 deletions
diff --git a/external/Makefile.am b/external/Makefile.am
new file mode 100644
index 0000000..68d2988
--- /dev/null
+++ b/external/Makefile.am
@@ -0,0 +1,12 @@
+if HAVE_GLIB2
+bin_PROGRAMS= rccexternal
+endif
+
+bindir = $(pkgdatadir)/
+
+rccexternal_SOURCES= rccexternal.c \
+ rcclibtranslate.c rcclibtranslate.h \
+ ../src/rccdb4.c ../src/rccdb4.h
+
+rccexternal_LDADD= @GLIB2_LIBS@ @LIBTRANSLATE_LIBS@ @BDB_LIBS@
+AM_CPPFLAGS = @GLIB2_CFLAGS@ @LIBTRANSLATE_CFLAGS@ @BDB_INCLUDES@ -I../src
diff --git a/external/rccexternal.c b/external/rccexternal.c
new file mode 100644
index 0000000..47f628a
--- /dev/null
+++ b/external/rccexternal.c
@@ -0,0 +1,117 @@
+#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_PWD_H
+# include <pwd.h>
+#endif /* HAVE_PWD_H */
+
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif /* HAVE_SYS_TYPES_H */
+#ifdef HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif /* HAVE_SYS_SOCKET_H */
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif /* HAVE_SYS_STAT_H */
+#ifdef HAVE_SYS_UN_H
+# include <sys/un.h>
+#endif /* HAVE_SYS_UN_H */
+
+#include <glib/gthread.h>
+
+#include "../src/rccexternal.h"
+#include "rcclibtranslate.h"
+
+
+int main() {
+ int s, sd;
+ char addr[376];
+ const char *rcc_home_dir;
+ struct sockaddr_un mysock, clisock;
+ socklen_t socksize;
+ pid_t mypid;
+
+ unsigned char loopflag = 1;
+
+ rcc_external_info info;
+ ssize_t readed;
+ unsigned char cmd;
+
+#ifdef HAVE_PWD_H
+ struct passwd *pw;
+#endif /* HAVE_PWD_H */
+
+ mypid = getpid();
+
+ rcc_home_dir = getenv ("HOME");
+#ifdef HAVE_PWD_H
+ if (!rcc_home_dir) {
+ setpwent ();
+ pw = getpwuid(getuid ());
+ endpwent ();
+ if ((pw)&&(pw->pw_dir)) rcc_home_dir = pw->pw_dir;
+ }
+#endif /* HAVE_PWD_H */
+ if (strlen(rcc_home_dir)>256) return -1;
+ if (!rcc_home_dir) rcc_home_dir = "/";
+
+ rccLibTranslateInit(rcc_home_dir);
+
+ sprintf(addr,"%s/.rcc/comm/",rcc_home_dir);
+ mkdir(addr, 00600);
+ sprintf(addr,"%s/.rcc/comm/%lu.sock", rcc_home_dir, (unsigned long)mypid);
+
+ s = socket(PF_UNIX, SOCK_STREAM, 0);
+ if (!s) return -1;
+
+ memset(&mysock, 0, sizeof(mysock));
+ mysock.sun_family=AF_UNIX;
+ strncpy(mysock.sun_path,addr,sizeof(mysock.sun_path));
+ mysock.sun_path[sizeof(mysock.sun_path)-1]=0;
+
+ unlink(addr);
+ if (bind(s,(struct sockaddr*)&mysock,sizeof(mysock))==-1) return -1;
+ if (listen(s,1)<0) {
+ unlink(addr);
+ return -1;
+ }
+
+ while (loopflag) {
+ sd = accept(s,(struct sockaddr*)&clisock,&socksize);
+ if (sd < 0) continue;
+
+ readed = recv(sd,&cmd,1,0);
+ if (readed<=0) {
+ close(sd);
+ continue;
+ }
+
+ switch (cmd) {
+ case RCC_EXTERNAL_MODULE_CONTROL:
+ loopflag = 0;
+ break;
+ case RCC_EXTERNAL_MODULE_LIBRTRANSLATE:
+ info = (rcc_external_info)malloc(sizeof(rcc_external_info_s));
+ if (info) info->s = sd;
+ else break;
+ if (g_thread_create(rccLibTranslate, info, FALSE, NULL)) continue;
+ break;
+ }
+ close(sd);
+ }
+
+ close(s);
+ unlink(addr);
+
+ rccLibTranslateFree();
+
+ return 0;
+}
diff --git a/external/rcclibtranslate.c b/external/rcclibtranslate.c
new file mode 100644
index 0000000..56ce8a2
--- /dev/null
+++ b/external/rcclibtranslate.c
@@ -0,0 +1,286 @@
+#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_LIBTRANSLATE
+#include <translate.h>
+#endif /* HAVE_LIBTRANSLATE */
+
+#include "../src/rccexternal.h"
+#include "../src/rcctranslate.h"
+#include "../src/rccdb4.h"
+#include "rcclibtranslate.h"
+
+
+#ifdef HAVE_LIBTRANSLATE
+static TranslateSession *session = NULL;
+static db4_context db4ctx = NULL;
+
+static int exitflag = 0;
+static GMutex *mutex = NULL;
+static GCond *cond = NULL;
+static GQueue *queue = NULL;
+static GThread *thread = NULL;
+
+
+static char *rccCreateKey(const char *from, const char *to, const char *data, size_t *keysize) {
+ char *res;
+
+ *keysize = strlen(data) + 4;
+ res = (char*)malloc((*keysize+1)*sizeof(char));
+ if (res) sprintf(res,"%s%s%s",from,to,data);
+ return res;
+}
+
+static void *rccLibPostponed(void *info) {
+ char *result;
+ char *data;
+ char from[3];
+ char to[3];
+
+ from[2] = 0;
+ to[2] = 0;
+
+ g_mutex_lock(mutex);
+ while (!exitflag) {
+ data = (char*)g_queue_pop_head(queue);
+ if (data) {
+ g_mutex_unlock(mutex);
+
+ memcpy(from, data, 2);
+ memcpy(to, data + 2, 2);
+ result = translate_session_translate_text(session, data + 4, from, to, NULL, NULL, NULL);
+
+ if (result) {
+ rccDb4SetKey(db4ctx, data, strlen(data), result);
+ free(result);
+ }
+
+ free(data);
+ g_mutex_lock(mutex);
+ } else {
+ g_cond_wait(cond, mutex);
+ }
+ }
+ g_mutex_unlock(mutex);
+ return NULL;
+}
+
+#endif /* HAVE_LIBTRANSLATE */
+
+
+int rccLibTranslateInit(const char *rcc_home_dir) {
+#ifdef HAVE_LIBTRANSLATE
+ size_t size;
+ char *dbname;
+ GSList *list = NULL;
+
+ const char *http_proxy;
+
+ if (!translate_init(NULL)) return -1;
+
+ http_proxy = getenv("HTTP_PROXY");
+ if (!http_proxy) http_proxy = getenv("http_proxy");
+ translate_set_proxy(http_proxy);
+
+ list = translate_get_services();
+
+ session = translate_session_new(list);
+
+ g_slist_foreach(list, (GFunc) g_object_unref, NULL);
+ g_slist_free(list);
+
+
+ size = strlen(rcc_home_dir) + 32;
+ dbname = (char*)malloc(size*sizeof(char));
+ if (dbname) {
+ sprintf(dbname,"%s/.rcc/",rcc_home_dir);
+ mkdir(dbname, 00644);
+
+ sprintf(dbname,"%s/.rcc/libtranslate.db/",rcc_home_dir);
+ mkdir(dbname, 00644);
+
+ db4ctx = rccDb4CreateContext(dbname, 0);
+ free(dbname);
+ }
+ if (db4ctx) {
+ mutex = g_mutex_new();
+ cond = g_cond_new();
+ if ((mutex)&&(cond))
+ queue = g_queue_new();
+ if (queue)
+ thread = g_thread_create(rccLibPostponed, NULL, TRUE, NULL);
+ }
+#endif /* HAVE_LIBTRANSLATE */
+
+ return 0;
+}
+
+void rccLibTranslateFree() {
+#ifdef HAVE_LIBTRANSLATE
+ char *ptr;
+ if (session) {
+ if (thread) {
+ exitflag = 1;
+ g_cond_signal(cond);
+ g_thread_join(thread);
+ thread = NULL;
+ exitflag = 0;
+ }
+ if (queue) {
+ do {
+ ptr = g_queue_pop_head(queue);
+ if (ptr) free(ptr);
+ } while (ptr);
+ g_queue_free(queue);
+ queue = NULL;
+ }
+ if (mutex) {
+ g_mutex_free(mutex);
+ mutex = NULL;
+ }
+ if (cond) {
+ g_cond_free(cond);
+ cond = NULL;
+ }
+ if (db4ctx) rccDb4FreeContext(db4ctx);
+ g_object_unref(session);
+ session = NULL;
+ }
+#endif /* HAVE_LIBTRANSLATE */
+}
+
+
+static char *rccLibTranslateDo(const char *from, const char *to, const char *text, unsigned long timeout) {
+#ifdef HAVE_LIBTRANSLATE
+ char *result;
+ char *key = NULL;
+ size_t keysize;
+
+ if ((!session)||(!from)||(!to)||(!text)) return NULL;
+ if ((strlen(from)!=2)||(strlen(to)!=2)) return NULL;
+
+ if (db4ctx) {
+ key = rccCreateKey(from,to,text,&keysize);
+ if (key) {
+ result = rccDb4GetKey(db4ctx, key, keysize);
+ if (result) {
+ free(key);
+ return result;
+ }
+ }
+ }
+# ifdef HAVE_LIBTRANSLATE_TIMED_TRANSLATE
+ result = translate_session_timed_translate_text(session, text, from, to, timeout, NULL, NULL, NULL);
+# else
+ result = translate_session_translate_text(session, text, from, to, NULL, NULL, NULL);
+# endif /* HAVE_LIBTRANSLATE_TIMED_TRANSLATE */
+
+ if ((db4ctx)&&(key)) {
+ if (result) {
+ rccDb4SetKey(db4ctx, key, keysize, result);
+ free(key);
+ }
+ else {
+ g_mutex_lock(mutex);
+ g_queue_push_tail(queue, key);
+ g_mutex_unlock(mutex);
+ g_cond_signal(cond);
+ }
+ }
+
+ return result;
+#else
+ return NULL;
+#endif /* HAVE_LIBTRANSLATE */
+}
+
+
+void *rccLibTranslate(void *info) {
+ int s;
+#ifdef HAVE_LIBTRANSLATE
+ unsigned char connected = 1;
+ rcc_translate_prefix_s prefix;
+ ssize_t readed, writed, res;
+ char *buffer;
+ size_t size;
+ char *translated = NULL;
+#endif /* HAVE_LIBTRANSLATE */
+
+ if (!info) return NULL;
+
+ s = ((rcc_external_info)info)->s;
+ free(info);
+
+#ifdef HAVE_LIBTRANSLATE
+ while (connected) {
+ readed = read(s, &prefix, sizeof(rcc_translate_prefix_s)-1);
+ if ((readed<=0)||(readed != (sizeof(rcc_translate_prefix_s)-1))) break;
+
+ switch (prefix.cmd.cmd) {
+ case RCC_EXTERNAL_COMMAND_CLOSE:
+ connected = 0;
+ break;
+ case RCC_EXTERNAL_COMMAND_TRANSLATE:
+ size = 1 + prefix.cmd.size + sizeof(rcc_external_command_s) - sizeof(rcc_translate_prefix_s);
+ buffer = (char*)malloc(size);
+ if (buffer) {
+ for (readed = 0; (readed < size)&&(connected); readed += res) {
+ res = read(s, buffer + readed, size - readed);
+ if (res<=0) connected = 0;
+ }
+
+ prefix.cmd.cmd = 0;
+ prefix.cmd.size = 0;
+
+ if ((prefix.from[2])||(prefix.to[2])||(buffer[readed-1])) goto respond;
+
+ translated = rccLibTranslateDo(prefix.from, prefix.to, buffer, prefix.timeout);
+ if (translated) {
+ prefix.cmd.cmd = RCC_EXTERNAL_COMMAND_TRANSLATE;
+ prefix.cmd.size = strlen(translated) + 1;
+ }
+
+respond:
+ res = write(s, &prefix.cmd, sizeof(rcc_external_command_s));
+ if (res == sizeof(rcc_external_command_s)) {
+ for (writed = 0; (writed < prefix.cmd.size)&&(connected); writed += res) {
+ res = write(s, translated + writed, prefix.cmd.size - writed);
+ if (res<=0) connected = 0;
+ }
+ } else connected = 0;
+
+ if (prefix.cmd.size) free(translated);
+ free(buffer);
+ } else connected = 0;
+ break;
+ default:
+ buffer = (char*)malloc(prefix.cmd.size);
+ if (buffer) {
+ for (readed = 0; (readed < prefix.cmd.size)&&(connected); readed += res) {
+ res = read(s, buffer + readed, prefix.cmd.size - readed);
+ if (res<=0) connected = 0;
+ }
+ free(buffer);
+ } else connected = 0;
+ }
+ }
+#endif /* HAVE_LIBTRANSLATE */
+
+ close(s);
+ return NULL;
+}
+
diff --git a/external/rcclibtranslate.h b/external/rcclibtranslate.h
new file mode 100644
index 0000000..f54f5e6
--- /dev/null
+++ b/external/rcclibtranslate.h
@@ -0,0 +1,9 @@
+#ifndef _RCC_LIBTRANSLATE_H
+#define _RCC_LIBTRANSLATE_H
+
+int rccLibTranslateInit(const char *rcc_home_dir);
+void rccLibTranslateFree();
+
+void *rccLibTranslate(void *info);
+
+#endif /* _RCC_LIBTRANSLATE_H */