~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/lib/X11/XlcDL.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright 1985, 1986, 1987, 1991, 1998  The Open Group
 
3
 
 
4
Portions Copyright 2000 Sun Microsystems, Inc. All Rights Reserved.
 
5
 
 
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.
 
15
 
 
16
 
 
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.
 
25
 
 
26
 
 
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,
 
31
Inc., as applicable.
 
32
 
 
33
 
 
34
X Window System is a trademark of The Open Group
 
35
 
 
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.
 
42
 
 
43
*/
 
44
/* $XFree86: xc/lib/X11/XlcDL.c,v 1.9 2002/11/25 14:04:53 eich Exp $ */
 
45
 
 
46
#include <stdio.h>
 
47
#if defined(hpux)
 
48
#include <dl.h>
 
49
#else
 
50
#include <dlfcn.h>
 
51
#endif
 
52
#include <ctype.h>
 
53
 
 
54
#include "Xlibint.h"
 
55
#include "XlcPublic.h"
 
56
#include "XlcPubI.h"
 
57
 
 
58
#ifdef _LP64
 
59
# if defined(__sparcv9)
 
60
#  define       _MACH64_NAME            "sparcv9"
 
61
# elif defined(__ia64__) 
 
62
#  undef MACH64_NAME
 
63
# else
 
64
#  error "Unknown architecture"
 
65
# endif /* defined(__sparcv9) */
 
66
# ifdef _MACH64_NAME
 
67
#  define       _MACH64_NAME_LEN        (sizeof (_MACH64_NAME) - 1)
 
68
# endif
 
69
#endif /* _LP64 */
 
70
 
 
71
#define XI18N_DLREL             2
 
72
 
 
73
#define iscomment(ch)   ((ch) == '\0' || (ch) == '#')
 
74
 
 
75
typedef enum {
 
76
  XLC_OBJECT,
 
77
  XIM_OBJECT,
 
78
  XOM_OBJECT
 
79
} XI18NDLType;
 
80
 
 
81
typedef struct {
 
82
  XI18NDLType type;
 
83
  int   locale_name_len;
 
84
  char *locale_name;
 
85
  char *dl_name;
 
86
  char *open;
 
87
  char *im_register;
 
88
  char *im_unregister;
 
89
  int dl_release;
 
90
  unsigned int refcount;
 
91
#if defined(hpux)
 
92
  shl_t dl_module;
 
93
#else
 
94
  void *dl_module;
 
95
#endif
 
96
} XI18NObjectsListRec, *XI18NObjectsList;
 
97
 
 
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;
 
103
 
 
104
static int
 
105
parse_line(line, argv, argsize)
 
106
char *line;
 
107
char **argv;
 
108
int argsize;
 
109
{
 
110
    int argc = 0;
 
111
    char *p = line;
 
112
 
 
113
    while (argc < argsize) {
 
114
        while (isspace(*p)) {
 
115
            ++p;
 
116
        }
 
117
        if (iscomment(*p)){
 
118
            break;
 
119
        }
 
120
        argv[argc++] = p;
 
121
        while (!isspace(*p)) {
 
122
            ++p;
 
123
        }
 
124
        if (iscomment(*p)) {
 
125
            break;
 
126
        }
 
127
        *p++ = '\0';
 
128
    }
 
129
    return argc;
 
130
}
 
131
 
 
132
static char *
 
133
strdup_with_underscore(const char *symbol)
 
134
{
 
135
        char *result;
 
136
 
 
137
        if ((result = malloc(strlen(symbol) + 2)) == NULL) 
 
138
                return NULL;
 
139
        result[0] = '_';
 
140
        strcpy(result + 1, symbol);
 
141
        return result;
 
142
}
 
143
 
 
144
#ifndef hpux
 
145
static void *
 
146
try_both_dlsym (void *handle, char *name)
 
