00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "includes.h"
00022
00023 static TDB_CONTEXT *tdb;
00024
00025
00026 static char *current_lang;
00027
00028
00029
00030 static BOOL load_msg(const char *msg_file)
00031 {
00032 char **lines;
00033 int num_lines, i;
00034 char *msgid, *msgstr;
00035 TDB_DATA key, data;
00036
00037 lines = file_lines_load(msg_file, &num_lines,0);
00038
00039 if (!lines) {
00040 return False;
00041 }
00042
00043 if (tdb_lockall(tdb) != 0) {
00044 file_lines_free(lines);
00045 return False;
00046 }
00047
00048
00049 tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
00050
00051 msgid = NULL;
00052
00053 for (i=0;i<num_lines;i++) {
00054 if (strncmp(lines[i], "msgid \"", 7) == 0) {
00055 msgid = lines[i] + 7;
00056 }
00057 if (msgid && strncmp(lines[i], "msgstr \"", 8) == 0) {
00058 msgstr = lines[i] + 8;
00059 trim_char(msgid, '\0', '\"');
00060 trim_char(msgstr, '\0', '\"');
00061 if (*msgstr == 0) {
00062 msgstr = msgid;
00063 }
00064 all_string_sub(msgid, "\\n", "\n", 0);
00065 all_string_sub(msgstr, "\\n", "\n", 0);
00066 key.dptr = msgid;
00067 key.dsize = strlen(msgid)+1;
00068 data.dptr = msgstr;
00069 data.dsize = strlen(msgstr)+1;
00070 tdb_store(tdb, key, data, 0);
00071 msgid = NULL;
00072 }
00073 }
00074
00075 file_lines_free(lines);
00076 tdb_unlockall(tdb);
00077
00078 return True;
00079 }
00080
00081
00082
00083 static const char *get_lang(void)
00084 {
00085 const char *vars[] = {"LANGUAGE", "LC_ALL", "LC_LANG", "LANG", NULL};
00086 int i;
00087 char *p;
00088
00089 for (i=0; vars[i]; i++) {
00090 if ((p = getenv(vars[i]))) {
00091 return p;
00092 }
00093 }
00094
00095 return NULL;
00096 }
00097
00098
00099
00100 BOOL lang_tdb_init(const char *lang)
00101 {
00102 char *path = NULL;
00103 char *msg_path = NULL;
00104 struct stat st;
00105 static int initialised;
00106 time_t loadtime;
00107 BOOL result = False;
00108
00109
00110
00111 if (initialised && !lang)
00112 return True;
00113
00114 if (initialised) {
00115
00116 if (tdb) {
00117 tdb_close(tdb);
00118 tdb = NULL;
00119 }
00120 SAFE_FREE(current_lang);
00121 }
00122
00123 initialised = 1;
00124
00125 if (!lang) {
00126
00127 lang = get_lang();
00128 }
00129
00130
00131 if (!lang)
00132 return True;
00133
00134 asprintf(&msg_path, "%s.msg", lib_path((const char *)lang));
00135 if (stat(msg_path, &st) != 0) {
00136
00137 DEBUG(10, ("lang_tdb_init: %s: %s\n", msg_path,
00138 strerror(errno)));
00139 goto done;
00140 }
00141
00142 asprintf(&path, "%s%s.tdb", lock_path("lang_"), lang);
00143
00144 DEBUG(10, ("lang_tdb_init: loading %s\n", path));
00145
00146 tdb = tdb_open_log(path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0644);
00147 if (!tdb) {
00148 tdb = tdb_open_log(path, 0, TDB_DEFAULT, O_RDONLY, 0);
00149 if (!tdb) {
00150 DEBUG(10, ("lang_tdb_init: %s: %s\n", path,
00151 strerror(errno)));
00152 goto done;
00153 }
00154 current_lang = SMB_STRDUP(lang);
00155 result = True;
00156 goto done;
00157 }
00158
00159 loadtime = tdb_fetch_int32(tdb, "/LOADTIME/");
00160
00161 if (loadtime == -1 || loadtime < st.st_mtime) {
00162 load_msg(msg_path);
00163 tdb_store_int32(tdb, "/LOADTIME/", (int)time(NULL));
00164 }
00165
00166 current_lang = SMB_STRDUP(lang);
00167 result = True;
00168
00169 done:
00170 SAFE_FREE(msg_path);
00171 SAFE_FREE(path);
00172
00173 return result;
00174 }
00175
00176
00177
00178
00179 const char *lang_msg(const char *msgid)
00180 {
00181 TDB_DATA key, data;
00182 const char *p;
00183 char *q, *msgid_quoted;
00184 int count;
00185
00186 lang_tdb_init(NULL);
00187
00188 if (!tdb) return msgid;
00189
00190
00191
00192
00193 count = 0;
00194
00195 for(p = msgid; *p; p++) {
00196 if (*p == '\"')
00197 count++;
00198 }
00199
00200 if (!(msgid_quoted = (char *)SMB_MALLOC(strlen(msgid) + count + 1)))
00201 return msgid;
00202
00203
00204
00205
00206 for(p = msgid, q = msgid_quoted; *p; p++) {
00207 if (*p == '\"') {
00208 *q = '\\';
00209 q++;
00210 }
00211 *q = *p;
00212 q++;
00213 }
00214
00215 *q = 0;
00216
00217 key.dptr = (char *)msgid_quoted;
00218 key.dsize = strlen(msgid_quoted)+1;
00219
00220 data = tdb_fetch(tdb, key);
00221
00222 free(msgid_quoted);
00223
00224
00225
00226 if (!data.dptr)
00227 return SMB_STRDUP(msgid);
00228
00229 return (const char *)data.dptr;
00230 }
00231
00232
00233
00234 void lang_msg_free(const char *msgstr)
00235 {
00236 if (!tdb) return;
00237 free((void *)msgstr);
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247 const char *lang_msg_rotate(const char *msgid)
00248 {
00249 #define NUM_LANG_BUFS 16
00250 char *msgstr;
00251 static pstring bufs[NUM_LANG_BUFS];
00252 static int next;
00253
00254 msgstr = (char *)lang_msg(msgid);
00255 if (!msgstr) return msgid;
00256
00257 pstrcpy(bufs[next], msgstr);
00258 msgstr = bufs[next];
00259
00260 next = (next+1) % NUM_LANG_BUFS;
00261
00262 return msgstr;
00263 }
00264
00265
00266
00267
00268
00269 char *lang_tdb_current(void)
00270 {
00271 return current_lang;
00272 }