2
Copyright 1985, 1986, 1987, 1991, 1998 The Open Group
4
Portions Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
6
Permission is hereby granted, free of charge, to any person obtaining a
7
copy of this software and associated documentation files (the
8
"Software"), to deal in the Software without restriction, including
9
without limitation the rights to use, copy, modify, merge, publish,
10
distribute, sublicense, and/or sell copies of the Software, and to
11
permit persons to whom the Software is furnished to do so, subject to
12
the following conditions: The above copyright notice and this
13
permission notice shall be included in all copies or substantial
14
portions of the Software.
17
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18
OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
20
IN NO EVENT SHALL THE OPEN GROUP OR SUN MICROSYSTEMS, INC. BE LIABLE
21
FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
22
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
23
THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE EVEN IF
24
ADVISED IN ADVANCE OF THE POSSIBILITY OF SUCH DAMAGES.
27
Except as contained in this notice, the names of The Open Group and/or
28
Sun Microsystems, Inc. shall not be used in advertising or otherwise to
29
promote the sale, use or other dealings in this Software without prior
30
written authorization from The Open Group and/or Sun Microsystems,
34
X Window System is a trademark of The Open Group
36
OSF/1, OSF/Motif and Motif are registered trademarks, and OSF, the OSF
37
logo, LBX, X Window System, and Xinerama are trademarks of the Open
38
Group. All other trademarks and registered trademarks mentioned herein
39
are the property of their respective owners. No right, title or
40
interest in or to any trademark, service mark, logo or trade name of
41
Sun Microsystems, Inc. or its licensors is granted.
44
/* $XFree86: xc/lib/X11/XlcDL.c,v 1.9 2002/11/25 14:04:53 eich Exp $ */
55
#include "XlcPublic.h"
59
# if defined(__sparcv9)
60
# define _MACH64_NAME "sparcv9"
61
# elif defined(__ia64__)
64
# error "Unknown architecture"
65
# endif /* defined(__sparcv9) */
67
# define _MACH64_NAME_LEN (sizeof (_MACH64_NAME) - 1)
73
#define iscomment(ch) ((ch) == '\0' || (ch) == '#')
90
unsigned int refcount;
96
} XI18NObjectsListRec, *XI18NObjectsList;
98
#define OBJECT_INIT_LEN 8
99
#define OBJECT_INC_LEN 4
100
static int lc_len = 0;
101
static XI18NObjectsListRec *xi18n_objects_list = NULL;
102
static int lc_count = 0;
105
parse_line(line, argv, argsize)
113
while (argc < argsize) {
114
while (isspace(*p)) {
121
while (!isspace(*p)) {
133
strdup_with_underscore(const char *symbol)
137
if ((result = malloc(strlen(symbol) + 2)) == NULL)
140
strcpy(result + 1, symbol);
146
try_both_dlsym (void *handle, char *name)
150
ret = dlsym (handle, name);
153
name = strdup_with_underscore (name);
156
ret = dlsym (handle, name);
165
resolve_object(path, lc_name)
169
char filename[BUFSIZ];
173
if (lc_len == 0) { /* True only for the 1st time */
174
lc_len = OBJECT_INIT_LEN;
175
xi18n_objects_list = (XI18NObjectsList)
176
Xmalloc(sizeof(XI18NObjectsListRec) * lc_len);
177
if (!xi18n_objects_list) return;
181
Limit the length of path to prevent stack buffer corruption.
182
sprintf(filename, "%s/%s", path, "XI18N_OBJS");
184
sprintf(filename, "%.*s/%s", BUFSIZ - 12, path, "XI18N_OBJS");
185
fp = fopen(filename, "r");
186
if (fp == (FILE *)NULL){
190
while (fgets(buf, BUFSIZ, fp) != NULL){
201
if (lc_count == lc_len) {
202
lc_len += OBJECT_INC_LEN;
203
xi18n_objects_list = (XI18NObjectsList)
204
Xrealloc(xi18n_objects_list,
205
sizeof(XI18NObjectsListRec) * lc_len);
206
if (!xi18n_objects_list) return;
208
n = parse_line(p, args, 6);
210
if (n == 3 || n == 5) {
211
if (!strcmp(args[0], "XLC")){
212
xi18n_objects_list[lc_count].type = XLC_OBJECT;
213
} else if (!strcmp(args[0], "XOM")){
214
xi18n_objects_list[lc_count].type = XOM_OBJECT;
215
} else if (!strcmp(args[0], "XIM")){
216
xi18n_objects_list[lc_count].type = XIM_OBJECT;
218
xi18n_objects_list[lc_count].dl_name = strdup(args[1]);
219
xi18n_objects_list[lc_count].open = strdup(args[2]);
220
xi18n_objects_list[lc_count].dl_release = XI18N_DLREL;
221
xi18n_objects_list[lc_count].locale_name = strdup(lc_name);
222
xi18n_objects_list[lc_count].refcount = 0;
223
xi18n_objects_list[lc_count].dl_module = (void*)NULL;
225
xi18n_objects_list[lc_count].im_register = strdup(args[3]);
226
xi18n_objects_list[lc_count].im_unregister = strdup(args[4]);
228
xi18n_objects_list[lc_count].im_register = NULL;
229
xi18n_objects_list[lc_count].im_unregister = NULL;
238
__lc_path(dl_name, lc_dir)
246
* reject this for possible security issue
248
if (strstr (dl_name, "../"))
251
#if defined (_LP64) && defined (_MACH64_NAME)
252
len = (lc_dir ? strlen(lc_dir) : 0 ) +
253
(dl_name ? strlen(dl_name) : 0) + _MACH64_NAME_LEN + 10;
254
path = Xmalloc(len + 1);
256
if (strchr(dl_name, '/') != NULL) {
257
char *tmp = strdup(dl_name);
258
char *dl_dir, *dl_file;
260
slash_p = strchr(tmp, '/');
265
slash_p = strrchr(lc_dir, '/');
267
strcpy(path, lc_dir); strcat(path, "/");
268
strcat(path, dl_dir); strcat(path, "/");
269
strcat(path, _MACH64_NAME); strcat(path, "/");
270
strcat(path, dl_file); strcat(path, ".so.2");
275
strcpy(path, lc_dir); strcat(path, "/");
276
strcat(path, _MACH64_NAME); strcat(path, "/");
277
strcat(path, dl_name); strcat(path, ".so.2");
280
len = (lc_dir ? strlen(lc_dir) : 0 ) +
281
(dl_name ? strlen(dl_name) : 0) + 10;
282
#if defined POSTLOCALELIBDIR
283
len += (strlen(POSTLOCALELIBDIR) + 1);
285
path = Xmalloc(len + 1);
287
if (strchr(dl_name, '/') != NULL) {
289
slash_p = strrchr(lc_dir, '/');
291
strcpy(path, lc_dir); strcat(path, "/");
292
#if defined POSTLOCALELIBDIR
293
strcat(path, POSTLOCALELIBDIR); strcat(path, "/");
295
strcat(path, dl_name); strcat(path, ".so.2");
298
strcpy(path, lc_dir); strcat(path, "/");
299
#if defined POSTLOCALELIBDIR
300
strcat(path, POSTLOCALELIBDIR); strcat(path, "/");
302
strcat(path, dl_name); strcat(path, ".so.2");
308
/* We reference count dlopen() and dlclose() of modules; unfortunately,
309
* since XCloseIM, XCloseOM, XlcClose aren't wrapped, but directly
310
* call the close method of the object, we leak a reference count every
311
* time we open then close a module. Fixing this would require
312
* either creating proxy objects or hooks for close_im/close_om
316
open_object (object, lc_dir)
317
XI18NObjectsList object;
322
if (object->refcount == 0) {
323
path = __lc_path(object->dl_name, lc_dir);
327
object->dl_module = shl_load(path, BIND_DEFERRED, 0L);
329
object->dl_module = dlopen(path, RTLD_LAZY);
333
if (!object->dl_module)
342
fetch_symbol (object, symbol)
343
XI18NObjectsList object;
349
struct shl_symbol *symbols;
356
getsyms_cnt = shl_getsymbols(object->dl_module, TYPE_PROCEDURE,
357
EXPORT_SYMBOLS, malloc, &symbols);
359
for(i=0; i<getsyms_cnt; i++) {
360
if(!strcmp(symbols[i].name, symbol)) {
361
result = symbols[i].value;
366
if(getsyms_cnt > 0) {
370
result = try_both_dlsym(object->dl_module, symbol);
377
close_object (object)
378
XI18NObjectsList object;
381
if (object->refcount == 0)
384
shl_unload(object->dl_module);
386
dlclose(object->dl_module);
388
object->dl_module = NULL;
394
#if NeedFunctionPrototypes
395
_XlcDynamicLoad(const char *lc_name)
397
_XlcDynamicLoad(lc_name)
401
XLCd lcd = (XLCd)NULL;
402
XLCd (*lc_loader)() = (XLCd(*)())NULL;
404
XI18NObjectsList objects_list;
405
char lc_dir[BUFSIZE];
407
if (lc_name == NULL) return (XLCd)NULL;
409
if (_XlcLocaleDirName(lc_dir, (char *)lc_name) == (char*)NULL)
412
resolve_object(lc_dir, lc_name);
414
objects_list = xi18n_objects_list;
416
for (; count-- > 0; objects_list++) {
417
if (objects_list->type != XLC_OBJECT ||
418
strcmp(objects_list->locale_name, lc_name)) continue;
419
if (!open_object (objects_list, lc_dir))
422
lc_loader = (XLCd(*)())fetch_symbol (objects_list, objects_list->open);
423
if (!lc_loader) continue;
424
lcd = (*lc_loader)(lc_name);
425
if (lcd != (XLCd)NULL) {
429
close_object (objects_list);
435
#if NeedFunctionPrototypes
436
_XDynamicOpenIM(XLCd lcd, Display *display, XrmDatabase rdb,
437
char *res_name, char *res_class)
439
_XDynamicOpenIM(lcd, display, rdb, res_name, res_class)
443
char *res_name, *res_class;
447
char lc_dir[BUFSIZE];
449
XIM (*im_openIM)() = (XIM(*)())NULL;
451
XI18NObjectsList objects_list = xi18n_objects_list;
453
lc_name = lcd->core->name;
455
if (_XlcLocaleDirName(lc_dir, lc_name) == NULL) return (XIM)0;
458
for (; count-- > 0; objects_list++) {
459
if (objects_list->type != XIM_OBJECT ||
460
strcmp(objects_list->locale_name, lc_name)) continue;
462
if (!open_object (objects_list, lc_dir))
465
im_openIM = (XIM(*)())fetch_symbol(objects_list, objects_list->open);
466
if (!im_openIM) continue;
467
im = (*im_openIM)(lcd, display, rdb, res_name, res_class);
468
if (im != (XIM)NULL) {
472
close_object (objects_list);
478
_XDynamicRegisterIMInstantiateCallback(lcd, display, rdb,
480
callback, client_data)
484
char *res_name, *res_class;
486
XPointer *client_data;
488
char lc_dir[BUFSIZE];
490
Bool (*im_registerIM)() = (Bool(*)())NULL;
491
Bool ret_flag = False;
493
XI18NObjectsList objects_list = xi18n_objects_list;
496
struct shl_symbol *symbols;
499
lc_name = lcd->core->name;
501
if (_XlcLocaleDirName(lc_dir, lc_name) == NULL) return False;
504
for (; count-- > 0; objects_list++) {
505
if (objects_list->type != XIM_OBJECT ||
506
strcmp(objects_list->locale_name, lc_name)) continue;
508
if (!open_object (objects_list, lc_dir))
510
im_registerIM = (Bool(*)())fetch_symbol(objects_list,
511
objects_list->im_register);
512
if (!im_registerIM) continue;
513
ret_flag = (*im_registerIM)(lcd, display, rdb,
515
callback, client_data);
518
close_object (objects_list);
520
return (Bool)ret_flag;
524
_XDynamicUnRegisterIMInstantiateCallback(lcd, display, rdb,
526
callback, client_data)
530
char *res_name, *res_class;
532
XPointer *client_data;
534
char lc_dir[BUFSIZE];
536
Bool (*im_unregisterIM)() = (Bool(*)())NULL;
537
Bool ret_flag = False;
539
XI18NObjectsList objects_list = xi18n_objects_list;
542
struct shl_symbol *symbols;
545
lc_name = lcd->core->name;
546
if (_XlcLocaleDirName(lc_dir, lc_name) == NULL) return False;
549
for (; count-- > 0; objects_list++) {
550
if (objects_list->type != XIM_OBJECT ||
551
strcmp(objects_list->locale_name, lc_name)) continue;
553
if (!objects_list->refcount) /* Must already be opened */
556
im_unregisterIM = (Bool(*)())fetch_symbol(objects_list,
557
objects_list->im_unregister);
559
if (!im_unregisterIM) continue;
560
ret_flag = (*im_unregisterIM)(lcd, display, rdb,
562
callback, client_data);
564
close_object (objects_list); /* opened in RegisterIMInstantiateCallback */
568
return (Bool)ret_flag;
572
#if NeedFunctionPrototypes
573
_XInitDynamicIM(XLCd lcd)
579
if(lcd == (XLCd)NULL)
581
lcd->methods->open_im = _XDynamicOpenIM;
582
lcd->methods->register_callback = _XDynamicRegisterIMInstantiateCallback;
583
lcd->methods->unregister_callback = _XDynamicUnRegisterIMInstantiateCallback;
588
#if NeedFunctionPrototypes
589
_XDynamicOpenOM(XLCd lcd, Display *display, XrmDatabase rdb,
590
_Xconst char *res_name, _Xconst char *res_class)
592
_XDynamicOpenOM(lcd, display, rdb, res_name, res_class)
602
char lc_dir[BUFSIZE];
604
XOM (*om_openOM)() = (XOM(*)())NULL;
605
XI18NObjectsList objects_list = xi18n_objects_list;
608
struct shl_symbol *symbols;
611
lc_name = lcd->core->name;
613
if (_XlcLocaleDirName(lc_dir, lc_name) == NULL) return (XOM)0;
616
for (; count-- > 0; objects_list++) {
617
if (objects_list->type != XOM_OBJECT ||
618
strcmp(objects_list->locale_name, lc_name)) continue;
619
if (!open_object (objects_list, lc_dir))
622
om_openOM = (XOM(*)())fetch_symbol(objects_list, objects_list->open);
623
if (!om_openOM) continue;
624
om = (*om_openOM)(lcd, display, rdb, res_name, res_class);
625
if (om != (XOM)NULL) {
628
close_object(objects_list);
634
#if NeedFunctionPrototypes
635
_XInitDynamicOM(XLCd lcd)
641
if(lcd == (XLCd)NULL)
644
lcd->methods->open_om = _XDynamicOpenOM;