147
{
 
148
    void    *ret;
 
149
 
 
150
    ret = dlsym (handle, name);
 
151
    if (!ret)
 
152
    {
 
153
         name = strdup_with_underscore (name);
 
154
         if (name)
 
155
         {
 
156
             ret = dlsym (handle, name);
 
157
             free (name);
 
158
         }
 
159
    }
 
160
    return ret;
 
161
}
 
162
#endif
 
163
 
 
164
static void
 
165
resolve_object(path, lc_name)
 
166
char *path;
 
167
char *lc_name;
 
168
{
 
169
    char filename[BUFSIZ];
 
170
    FILE *fp;
 
171
    char buf[BUFSIZ];
 
172
 
 
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;
 
178
    }
 
179
/*
 
180
1266793
 
181
Limit the length of path to prevent stack buffer corruption.
 
182
    sprintf(filename, "%s/%s", path, "XI18N_OBJS");
 
183
*/
 
184
    sprintf(filename, "%.*s/%s", BUFSIZ - 12, path, "XI18N_OBJS");
 
185
    fp = fopen(filename, "r");
 
186
    if (fp == (FILE *)NULL){
 
187
        return;
 
188
    }
 
189
 
 
190
    while (fgets(buf, BUFSIZ, fp) != NULL){
 
191
        char *p = buf;
 
192
        int n;
 
193
        char *args[6];
 
194
        while (isspace(*p)){
 
195
            ++p;
 
196
        }
 
197
        if (iscomment(*p)){
 
198
            continue;
 
199
        }
 
200
 
 
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;
 
207
        }
 
208
        n = parse_line(p, args, 6);
 
209
        
 
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;
 
217
          }
 
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;
 
224
          if (n == 5) {
 
225
            xi18n_objects_list[lc_count].im_register = strdup(args[3]);
 
226
            xi18n_objects_list[lc_count].im_unregister = strdup(args[4]);
 
227
          } else {
 
228
            xi18n_objects_list[lc_count].im_register = NULL;
 
229
            xi18n_objects_list[lc_count].im_unregister = NULL;
 
230
          }
 
231
          lc_count++;
 
232
        }
 
233
    }
 
234
    fclose(fp);
 
235
}
 
236
 
 
237
static char*
 
238
__lc_path(dl_name, lc_dir)
 
239
const char *dl_name;
 
240
const char *lc_dir;
 
241
{
 
242
    char *path;
 
243
    size_t len;
 
244
 
 
245
    /*
 
246
     * reject this for possible security issue
 
247
     */
 
248
    if (strstr (dl_name, "../"))
 
249
        return NULL;
 
250
 
 
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);
 
255
 
 
256
    if (strchr(dl_name, '/') != NULL) {
 
257
        char *tmp = strdup(dl_name);
 
258
        char *dl_dir, *dl_file;
 
259
        char *slash_p;
 
260
        slash_p = strchr(tmp, '/');
 
261
        *slash_p = '\0';
 
262
        dl_dir = tmp;
 
263
        dl_file = ++slash_p;
 
264
 
 
265
        slash_p = strrchr(lc_dir, '/');
 
266
        *slash_p = '\0';
 
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");
 
271
 
 
272
        *slash_p = '/';
 
273
        Xfree(tmp);
 
274
    } else {
 
275
        strcpy(path, lc_dir); strcat(path, "/");
 
276
        strcat(path, _MACH64_NAME); strcat(path, "/");
 
277
        strcat(path, dl_name); strcat(path, ".so.2");
 
278
    }
 
279
#else
 
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);
 
284
#endif
 
285
    path = Xmalloc(len + 1);
 
286
 
 
287
    if (strchr(dl_name, '/') != NULL) {
 
288
        char *slash_p;
 
289
        slash_p = strrchr(lc_dir, '/');
 
290
        *slash_p = '\0';
 
291
        strcpy(path, lc_dir); strcat(path, "/");
 
292
#if defined POSTLOCALELIBDIR
 
293
        strcat(path, POSTLOCALELIBDIR); strcat(path, "/");
 
294
#endif
 
295
        strcat(path, dl_name); strcat(path, ".so.2");
 
296
        *slash_p = '/';
 
297
    } else {
 
298
        strcpy(path, lc_dir); strcat(path, "/");
 
299
#if defined POSTLOCALELIBDIR
 
300
        strcat(path, POSTLOCALELIBDIR); strcat(path, "/");
 
301
#endif
 
302
        strcat(path, dl_name); strcat(path, ".so.2");
 
303
    }
 
