#include "includes.h"
static TDB_CONTEXT *tdb;
static char *current_lang;
static BOOL load_msg(const char *msg_file)
{
char **lines;
int num_lines, i;
char *msgid, *msgstr;
TDB_DATA key, data;
lines = file_lines_load(msg_file, &num_lines,0);
if (!lines) {
return False;
}
if (tdb_lockall(tdb) != 0) {
file_lines_free(lines);
return False;
}
tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
msgid = NULL;
for (i=0;i<num_lines;i++) {
if (strncmp(lines[i], "msgid \"", 7) == 0) {
msgid = lines[i] + 7;
}
if (msgid && strncmp(lines[i], "msgstr \"", 8) == 0) {
msgstr = lines[i] + 8;
trim_char(msgid, '\0', '\"');
trim_char(msgstr, '\0', '\"');
if (*msgstr == 0) {
msgstr = msgid;
}
all_string_sub(msgid, "\\n", "\n", 0);
all_string_sub(msgstr, "\\n", "\n", 0);
key.dptr = msgid;
key.dsize = strlen(msgid)+1;
data.dptr = msgstr;
data.dsize = strlen(msgstr)+1;
tdb_store(tdb, key, data, 0);
msgid = NULL;
}
}
file_lines_free(lines);
tdb_unlockall(tdb);
return True;
}
static const char *get_lang(void)
{
const char *vars[] = {"LANGUAGE", "LC_ALL", "LC_LANG", "LANG", NULL};
int i;
char *p;
for (i=0; vars[i]; i++) {
if ((p = getenv(vars[i]))) {
return p;
}
}
return NULL;
}
BOOL lang_tdb_init(const char *lang)
{
char *path = NULL;
char *msg_path = NULL;
struct stat st;
static int initialised;
time_t loadtime;
BOOL result = False;
if (initialised && !lang)
return True;
if (initialised) {
if (tdb) {
tdb_close(tdb);
tdb = NULL;
}
SAFE_FREE(current_lang);
}
initialised = 1;
if (!lang) {
lang = get_lang();
}
if (!lang)
return True;
asprintf(&msg_path, "%s.msg", lib_path((const char *)lang));
if (stat(msg_path, &st) != 0) {
DEBUG(10, ("lang_tdb_init: %s: %s\n", msg_path,
strerror(errno)));
goto done;
}
asprintf(&path, "%s%s.tdb", lock_path("lang_"), lang);
DEBUG(10, ("lang_tdb_init: loading %s\n", path));
tdb = tdb_open_log(path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644);
if (!tdb) {
tdb = tdb_open_log(path, 0, TDB_DEFAULT, O_RDONLY, 0);
if (!tdb) {
DEBUG(10, ("lang_tdb_init: %s: %s\n", path,
strerror(errno)));
goto done;
}
current_lang = SMB_STRDUP(lang);
result = True;
goto done;
}
loadtime = tdb_fetch_int32(tdb, "/LOADTIME/");
if (loadtime == -1 || loadtime < st.st_mtime) {
load_msg(msg_path);
tdb_store_int32(tdb, "/LOADTIME/", (int)time(NULL));
}
current_lang = SMB_STRDUP(lang);
result = True;
done:
SAFE_FREE(msg_path);
SAFE_FREE(path);
return result;
}
const char *lang_msg(const char *msgid)
{
TDB_DATA key, data;
const char *p;
char *q, *msgid_quoted;
int count;
lang_tdb_init(NULL);
if (!tdb) return msgid;
count = 0;
for(p = msgid; *p; p++) {
if (*p == '\"')
count++;
}
if (!(msgid_quoted = (char *)SMB_MALLOC(strlen(msgid) + count + 1)))
return msgid;
for(p = msgid, q = msgid_quoted; *p; p++) {
if (*p == '\"') {
*q = '\\';
q++;
}
*q = *p;
q++;
}
*q = 0;
key.dptr = (char *)msgid_quoted;
key.dsize = strlen(msgid_quoted)+1;
data = tdb_fetch(tdb, key);
free(msgid_quoted);
if (!data.dptr)
return SMB_STRDUP(msgid);
return (const char *)data.dptr;
}
void lang_msg_free(const char *msgstr)
{
if (!tdb) return;
free((void *)msgstr);
}
const char *lang_msg_rotate(const char *msgid)
{
#define NUM_LANG_BUFS 16
char *msgstr;
static pstring bufs[NUM_LANG_BUFS];
static int next;
msgstr = (char *)lang_msg(msgid);
if (!msgstr) return msgid;
pstrcpy(bufs[next], msgstr);
msgstr = bufs[next];
next = (next+1) % NUM_LANG_BUFS;
return msgstr;
}
char *lang_tdb_current(void)
{
return current_lang;
}