util.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841
  1. /*
  2. * CDE - Common Desktop Environment
  3. *
  4. * Copyright (c) 1993-2012, The Open Group. All rights reserved.
  5. *
  6. * These libraries and programs are free software; you can
  7. * redistribute them and/or modify them under the terms of the GNU
  8. * Lesser General Public License as published by the Free Software
  9. * Foundation; either version 2 of the License, or (at your option)
  10. * any later version.
  11. *
  12. * These libraries and programs are distributed in the hope that
  13. * they will be useful, but WITHOUT ANY WARRANTY; without even the
  14. * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
  15. * PURPOSE. See the GNU Lesser General Public License for more
  16. * details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with these libraries and programs; if not, write
  20. * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
  21. * Floor, Boston, MA 02110-1301 USA
  22. */
  23. /* (c) Copyright 1997 The Open Group */
  24. /* *
  25. * (c) Copyright 1993, 1994 Hewlett-Packard Company *
  26. * (c) Copyright 1993, 1994 International Business Machines Corp. *
  27. * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
  28. * (c) Copyright 1993, 1994 Novell, Inc. *
  29. */
  30. /*
  31. * xdm - display manager daemon
  32. *
  33. * $TOG: util.c /main/15 1998/04/06 13:22:20 mgreess $
  34. *
  35. * Copyright 1988 Massachusetts Institute of Technology
  36. *
  37. * Permission to use, copy, modify, and distribute this software and its
  38. * documentation for any purpose and without fee is hereby granted, provided
  39. * that the above copyright notice appear in all copies and that both that
  40. * copyright notice and this permission notice appear in supporting
  41. * documentation, and that the name of M.I.T. not be used in advertising or
  42. * publicity pertaining to distribution of the software without specific,
  43. * written prior permission. M.I.T. makes no representations about the
  44. * suitability of this software for any purpose. It is provided "as is"
  45. * without express or implied warranty.
  46. *
  47. * Author: Keith Packard, MIT X Consortium
  48. */
  49. /*
  50. * util.c
  51. *
  52. * various utility routines
  53. */
  54. #include <sys/stat.h>
  55. #include <setjmp.h>
  56. #include <string.h>
  57. #include <dirent.h>
  58. #include <Dt/MsgCatP.h>
  59. #include <signal.h>
  60. # ifndef NULL
  61. # define NULL 0
  62. # endif
  63. # include "dm.h"
  64. # include "vgmsg.h"
  65. nl_catd nl_fd = (nl_catd)-1; /* message catalog file descriptor */
  66. #if !defined(NL_CAT_LOCALE)
  67. #define NL_CAT_LOCALE 0
  68. #endif
  69. #if !defined (ENABLE_DYNAMIC_LANGLIST)
  70. #define LANGLISTSIZE 2048
  71. char languageList[LANGLISTSIZE]; /* global list of languages */
  72. #endif /* ENABLE_DYNAMIC_LANGLIST */
  73. /***************************************************************************
  74. *
  75. * Local procedure declarations
  76. *
  77. ***************************************************************************/
  78. static char * makeEnv(
  79. char *name,
  80. char *value) ;
  81. static SIGVAL MakeLangAbort(
  82. int arg );
  83. static int MatchesFileSuffix(const char *filename, const char *suffix);
  84. static void ScanNLSDir(
  85. char * dirname );
  86. /******** End Local Function Declarations ********/
  87. /***************************************************************************
  88. *
  89. * ReadCatalog
  90. *
  91. * read a string from the message catalog
  92. ***************************************************************************/
  93. unsigned char *
  94. ReadCatalog( int set_num, int msg_num, char *def_str )
  95. {
  96. static Bool alreadyopen = False;
  97. if (alreadyopen == False)
  98. {
  99. char *curNlsPath, *newNlsPath;
  100. int newNlsPathLen;
  101. alreadyopen = True;
  102. /*
  103. * Desktop message catalogs are in DT directory, so append desktop
  104. * search paths to current NLSPATH.
  105. */
  106. #define NLS_PATH_STRING CDE_INSTALLATION_TOP "/nls/msg/%L/%N.cat:" \
  107. CDE_INSTALLATION_TOP "/lib/nls/msg/%L/%N.cat:" \
  108. CDE_INSTALLATION_TOP "/lib/nls/msg/%l/%t/%c/%N.cat:" \
  109. CDE_INSTALLATION_TOP "/lib/nls/msg/%l/%c/%N.cat"
  110. curNlsPath = getenv("NLSPATH");
  111. if (curNlsPath && strlen(curNlsPath) == 0)
  112. {
  113. curNlsPath = NULL;
  114. }
  115. /*
  116. * 7 is "NLSPATH"
  117. * 1 is "="
  118. * <length of NLS_PATH_STRING>
  119. * 1 for null byte
  120. */
  121. newNlsPathLen = 7 + 1 + strlen(NLS_PATH_STRING) + 1;
  122. if (curNlsPath != NULL)
  123. {
  124. /*
  125. * 1 is ":"
  126. * <length of curNlsPath>
  127. */
  128. newNlsPathLen += (1 + strlen(curNlsPath));
  129. }
  130. newNlsPath = malloc(newNlsPathLen); /* placed in environ, do not free */
  131. if (curNlsPath != NULL)
  132. {
  133. sprintf(newNlsPath, "NLSPATH=%s:%s", curNlsPath, NLS_PATH_STRING);
  134. }
  135. else
  136. {
  137. sprintf(newNlsPath, "NLSPATH=%s", NLS_PATH_STRING);
  138. }
  139. /*
  140. * Store new NLSPATH in environment. Note this memory cannot be freed
  141. */
  142. putenv(newNlsPath);
  143. /*
  144. * Open message catalog. Note, if invalid descriptor returned (ie
  145. * msg catalog could not be opened), subsequent call to catgets() using
  146. * that descriptor will return 'def_str'.
  147. */
  148. nl_fd = CATOPEN("dtlogin", NL_CAT_LOCALE);
  149. }
  150. return ((unsigned char *) CATGETS(nl_fd, set_num, msg_num, def_str));
  151. }
  152. void
  153. printEnv( char **e )
  154. {
  155. while (*e)
  156. Debug (" %s\n", *e++);
  157. }
  158. static char *
  159. makeEnv( char *name, char *value )
  160. {
  161. char *result;
  162. result = malloc ((unsigned) (strlen (name) + strlen (value) + 2));
  163. if (!result) {
  164. LogOutOfMem(
  165. ReadCatalog(MC_LOG_SET,MC_LOG_MAKEENV,MC_DEF_LOG_MAKEENV));
  166. return 0;
  167. }
  168. if (*value) {
  169. sprintf (result, "%s=%s", name, value);
  170. }
  171. else {
  172. sprintf (result, "%s", name);
  173. }
  174. return result;
  175. }
  176. char *
  177. getEnv( char **e, char *name )
  178. {
  179. int l = strlen (name);
  180. while (*e) {
  181. if ((int) strlen (*e) > l &&
  182. !strncmp (*e, name, l) &&
  183. (*e)[l] == '=')
  184. return (*e) + l + 1;
  185. ++e;
  186. }
  187. return 0;
  188. }
  189. char **
  190. setEnv( char **e, char *name, char *value )
  191. {
  192. char **new, **old;
  193. char *newe;
  194. int envsize;
  195. int l;
  196. l = strlen (name);
  197. newe = makeEnv (name, value);
  198. if (!newe) {
  199. LogOutOfMem(ReadCatalog(MC_LOG_SET,MC_LOG_SETENV,MC_DEF_LOG_SETENV));
  200. return e;
  201. }
  202. if (e) {
  203. for (old = e; *old; old++)
  204. if ((int) strlen (*old) > l &&
  205. !strncmp (*old, name, l) &&
  206. (*old)[l] == '=')
  207. break;
  208. if (*old) {
  209. free (*old);
  210. *old = newe;
  211. return e;
  212. }
  213. envsize = old - e;
  214. new = (char **)
  215. realloc((char *) e, (unsigned) ((envsize + 2) * sizeof (char *)));
  216. } else {
  217. envsize = 0;
  218. new = (char **) malloc (2 * sizeof (char *));
  219. }
  220. if (!new) {
  221. LogOutOfMem(ReadCatalog(MC_LOG_SET,MC_LOG_SETENV,MC_DEF_LOG_SETENV));
  222. free (newe);
  223. return e;
  224. }
  225. new[envsize] = newe;
  226. new[envsize+1] = 0;
  227. return new;
  228. }
  229. void
  230. freeEnv (char **env)
  231. {
  232. char **e;
  233. if (env)
  234. {
  235. for (e = env; *e; e++)
  236. free (*e);
  237. free (env);
  238. }
  239. }
  240. # define isblank(c) ((c) == ' ' || c == '\t')
  241. char **
  242. parseArgs( char **argv, char *string )
  243. {
  244. char *word;
  245. char *save;
  246. int i;
  247. i = 0;
  248. while (argv && argv[i])
  249. ++i;
  250. if (!argv) {
  251. argv = (char **) malloc (sizeof (char *));
  252. if (!argv) {
  253. LogOutOfMem(ReadCatalog(
  254. MC_LOG_SET,MC_LOG_PARSEARGS,MC_DEF_LOG_PARSEARGS));
  255. return 0;
  256. }
  257. }
  258. word = string;
  259. for (;;) {
  260. if (!*string || isblank (*string)) {
  261. if (word != string) {
  262. argv = (char **) realloc ((char *) argv,
  263. (unsigned) ((i + 2) * sizeof (char *)));
  264. save = malloc ((unsigned) (string - word + 1));
  265. if (!argv || !save) {
  266. LogOutOfMem(ReadCatalog(MC_LOG_SET,
  267. MC_LOG_PARSEARGS,
  268. MC_DEF_LOG_PARSEARGS));
  269. if (argv)
  270. free ((char *) argv);
  271. if (save)
  272. free (save);
  273. return 0;
  274. }
  275. argv[i] = strncpy (save, word, string-word);
  276. argv[i][string-word] = '\0';
  277. i++;
  278. }
  279. if (!*string)
  280. break;
  281. word = string + 1;
  282. }
  283. ++string;
  284. }
  285. argv[i] = 0;
  286. return argv;
  287. }
  288. void
  289. CleanUpChild( void )
  290. {
  291. /*
  292. * On i386/i486 platforms setprrp() functions causes the mouse not
  293. * to work. Since in the daemon mode the parent daemon has already
  294. * executed a setpgrp it is a process and session leader. Since it
  295. * has also gotten rid of the controlling terminal there is no great
  296. * harm in not making the sub-daemons as leaders.
  297. */
  298. #if defined (SYSV) || defined (SVR4) || defined(__linux__)
  299. setpgrp ();
  300. #else
  301. setpgrp (0, getpid ());
  302. sigsetmask (0);
  303. #endif
  304. #ifdef SIGCHLD
  305. (void) signal (SIGCHLD, SIG_DFL);
  306. #endif
  307. (void) signal (SIGTERM, SIG_DFL);
  308. (void) signal (SIGPIPE, SIG_DFL);
  309. (void) signal (SIGALRM, SIG_DFL);
  310. (void) signal (SIGHUP, SIG_DFL);
  311. CloseOnFork ();
  312. }
  313. char * *
  314. parseEnv( char **e, char *string )
  315. {
  316. char *s1, *s2, *t1, *t2;
  317. s1 = s2 = strdup(string);
  318. while ((t1 = strtok(s1," \t")) != NULL ) {
  319. if ( (t2 = strchr(t1,'=')) != NULL ) {
  320. *t2++ = '\0';
  321. e = setEnv(e, t1, t2);
  322. }
  323. s1 = NULL;
  324. }
  325. free(s2);
  326. return (e);
  327. }
  328. /*************************************<->*************************************
  329. *
  330. * void SetHourGlassCursor
  331. *
  332. *
  333. * Description:
  334. * -----------
  335. * sets the window cursor to an hourglass
  336. *
  337. *
  338. * Inputs:
  339. * ------
  340. * dpy = display
  341. * w = window
  342. *
  343. * Outputs:
  344. * -------
  345. * None
  346. *
  347. * Comments:
  348. * --------
  349. * None. (None doesn't count as a comment)
  350. *
  351. *************************************<->***********************************/
  352. void
  353. SetHourGlassCursor( Display *dpy, Window w )
  354. {
  355. Cursor cursor;
  356. XUndefineCursor(dpy, w);
  357. cursor = _DtGetHourGlassCursor(dpy);
  358. XDefineCursor(dpy, w, cursor);
  359. XFreeCursor(dpy, cursor);
  360. XFlush(dpy);
  361. }
  362. #if !defined (ENABLE_DYNAMIC_LANGLIST)
  363. /***************************************************************************
  364. *
  365. * MakeLangList
  366. *
  367. * Generate the list of languages installed on the host.
  368. * Result is stored the global array "languageList"
  369. *
  370. ***************************************************************************/
  371. #define DELIM " \t" /* delimiters in language list */
  372. static jmp_buf langJump;
  373. static SIGVAL
  374. MakeLangAbort( int arg )
  375. {
  376. longjmp (langJump, 1);
  377. }
  378. void
  379. MakeLangList( void )
  380. {
  381. int i, j;
  382. char *lang[500]; /* sort list for languages */
  383. int nlang; /* total number of languages */
  384. char *p, *s;
  385. char *savelist;
  386. /*
  387. * build language list from set of languages installed on the host...
  388. * Wrap a timer around it so it doesn't hang things up too long.
  389. * langListTimeout resource by default is 30 seconds to scan NLS dir.
  390. */
  391. p = languageList;
  392. strcpy( p, "C");
  393. signal (SIGALRM, MakeLangAbort);
  394. alarm ((unsigned) langListTimeout);
  395. if (!setjmp (langJump)) {
  396. ScanNLSDir(DEF_NLS_DIR);
  397. }
  398. else {
  399. LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_SCAN,MC_DEF_LOG_NO_SCAN),
  400. DEF_NLS_DIR, langListTimeout);
  401. }
  402. alarm (0);
  403. signal (SIGALRM, SIG_DFL);
  404. /*
  405. * sort the list to eliminate duplicates and replace in global array...
  406. */
  407. p = savelist = strdup(languageList);
  408. nlang = 0;
  409. while ( (s = strtok(p, DELIM)) != NULL ) {
  410. if ( nlang == 0 ) {
  411. lang[0] = s;
  412. lang[++nlang] = 0;
  413. p = NULL;
  414. continue;
  415. }
  416. for (i = nlang; i > 0 && strcmp(s,lang[i-1]) < 0; i--);
  417. if (i==0 || strcmp(s,lang[i-1]) != 0 ) {
  418. for (j = nlang; j > i; j--)
  419. lang[j] = lang[j-1];
  420. lang[i] = s;
  421. lang[++nlang] = 0;
  422. }
  423. p = NULL;
  424. }
  425. p = languageList;
  426. strcpy(p,"");
  427. for ( i = 0; i < nlang; i++) {
  428. strcat(p, lang[i]);
  429. strcat(p, " ");
  430. }
  431. free(savelist);
  432. }
  433. static int
  434. MatchesFileSuffix(const char *filename, const char *suffix)
  435. {
  436. int retval = 0;
  437. #if defined(_AIX) || defined(SVR4) || defined(__linux__) || defined(CSRG_BASED)
  438. int different = 1;
  439. /*
  440. * The assumption here is that the use of strrstr is
  441. * to determine if "dp->d_name" ends in ".cat".
  442. */
  443. if (strlen(filename) >= strlen(suffix)) {
  444. different = strcmp(filename + (strlen(filename) - strlen (suffix)), suffix);
  445. }
  446. return (different == 0);
  447. #else
  448. return (strrstr(filename, suffix) != NULL);
  449. #endif
  450. }
  451. /***************************************************************************
  452. *
  453. * ScanNLSDir
  454. *
  455. * Scan a directory structure to see if it contains an installed language.
  456. * If so, the name of the language is appended to a global list of languages.
  457. *
  458. * Scan method and scan directory will vary by platform.
  459. *
  460. ***************************************************************************/
  461. static void
  462. ScanNLSDir(char *dirname)
  463. #if defined(_AIX)
  464. /*
  465. * Search installed locale names for AIX 3.2.5
  466. */
  467. {
  468. DIR *dirp;
  469. struct dirent *dp;
  470. /* Search valid locales which are locale database files in
  471. * /usr/lib/nls/loc.
  472. * File name is "??_??" which can be used as LANG variable.
  473. */
  474. if((dirp = opendir(dirname)) != NULL)
  475. {
  476. while((dp = readdir(dirp)) != NULL)
  477. {
  478. if(strlen(dp->d_name) == 5 && dp->d_name[2] == '_')
  479. {
  480. if((int) strlen(languageList) + 7 < LANGLISTSIZE )
  481. {
  482. strcat(languageList, " ");
  483. strcat(languageList, dp->d_name);
  484. }
  485. }
  486. }
  487. closedir(dirp);
  488. }
  489. }
  490. #elif defined(hpV4)
  491. #define LOCALE "locale.inf"
  492. #define LOCALEOLD "locale.def"
  493. #define COLLATE8 "collate8"
  494. #define MAILX "mailx"
  495. #define ELM "elm"
  496. #define MSGCAT ".cat"
  497. #define DOT "."
  498. #define DOTDOT ".."
  499. /*
  500. * Scan for installed locales on HP platform.
  501. */
  502. {
  503. /***************************************************************************
  504. * Scan supplied NLS directory structure to see if it contains an
  505. * installed language. If so, the name of the language is appended
  506. * to a global list of languages.
  507. *
  508. * This routine is recursively called as a directory structure is
  509. * traversed.
  510. *
  511. *************************************************************************/
  512. DIR *dirp;
  513. struct dirent *dp;
  514. struct stat statb;
  515. char buf[1024];
  516. /*
  517. * Scan input directory, looking for a LOCALE file. If a sub-directory
  518. * is found, recurse down into it...
  519. */
  520. if ( (dirp = opendir(dirname)) != NULL )
  521. {
  522. while ( (dp = readdir(dirp)) != NULL )
  523. {
  524. /*
  525. * ignore files that are known not to be candidates...
  526. */
  527. if ( MatchesFileSuffix(dp->d_name, MSGCAT) ||
  528. (strcmp (dp->d_name, COLLATE8) == 0 ) ||
  529. (strcmp (dp->d_name, MAILX) == 0 ) ||
  530. (strcmp (dp->d_name, ELM) == 0 ) ||
  531. (strcmp (dp->d_name, DOT) == 0 ) ||
  532. (strcmp (dp->d_name, DOTDOT) == 0 ) )
  533. continue;
  534. /*
  535. * check to see if this is the locale file...
  536. */
  537. if ( (strcmp(dp->d_name, LOCALEOLD) == 0 ) ||
  538. (strcmp(dp->d_name, LOCALE) == 0 ) )
  539. {
  540. char *p, *s;
  541. /*
  542. * Convert directory name to language name...
  543. */
  544. if ( (p = strstr(dirname, DEF_NLS_DIR)) != NULL )
  545. {
  546. p += strlen(DEF_NLS_DIR);
  547. if ( *p == '/' )
  548. p++;
  549. s = p;
  550. while ( (p = strchr(s,'/')) != NULL )
  551. *p = '.';
  552. /*
  553. * append to global list of languages...
  554. */
  555. if ((int) (strlen(languageList)+strlen(s)+2) < LANGLISTSIZE)
  556. {
  557. strcat(languageList, " ");
  558. strcat(languageList, s);
  559. }
  560. }
  561. continue;
  562. }
  563. /*
  564. * if this file is a directory, scan it also...
  565. */
  566. strcpy(buf, dirname);
  567. strcat(buf, "/");
  568. strcat(buf, dp->d_name);
  569. if (stat(buf, &statb) == 0 && S_ISDIR(statb.st_mode))
  570. ScanNLSDir(buf);
  571. }
  572. closedir(dirp);
  573. }
  574. }
  575. #else /* !_AIX && !hpV4 */
  576. /*
  577. * Scan for installed locales on generic platform
  578. */
  579. {
  580. DIR *dirp;
  581. struct dirent *dp;
  582. char* locale;
  583. char locale_path[MAXPATHLEN];
  584. struct stat locale_stat;
  585. int retval;
  586. /*
  587. * To determin the fully installed locale list, check several locations.
  588. */
  589. if(NULL != (dirp = opendir(dirname)))
  590. {
  591. while((dp = readdir(dirp)) != NULL)
  592. {
  593. locale = dp->d_name;
  594. if ( (strcmp(dp->d_name, ".") == 0) ||
  595. (strcmp(dp->d_name, "..") == 0) )
  596. continue;
  597. if (locale[0] != '.' &&
  598. LANGLISTSIZE > (int) (strlen(languageList)+strlen(locale)+2));
  599. {
  600. (void) sprintf(locale_path, "%s/%s", dirname, locale);
  601. retval = stat(locale_path, &locale_stat);
  602. if (0 == retval && S_ISDIR(locale_stat.st_mode))
  603. {
  604. strcat(languageList, " ");
  605. strcat(languageList, locale);
  606. }
  607. }
  608. }
  609. closedir(dirp);
  610. }
  611. }
  612. #endif
  613. #endif /* ENABLE_DYNAMIC_LANGLIST */
  614. #ifdef _AIX
  615. #define ENVFILE "/etc/environment"
  616. /* Refer to the LANG environment variable, first.
  617. * Or, search a line which includes "LANG=XX_XX" in /etc/environment.
  618. * If succeeded, set the value to d->language.
  619. */
  620. void
  621. SetDefaultLanguage(struct display *d)
  622. {
  623. FILE *file;
  624. char lineBuf[160];
  625. int n;
  626. char *p;
  627. char *lang = NULL;
  628. if((lang = getenv( "LANG" )) == NULL ) {
  629. if((file = fopen(ENVFILE, "r")) != NULL) {
  630. while(fgets(lineBuf, sizeof(lineBuf) - 1, file)) {
  631. n = strlen(lineBuf);
  632. if(n > 1 && lineBuf[0] != '#') {
  633. if(lineBuf[n - 1] == '\n')
  634. lineBuf[n - 1] = '\0';
  635. if((p = strstr(lineBuf, "LANG=")) != NULL) {
  636. p += 5;
  637. if(strlen(p) == 5 && p[2] == '_') {
  638. lang = p;
  639. break;
  640. }
  641. }
  642. }
  643. }
  644. fclose(file);
  645. }
  646. }
  647. if(lang != NULL && strlen(lang) > 0) {
  648. /*
  649. * If LANG is set for hft, we need to change it for X.
  650. * Currently there are four hft LANG variables.
  651. */
  652. d->language = (char *)malloc(strlen(lang)+1);
  653. if(strcmp(lang, "En_JP") == 0)
  654. strcpy(d->language, "Ja_JP");
  655. else if(strcmp(lang, "en_JP") == 0)
  656. strcpy(d->language, "ja_JP");
  657. else if(strcmp(lang, "en_KR") == 0)
  658. strcpy(d->language, "ko_KR");
  659. else if(strcmp(lang, "en_TW") == 0)
  660. strcpy(d->language, "zh_TW");
  661. else
  662. strcpy(d->language, lang);
  663. }
  664. }
  665. #endif /* _AIX */
  666. char **
  667. setLang( struct display *d, char **env , char *langptr)
  668. {
  669. char langlist[LANGLISTSIZE];
  670. int s = 0;
  671. char *element = NULL;
  672. int set_def_lang = FALSE;
  673. if (NULL != langptr)
  674. Debug("setLang(): langlist = %s\n", langptr);
  675. else
  676. Debug("setLang(): langlist = NULL\n");
  677. if (langptr)
  678. snprintf(langlist, sizeof(langlist), "%s", langptr);
  679. else
  680. snprintf(langlist, sizeof(langlist), "%s", getEnv(env, "LANGLIST"));
  681. if (strlen(langlist) > 0) {
  682. element = strtok(langlist, DELIM);
  683. while(element) {
  684. set_def_lang = FALSE;
  685. if (strcmp(element,d->language) == 0){
  686. env = setEnv(env, "LANG", d->language);
  687. break;
  688. }
  689. else
  690. set_def_lang = TRUE;
  691. s += strlen(element) +1;
  692. element = strtok(langlist+s, DELIM);
  693. }
  694. } else
  695. set_def_lang = TRUE;
  696. if (set_def_lang) {
  697. env = setEnv(env, "LANG", "C");
  698. d->language = strdup("C");
  699. }
  700. return env;
  701. }
  702. static char localHostbuf[256];
  703. static int gotLocalHostname;
  704. char *
  705. localHostname (void)
  706. {
  707. if (!gotLocalHostname)
  708. {
  709. XmuGetHostname (localHostbuf, sizeof (localHostbuf) - 1);
  710. gotLocalHostname = 1;
  711. }
  712. return localHostbuf;
  713. }