304
#endif
 
305
    return path;
 
306
}
 
307
 
 
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
 
313
 * in XLCd
 
314
 */
 
315
static Bool
 
316
open_object (object, lc_dir)
 
317
     XI18NObjectsList object;
 
318
     char *lc_dir;
 
319
{
 
320
  char *path;
 
321
  
 
322
  if (object->refcount == 0) {
 
323
      path = __lc_path(object->dl_name, lc_dir);
 
324
      if (!path)
 
325
          return False;
 
326
#if defined(hpux)
 
327
      object->dl_module = shl_load(path, BIND_DEFERRED, 0L);
 
328
#else
 
329
      object->dl_module = dlopen(path, RTLD_LAZY);
 
330
#endif
 
331
      Xfree(path);
 
332
 
 
333
      if (!object->dl_module)
 
334
          return False;
 
335
    }
 
336
 
 
337
  object->refcount++;
 
338
  return True;
 
339
}
 
340
 
 
341
static void *
 
342
fetch_symbol (object, symbol)
 
343
     XI18NObjectsList object;
 
344
     char *symbol;
 
345
{
 
346
    void *result = NULL;
 
347
#if defined(hpux)
 
348
    int getsyms_cnt, i;
 
349
    struct shl_symbol *symbols;
 
350
#endif
 
351
 
 
352
    if (symbol == NULL)
 
353
        return NULL;
 
354
 
 
355
#if defined(hpux)
 
356
    getsyms_cnt = shl_getsymbols(object->dl_module, TYPE_PROCEDURE,
 
357
                                 EXPORT_SYMBOLS, malloc, &symbols);
 
358
 
 
359
    for(i=0; i<getsyms_cnt; i++) {
 
360
        if(!strcmp(symbols[i].name, symbol)) {
 
361
            result = symbols[i].value;
 
362
            break;
 
363
         }
 
364
    }
 
365
 
 
366
    if(getsyms_cnt > 0) {
 
367
        free(symbols);
 
368
    }
 
369
#else
 
370
    result = try_both_dlsym(object->dl_module, symbol);
 
371
#endif
 
372
 
 
373
    return result;
 
374
}
 
375
 
 
376
static void
 
377
close_object (object)
 
378
     XI18NObjectsList object;
 
379
{
 
380
  object->refcount--;
 
381
  if (object->refcount == 0)
 
382
    {
 
383
#if defined(hpux)
 
384
        shl_unload(object->dl_module);
 
385
#else
 
386
        dlclose(object->dl_module);
 
387
#endif
 
388
        object->dl_module = NULL;
 
389
    }
 
390
}
 
391
 
 
392
 
 
393
XLCd
 
394
#if NeedFunctionPrototypes
 
395
_XlcDynamicLoad(const char *lc_name)
 
396
#else
 
397
_XlcDynamicLoad(lc_name)
 
398
     const char *lc_name;
 
399
#endif
 
400
{
 
401
    XLCd lcd = (XLCd)NULL;
 
402
    XLCd (*lc_loader)() = (XLCd(*)())NULL;
 
403
    int count;
 
404
    XI18NObjectsList objects_list;
 
405
    char lc_dir[BUFSIZE];
 
406
 
 
407
    if (lc_name == NULL) return (XLCd)NULL;
 
408
 
 
409
    if (_XlcLocaleDirName(lc_dir, (char *)lc_name) == (char*)NULL)
 
410
        return (XLCd)NULL;
 
411
 
 
412
    resolve_object(lc_dir, lc_name);
 
413
 
 
414
    objects_list = xi18n_objects_list;
 
415
    count = lc_count;
 
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))
 
420
            continue;
 
421
 
 
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) {
 
426
            break;
 
427
        }
 
