diff options
author | Andrew Tridgell <tridge@samba.org> | 2001-10-03 12:18:20 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2001-10-03 12:18:20 +0000 |
commit | 9bcd133e9e7b0cfe974f273fb23409d660af8358 (patch) | |
tree | aed9e919a60602c2a7d9826038a990e51be949cf /source3/intl | |
parent | 5b24e783dd60b01e2cef1e47cc4b181e7cf2bc38 (diff) | |
download | samba-9bcd133e9e7b0cfe974f273fb23409d660af8358.tar.gz samba-9bcd133e9e7b0cfe974f273fb23409d660af8358.tar.bz2 samba-9bcd133e9e7b0cfe974f273fb23409d660af8358.zip |
switched over to a new method of handling uppercase/lowercase mappings
for unicode strings. The new method relies on 3 files that are mmap'd
at startup to provide the mapping tables. The upcase.dat and
lowcase.dat tables should be the same on all systems. The valid.dat
table says what characters are valid in 8.3 names, and differs between
systems. I'm committing the japanese valid.dat here, in future we need
some way of automatically installing and choosing a appropriate table.
This commit also adds my mini tdb based gettext replacement in
intl/lang_tdb.c. I have not enabled this yet and have not removed the
old gettext code as the new code is still being looked at by Monyo.
Right now the code assumes that the upcase.dat, lowcase.dat and
valid.dat files are installed in the Samba lib directory. That is not
a good choice, but I'll leave them there until we work out the new
install directory structure for Samba 3.0.
simo - please look at the isvalid_w() function and think about using
it in your new mangling code. That should be the final step to
correctly passing the chargen test code from monyo.
(This used to be commit 1c221994f118dd542a158b2db51e07d04d0e9314)
Diffstat (limited to 'source3/intl')
-rw-r--r-- | source3/intl/lang_tdb.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/source3/intl/lang_tdb.c b/source3/intl/lang_tdb.c new file mode 100644 index 0000000000..52a84d59a2 --- /dev/null +++ b/source3/intl/lang_tdb.c @@ -0,0 +1,181 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + tdb based replacement for gettext + Copyright (C) Andrew Tridgell 2001 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +static TDB_CONTEXT *tdb; + +/* load a po file into the tdb */ +static BOOL load_po(const char *po_file) +{ + char **lines; + int num_lines, i; + char *msgid, *msgstr; + TDB_DATA key, data; + + lines = file_lines_load(po_file, &num_lines); + + if (!lines) { + return False; + } + + if (tdb_lockall(tdb) != 0) return False; + + /* wipe the db */ + tdb_traverse(tdb, (tdb_traverse_func) tdb_delete, NULL); + + for (i=0;i<num_lines;i++) { + if (strncmp(lines[i], "msgid \"", 7) == 0) { + msgid = lines[i] + 7; + } + if (strncmp(lines[i], "msgstr \"", 8) == 0) { + msgstr = lines[i] + 8; + trim_string(msgid, NULL, "\""); + trim_string(msgstr, NULL, "\""); + if (*msgstr == 0) { + msgstr = msgid; + } + key.dptr = msgid; + key.dsize = strlen(msgid)+1; + data.dptr = msgstr; + data.dsize = strlen(msgstr)+1; + tdb_store(tdb, key, data, 0); + } + } + + file_lines_free(lines); + tdb_unlockall(tdb); + + return True; +} + + +/* work out what language to use from locale variables */ +static char *get_lang(void) +{ + 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; +} + +/* initialise the message translation subsystem */ +void lang_tdb_init(void) +{ + char *lang; + char *path = NULL; + struct stat st; + static int initialised; + time_t loadtime; + + /* we only want to init once per process */ + if (initialised) return; + initialised = 1; + + lang = get_lang(); + + /* if no lang then we don't translate */ + if (!lang) return; + + asprintf(&path, "%s%s.tdb", lock_path("lang_"), lang); + + 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); + free(path); + return; + } + + free(path); + + asprintf(&path, "%s.po", lock_path(lang)); + + loadtime = tdb_fetch_int(tdb, "/LOADTIME/"); + + if (stat(path, &st) == 0 && (loadtime == -1 || loadtime < st.st_mtime)) { + load_po(path); + tdb_store_int(tdb, "/LOADTIME/", (int)time(NULL)); + } + free(path); +} + +/* translate a msgid to a message string in the current language + returns a string that must be freed by calling lang_msg_free() +*/ +const char *lang_msg(const char *msgid) +{ + TDB_DATA key, data; + + lang_tdb_init(); + + if (!tdb) return msgid; + + key.dptr = (char *)msgid; + key.dsize = strlen(msgid)+1; + + data = tdb_fetch(tdb, key); + + /* if the message isn't found then we still need to return a pointer + that can be freed. Pity. */ + if (!data.dptr) return strdup(msgid); + + return (const char *)data.dptr; +} + + +/* free up a string from lang_msg() */ +void lang_msg_free(const char *msgstr) +{ + if (!tdb) return; + free((void *)msgstr); +} + + +/* + when the _() translation macro is used there is no obvious place to free + the resulting string and there is no easy way to give a static pointer. + All we can do is rotate between some static buffers and hope a single d_printf() + doesn't have more calls to _() than the number of buffers +*/ +const char *lang_msg_rotate(const char *msgid) +{ +#define NUM_LANG_BUFS 4 + char *msgstr; + static pstring bufs[NUM_LANG_BUFS]; + static int next; + + msgstr = lang_msg(msgid); + if (!msgstr) return msgid; + + pstrcpy(bufs[next], msgstr); + msgstr = bufs[next]; + + next = (next+1) % NUM_LANG_BUFS; + + return msgstr; +} |