123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* (c) Copyright 1997 The Open Group */
- /* *
- * (c) Copyright 1993, 1994 Hewlett-Packard Company *
- * (c) Copyright 1993, 1994 International Business Machines Corp. *
- * (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
- * (c) Copyright 1993, 1994 Novell, Inc. *
- */
- /*
- * xdm - display manager daemon
- *
- * $TOG: util.c /main/15 1998/04/06 13:22:20 mgreess $
- *
- * Copyright 1988 Massachusetts Institute of Technology
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted, provided
- * that the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation, and that the name of M.I.T. not be used in advertising or
- * publicity pertaining to distribution of the software without specific,
- * written prior permission. M.I.T. makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * Author: Keith Packard, MIT X Consortium
- */
- /*
- * util.c
- *
- * various utility routines
- */
- #include <sys/stat.h>
- #include <setjmp.h>
- #include <string.h>
- #include <dirent.h>
- #include <Dt/MsgCatP.h>
- #include <X11/Xutil.h>
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Xmu/SysUtil.h>
- #include <Dt/HourGlass.h>
- #include <signal.h>
- # include "dm.h"
- # include "vgmsg.h"
- nl_catd nl_fd = (nl_catd)-1; /* message catalog file descriptor */
- #if !defined(NL_CAT_LOCALE)
- #define NL_CAT_LOCALE 0
- #endif
- #if !defined (ENABLE_DYNAMIC_LANGLIST)
- #define LANGLISTSIZE 2048
- char languageList[LANGLISTSIZE]; /* global list of languages */
- #endif /* ENABLE_DYNAMIC_LANGLIST */
- /***************************************************************************
- *
- * Local procedure declarations
- *
- ***************************************************************************/
- static char * makeEnv(
- char *name,
- char *value) ;
- static SIGVAL MakeLangAbort(
- int arg );
- static int MatchesFileSuffix(const char *filename, const char *suffix);
- static void ScanNLSDir(
- char * dirname );
- /******** End Local Function Declarations ********/
- /***************************************************************************
- *
- * ReadCatalog
- *
- * read a string from the message catalog
- ***************************************************************************/
- unsigned char *
- ReadCatalog( int set_num, int msg_num, char *def_str )
- {
- static Bool alreadyopen = False;
- if (alreadyopen == False)
- {
- char *curNlsPath, *newNlsPath;
- int newNlsPathLen;
- alreadyopen = True;
- /*
- * Desktop message catalogs are in DT directory, so append desktop
- * search paths to current NLSPATH.
- */
- #define NLS_PATH_STRING CDE_INSTALLATION_TOP "/nls/msg/%L/%N.cat:" \
- CDE_INSTALLATION_TOP "/lib/nls/msg/%L/%N.cat:" \
- CDE_INSTALLATION_TOP "/lib/nls/msg/%l/%t/%c/%N.cat:" \
- CDE_INSTALLATION_TOP "/lib/nls/msg/%l/%c/%N.cat"
- curNlsPath = getenv("NLSPATH");
- if (curNlsPath && strlen(curNlsPath) == 0)
- {
- curNlsPath = NULL;
- }
- /*
- * 7 is "NLSPATH"
- * 1 is "="
- * <length of NLS_PATH_STRING>
- * 1 for null byte
- */
- newNlsPathLen = 7 + 1 + strlen(NLS_PATH_STRING) + 1;
- if (curNlsPath != NULL)
- {
- /*
- * 1 is ":"
- * <length of curNlsPath>
- */
- newNlsPathLen += (1 + strlen(curNlsPath));
- }
- newNlsPath = malloc(newNlsPathLen); /* placed in environ, do not free */
- if (curNlsPath != NULL)
- {
- sprintf(newNlsPath, "NLSPATH=%s:%s", curNlsPath, NLS_PATH_STRING);
- }
- else
- {
- sprintf(newNlsPath, "NLSPATH=%s", NLS_PATH_STRING);
- }
- /*
- * Store new NLSPATH in environment. Note this memory cannot be freed
- */
- putenv(newNlsPath);
- /*
- * Open message catalog. Note, if invalid descriptor returned (ie
- * msg catalog could not be opened), subsequent call to catgets() using
- * that descriptor will return 'def_str'.
- */
- nl_fd = CATOPEN("dtlogin", NL_CAT_LOCALE);
- }
- return ((unsigned char *) CATGETS(nl_fd, set_num, msg_num, def_str));
- }
- void
- printEnv( char **e )
- {
- while (*e)
- Debug (" %s\n", *e++);
- }
- static char *
- makeEnv( char *name, char *value )
- {
- char *result;
- result = malloc ((unsigned) (strlen (name) + strlen (value) + 2));
- if (!result) {
- LogOutOfMem(
- ReadCatalog(MC_LOG_SET,MC_LOG_MAKEENV,MC_DEF_LOG_MAKEENV));
- return 0;
- }
- if (*value) {
- sprintf (result, "%s=%s", name, value);
- }
- else {
- sprintf (result, "%s", name);
- }
- return result;
- }
- char *
- getEnv( char **e, char *name )
- {
- int l = strlen (name);
- while (*e) {
- if ((int) strlen (*e) > l &&
- !strncmp (*e, name, l) &&
- (*e)[l] == '=')
- return (*e) + l + 1;
- ++e;
- }
- return 0;
- }
- char **
- setEnv( char **e, char *name, char *value )
- {
- char **new, **old;
- char *newe;
- int envsize;
- int l;
- l = strlen (name);
- newe = makeEnv (name, value);
- if (!newe) {
- LogOutOfMem(ReadCatalog(MC_LOG_SET,MC_LOG_SETENV,MC_DEF_LOG_SETENV));
- return e;
- }
- if (e) {
- for (old = e; *old; old++)
- if ((int) strlen (*old) > l &&
- !strncmp (*old, name, l) &&
- (*old)[l] == '=')
- break;
- if (*old) {
- free (*old);
- *old = newe;
- return e;
- }
- envsize = old - e;
- new = (char **)
- realloc((char *) e, (unsigned) ((envsize + 2) * sizeof (char *)));
- } else {
- envsize = 0;
- new = (char **) malloc (2 * sizeof (char *));
- }
- if (!new) {
- LogOutOfMem(ReadCatalog(MC_LOG_SET,MC_LOG_SETENV,MC_DEF_LOG_SETENV));
- free (newe);
- return e;
- }
- new[envsize] = newe;
- new[envsize+1] = 0;
- return new;
- }
- void
- freeEnv (char **env)
- {
- char **e;
- if (env)
- {
- for (e = env; *e; e++)
- free (*e);
- free (env);
- }
- }
- # define isblank(c) ((c) == ' ' || c == '\t')
- char **
- parseArgs( char **argv, char *string )
- {
- char *word;
- char *save;
- int i;
- i = 0;
- while (argv && argv[i])
- ++i;
- if (!argv) {
- argv = (char **) malloc (sizeof (char *));
- if (!argv) {
- LogOutOfMem(ReadCatalog(
- MC_LOG_SET,MC_LOG_PARSEARGS,MC_DEF_LOG_PARSEARGS));
- return 0;
- }
- }
- word = string;
- for (;;) {
- if (!*string || isblank (*string)) {
- if (word != string) {
- argv = (char **) realloc ((char *) argv,
- (unsigned) ((i + 2) * sizeof (char *)));
- save = malloc ((unsigned) (string - word + 1));
- if (!argv || !save) {
- LogOutOfMem(ReadCatalog(MC_LOG_SET,
- MC_LOG_PARSEARGS,
- MC_DEF_LOG_PARSEARGS));
- if (argv)
- free ((char *) argv);
- if (save)
- free (save);
- return 0;
- }
- argv[i] = strncpy (save, word, string-word);
- argv[i][string-word] = '\0';
- i++;
- }
- if (!*string)
- break;
- word = string + 1;
- }
- ++string;
- }
- argv[i] = 0;
- return argv;
- }
- void
- CleanUpChild( void )
- {
- /*
- * On i386/i486 platforms setprrp() functions causes the mouse not
- * to work. Since in the daemon mode the parent daemon has already
- * executed a setpgrp it is a process and session leader. Since it
- * has also gotten rid of the controlling terminal there is no great
- * harm in not making the sub-daemons as leaders.
- */
- #if defined (SYSV) || defined (SVR4) || defined(__linux__)
- setpgrp ();
- #else
- setpgrp (0, getpid ());
- sigsetmask (0);
- #endif
- #ifdef SIGCHLD
- (void) signal (SIGCHLD, SIG_DFL);
- #endif
- (void) signal (SIGTERM, SIG_DFL);
- (void) signal (SIGPIPE, SIG_DFL);
- (void) signal (SIGALRM, SIG_DFL);
- (void) signal (SIGHUP, SIG_DFL);
- CloseOnFork ();
- }
- char * *
- parseEnv( char **e, char *string )
- {
- char *s1, *s2, *t1, *t2;
- s1 = s2 = strdup(string);
- while ((t1 = strtok(s1," \t")) != NULL ) {
- if ( (t2 = strchr(t1,'=')) != NULL ) {
- *t2++ = '\0';
- e = setEnv(e, t1, t2);
- }
- s1 = NULL;
- }
- free(s2);
- return (e);
- }
- /*************************************<->*************************************
- *
- * void SetHourGlassCursor
- *
- *
- * Description:
- * -----------
- * sets the window cursor to an hourglass
- *
- *
- * Inputs:
- * ------
- * dpy = display
- * w = window
- *
- * Outputs:
- * -------
- * None
- *
- * Comments:
- * --------
- * None. (None doesn't count as a comment)
- *
- *************************************<->***********************************/
- void
- SetHourGlassCursor( Display *dpy, Window w )
- {
- Cursor cursor;
- XUndefineCursor(dpy, w);
- cursor = _DtGetHourGlassCursor(dpy);
- XDefineCursor(dpy, w, cursor);
- XFreeCursor(dpy, cursor);
- XFlush(dpy);
- }
- #if !defined (ENABLE_DYNAMIC_LANGLIST)
- /***************************************************************************
- *
- * MakeLangList
- *
- * Generate the list of languages installed on the host.
- * Result is stored the global array "languageList"
- *
- ***************************************************************************/
- #define DELIM " \t" /* delimiters in language list */
- static sigjmp_buf langJump;
- static SIGVAL
- MakeLangAbort( int arg )
- {
- siglongjmp (langJump, 1);
- }
- void
- MakeLangList( void )
- {
- int i, j;
- char *lang[500]; /* sort list for languages */
- int nlang; /* total number of languages */
- char *p, *s;
- char *savelist;
- /*
- * build language list from set of languages installed on the host...
- * Wrap a timer around it so it doesn't hang things up too long.
- * langListTimeout resource by default is 30 seconds to scan NLS dir.
- */
- p = languageList;
- strcpy( p, "C");
- signal (SIGALRM, MakeLangAbort);
- alarm ((unsigned) langListTimeout);
- if (!sigsetjmp (langJump, 1)) {
- ScanNLSDir(DEF_NLS_DIR);
- }
- else {
- LogError(ReadCatalog(MC_LOG_SET,MC_LOG_NO_SCAN,MC_DEF_LOG_NO_SCAN),
- DEF_NLS_DIR, langListTimeout);
- }
- alarm (0);
- signal (SIGALRM, SIG_DFL);
- /*
- * sort the list to eliminate duplicates and replace in global array...
- */
- p = savelist = strdup(languageList);
- nlang = 0;
- while ( (s = strtok(p, DELIM)) != NULL ) {
- if ( nlang == 0 ) {
- lang[0] = s;
- lang[++nlang] = 0;
- p = NULL;
- continue;
- }
- for (i = nlang; i > 0 && strcmp(s,lang[i-1]) < 0; i--);
- if (i==0 || strcmp(s,lang[i-1]) != 0 ) {
- for (j = nlang; j > i; j--)
- lang[j] = lang[j-1];
- lang[i] = s;
- lang[++nlang] = 0;
- }
- p = NULL;
- }
- p = languageList;
- strcpy(p,"");
- for ( i = 0; i < nlang; i++) {
- strcat(p, lang[i]);
- strcat(p, " ");
- }
- free(savelist);
- }
- static int
- MatchesFileSuffix(const char *filename, const char *suffix)
- {
- int retval = 0;
- #if defined(_AIX) || defined(SVR4) || defined(__linux__) || defined(CSRG_BASED)
- int different = 1;
- /*
- * The assumption here is that the use of strrstr is
- * to determine if "dp->d_name" ends in ".cat".
- */
- if (strlen(filename) >= strlen(suffix)) {
- different = strcmp(filename + (strlen(filename) - strlen (suffix)), suffix);
- }
- return (different == 0);
- #else
- return (strrstr(filename, suffix) != NULL);
- #endif
- }
- /***************************************************************************
- *
- * ScanNLSDir
- *
- * Scan a directory structure to see if it contains an installed language.
- * If so, the name of the language is appended to a global list of languages.
- *
- * Scan method and scan directory will vary by platform.
- *
- ***************************************************************************/
- static void
- ScanNLSDir(char *dirname)
- #if defined(_AIX)
- /*
- * Search installed locale names for AIX 3.2.5
- */
- {
- DIR *dirp;
- struct dirent *dp;
- /* Search valid locales which are locale database files in
- * /usr/lib/nls/loc.
- * File name is "??_??" which can be used as LANG variable.
- */
- if((dirp = opendir(dirname)) != NULL)
- {
- while((dp = readdir(dirp)) != NULL)
- {
- if(strlen(dp->d_name) == 5 && dp->d_name[2] == '_')
- {
- if((int) strlen(languageList) + 7 < LANGLISTSIZE )
- {
- strcat(languageList, " ");
- strcat(languageList, dp->d_name);
- }
- }
- }
- closedir(dirp);
- }
- }
- #else /* !_AIX */
- /*
- * Scan for installed locales on generic platform
- */
- {
- DIR *dirp;
- struct dirent *dp;
- char* locale;
- char locale_path[MAXPATHLEN];
- struct stat locale_stat;
- int retval;
- /*
- * To determin the fully installed locale list, check several locations.
- */
- if(NULL != (dirp = opendir(dirname)))
- {
- while((dp = readdir(dirp)) != NULL)
- {
- locale = dp->d_name;
- if ( (strcmp(dp->d_name, ".") == 0) ||
- (strcmp(dp->d_name, "..") == 0) )
- continue;
- if (locale[0] != '.' &&
- LANGLISTSIZE > (int) (strlen(languageList)+strlen(locale)+2))
- {
- (void) snprintf(locale_path, MAXPATHLEN, "%s/%s",
- dirname, locale);
- retval = stat(locale_path, &locale_stat);
- if (0 == retval && S_ISDIR(locale_stat.st_mode))
- {
- strcat(languageList, " ");
- strcat(languageList, locale);
- }
- }
- }
- closedir(dirp);
- }
- }
- #endif
- #endif /* ENABLE_DYNAMIC_LANGLIST */
- #ifdef _AIX
- #define ENVFILE "/etc/environment"
- /* Refer to the LANG environment variable, first.
- * Or, search a line which includes "LANG=XX_XX" in /etc/environment.
- * If succeeded, set the value to d->language.
- */
- void
- SetDefaultLanguage(struct display *d)
- {
- FILE *file;
- char lineBuf[160];
- int n;
- char *p;
- char *lang = NULL;
- if((lang = getenv( "LANG" )) == NULL ) {
- if((file = fopen(ENVFILE, "r")) != NULL) {
- while(fgets(lineBuf, sizeof(lineBuf) - 1, file)) {
- n = strlen(lineBuf);
- if(n > 1 && lineBuf[0] != '#') {
- if(lineBuf[n - 1] == '\n')
- lineBuf[n - 1] = '\0';
- if((p = strstr(lineBuf, "LANG=")) != NULL) {
- p += 5;
- if(strlen(p) == 5 && p[2] == '_') {
- lang = p;
- break;
- }
- }
- }
- }
- fclose(file);
- }
- }
- if(lang != NULL && strlen(lang) > 0) {
- /*
- * If LANG is set for hft, we need to change it for X.
- * Currently there are four hft LANG variables.
- */
- if(strcmp(lang, "En_JP") == 0)
- strcpy(d->language, "Ja_JP");
- else if(strcmp(lang, "en_JP") == 0)
- strcpy(d->language, "ja_JP");
- else if(strcmp(lang, "en_KR") == 0)
- strcpy(d->language, "ko_KR");
- else if(strcmp(lang, "en_TW") == 0)
- strcpy(d->language, "zh_TW");
- else
- *(strncpy(d->language, lang, LANGUAGESIZE) + LANGUAGESIZE) = '\0';
- }
- }
- #endif /* _AIX */
- char **
- setLang( struct display *d, char **env , char *langptr)
- {
- char langlist[LANGLISTSIZE];
- int s = 0;
- char *element = NULL;
- int set_def_lang = FALSE;
- if (NULL != langptr)
- Debug("setLang(): langlist = %s\n", langptr);
- else
- Debug("setLang(): langlist = NULL\n");
- if (langptr)
- snprintf(langlist, sizeof(langlist), "%s", langptr);
- else
- snprintf(langlist, sizeof(langlist), "%s", getEnv(env, "LANGLIST"));
- if (strlen(langlist) > 0) {
- element = strtok(langlist, DELIM);
- while(element) {
- set_def_lang = FALSE;
- if (strcmp(element,d->language) == 0){
- env = setEnv(env, "LANG", d->language);
- break;
- }
- else
- set_def_lang = TRUE;
- s += strlen(element) +1;
- element = strtok(langlist+s, DELIM);
- }
- } else
- set_def_lang = TRUE;
- if (set_def_lang) {
- env = setEnv(env, "LANG", "C");
- strcpy(d->language, "C");
- }
- return env;
- }
- static char localHostbuf[256];
- static int gotLocalHostname;
- char *
- localHostname (void)
- {
- if (!gotLocalHostname)
- {
- XmuGetHostname (localHostbuf, sizeof (localHostbuf) - 1);
- gotLocalHostname = 1;
- }
- return localHostbuf;
- }
|