428
        
 
429
        close_object (objects_list);
 
430
    }
 
431
    return (XLCd)lcd;
 
432
}
 
433
 
 
434
static XIM
 
435
#if NeedFunctionPrototypes
 
436
_XDynamicOpenIM(XLCd lcd, Display *display, XrmDatabase rdb,
 
437
                char *res_name, char *res_class)
 
438
#else
 
439
_XDynamicOpenIM(lcd, display, rdb, res_name, res_class)
 
440
XLCd lcd;
 
441
Display *display;
 
442
XrmDatabase rdb;
 
443
char *res_name, *res_class;
 
444
#endif
 
445
{
 
446
  XIM im = (XIM)NULL;
 
447
  char lc_dir[BUFSIZE];
 
448
  char *lc_name;
 
449
  XIM (*im_openIM)() = (XIM(*)())NULL;
 
450
  int count;
 
451
  XI18NObjectsList objects_list = xi18n_objects_list;
 
452
 
 
453
  lc_name = lcd->core->name;
 
454
 
 
455
  if (_XlcLocaleDirName(lc_dir, lc_name) == NULL) return (XIM)0;
 
456
 
 
457
  count = lc_count;
 
458
  for (; count-- > 0; objects_list++) {
 
459
    if (objects_list->type != XIM_OBJECT ||
 
460
        strcmp(objects_list->locale_name, lc_name)) continue;
 
461
 
 
462
    if (!open_object (objects_list, lc_dir))
 
463
        continue;
 
464
 
 
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) {
 
469
        break;
 
470
    }
 
471
    
 
472
    close_object (objects_list);
 
473
  }
 
474
  return (XIM)im;
 
475
}
 
476
 
 
477
static Bool
 
478
_XDynamicRegisterIMInstantiateCallback(lcd, display, rdb,
 
479
                                       res_name, res_class,
 
480
                                       callback, client_data)
 
481
XLCd     lcd;
 
482
Display *display;
 
483
XrmDatabase      rdb;
 
484
char    *res_name, *res_class;
 
485
XIMProc  callback;
 
486
XPointer        *client_data;
 
487
{
 
488
  char lc_dir[BUFSIZE];
 
489
  char *lc_name;
 
490
  Bool (*im_registerIM)() = (Bool(*)())NULL;
 
491
  Bool ret_flag = False;
 
492
  int count;
 
493
  XI18NObjectsList objects_list = xi18n_objects_list;
 
494
#if defined(hpux)
 
495
  int getsyms_cnt, i;
 
496
  struct shl_symbol *symbols;
 
497
#endif
 
498
 
 
499
  lc_name = lcd->core->name;
 
500
 
 
501
  if (_XlcLocaleDirName(lc_dir, lc_name) == NULL) return False;
 
502
 
 
503
  count = lc_count;
 
504
  for (; count-- > 0; objects_list++) {
 
505
    if (objects_list->type != XIM_OBJECT ||
 
506
        strcmp(objects_list->locale_name, lc_name)) continue;
 
507
 
 
508
    if (!open_object (objects_list, lc_dir))
 
509
        continue;
 
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,
 
514
                                res_name, res_class,
 
515
                                callback, client_data);
 
516
    if (ret_flag) break;
 
517
 
 
518
    close_object (objects_list);
 
519
  }
 
520
  return (Bool)ret_flag;
 
521
}
 
522
 
 
523
static Bool
 
524
_XDynamicUnRegisterIMInstantiateCallback(lcd, display, rdb,
 
525
                                         res_name, res_class,
 
526
                                         callback, client_data)
 
527
XLCd     lcd;
 
528
Display *display;
 
529
XrmDatabase      rdb;
 
530
char    *res_name, *res_class;
 
531
XIMProc  callback;
 
532
XPointer        *client_data;
 
533
{
 
534
  char lc_dir[BUFSIZE];
 
535
  char *lc_name;
 
536
  Bool (*im_unregisterIM)() = (Bool(*)())NULL;
 
537
  Bool ret_flag = False;
 
538
  int count;
 
539
  XI18NObjectsList objects_list = xi18n_objects_list;
 
540
#if defined(hpux)
 
541
  int getsyms_cnt, i;
 
542
  struct shl_symbol *symbols;
 
543
#endif
 
544
 
 
545
  lc_name = lcd->core->name;
 
546
  if (_XlcLocaleDirName(lc_dir, lc_name) == NULL) return False;
 
547
 
 
548
  count = lc_count;
 
549
  for (; count-- > 0; objects_list++) {
 
550
    if (objects_list->type != XIM_OBJECT ||
 
551
        strcmp(objects_list->locale_name, lc_name)) continue;
 
552
 
 
553
    if (!objects_list->refcount) /* Must already be opened */
 
554
        continue;
 
555
 
 
556
    im_unregisterIM = (Bool(*)())fetch_symbol(objects_list,
 
557
                                              objects_list->im_unregister);
 
558
 
 
559
    if (!im_unregisterIM) continue;
 
560
    ret_flag = (*im_unregisterIM)(lcd, display, rdb,
 
561
                                  res_name, res_class,
 
562
                                  callback, client_data);
 
563
    if (ret_flag) {
 
564
        close_object (objects_list); /* opened in RegisterIMInstantiateCallback */
 
565
        break;
 
566
    }
 
567
  }
 
568
  return (Bool)ret_flag;
 
569
}
 
570
 
 
571
Bool
 
572
#if NeedFunctionPrototypes
 
573
_XInitDynamicIM(XLCd lcd)
 
574
#else
 
575
_XInitDynamicIM(lcd)
 
576
XLCd lcd;
 
577
#endif
 
578
{
 
579
    if(lcd == (XLCd)NULL)
 
580
        return False;
 
581
    lcd->methods->open_im = _XDynamicOpenIM;
 
582
    lcd->methods->register_callback = _XDynamicRegisterIMInstantiateCallback;
 
583
    lcd->methods->unregister_callback = _XDynamicUnRegisterIMInstantiateCallback;
 
584
    return True;
 
585
}
 
586
 
 
587
static XOM
 
588
#if NeedFunctionPrototypes
 
589
_XDynamicOpenOM(XLCd lcd, Display *display, XrmDatabase rdb,
 
590
                _Xconst char *res_name, _Xconst char *res_class)
 
591
#else
 
592
_XDynamicOpenOM(lcd, display, rdb, res_name, res_class)
 
593
XLCd lcd;
 
594
Display *display;
 
595
XrmDatabase rdb;
 
596
char *res_name;
 
597
char *res_class;
 
598
#endif
 
599
{
 
600
  XOM om = (XOM)NULL;
 
601
  int count;
 
602
  char lc_dir[BUFSIZE];
 
603
  char *lc_name;
 
604
  XOM (*om_openOM)() = (XOM(*)())NULL;
 
605
  XI18NObjectsList objects_list = xi18n_objects_list;
 
606
#if defined(hpux)
 
607
  int getsyms_cnt, i;
 
608
  struct shl_symbol *symbols;
 
609
#endif
 
610
 
 
611
  lc_name = lcd->core->name;
 
612
 
 
613
  if (_XlcLocaleDirName(lc_dir, lc_name) == NULL) return (XOM)0;
 
614
 
 
615
  count = lc_count;
 
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))
 
620
        continue;
 
621
    
 
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) {
 
626
        break;
 
627
    }
 
628
    close_object(objects_list);
 
629
  }
 
630
  return (XOM)om;
 
631
}
 
632
 
 
633
Bool
 
634
#if NeedFunctionPrototypes
 
635
_XInitDynamicOM(XLCd lcd)
 
636
#else
 
637
_XInitDynamicOM(lcd)
 
638
    XLCd lcd;
 
639
#endif
 
640
{
 
641
    if(lcd == (XLCd)NULL)
 
642
        return False;
 
643
 
 
644
    lcd->methods->open_om = _XDynamicOpenOM;
 
645
 
 
646
    return True;
 
647
}