123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690 |
- /*
- * 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
- */
- /* $TOG: I18nEnv.c /main/4 1997/08/11 12:31:10 samborn $ */
- /*
- * (c) Copyright 1996 Digital Equipment Corporation.
- * (c) Copyright 1996 Hewlett-Packard Company.
- * (c) Copyright 1996 International Business Machines Corp.
- * (c) Copyright 1996 Sun Microsystems, Inc.
- * (c) Copyright 1996 Novell, Inc.
- * (c) Copyright 1996 FUJITSU LIMITED.
- * (c) Copyright 1996 Hitachi.
- */
- /************************************<+>*************************************
- ****************************************************************************
- **
- ** File: I18nEnv.c
- **
- ** Description: Controls the Dtstyle I18N component interaction with
- ** the environment.
- **
- **
- ****************************************************************************
- ************************************<+>*************************************/
- /*+++++++++++++++++++++++++++++++++++++++*/
- /* include files */
- /*+++++++++++++++++++++++++++++++++++++++*/
- #include <pwd.h>
- #include <X11/Xlib.h>
- #include <X11/Intrinsic.h>
- #include <DtHelp/LocaleXlate.h> /* for locale equivalence between platforms */
- #include "Main.h"
- #include "I18nEnv.h"
- /*+++++++++++++++++++++++++++++++++++++++*/
- /* include extern functions */
- /*+++++++++++++++++++++++++++++++++++++++*/
- /*+++++++++++++++++++++++++++++++++++++++*/
- /* Local #defines */
- /*+++++++++++++++++++++++++++++++++++++++*/
- /*+++++++++++++++++++++++++++++++++++++++*/
- /* Internal Functions */
- /*+++++++++++++++++++++++++++++++++++++++*/
- static int GetUserEnv(I18nEnv *env);
- static int FindCDELocaleName(UserEnv *uenv);
- static int GetUserIMSelectionFile(I18nEnv *env);
- static int GetUserFileName(I18nEnv *env);
- static int ReadImSelectionFile(FileSel *fsel, FILE *fp);
- static int GetImsList(I18nEnv *env, char *hostname);
- static void TimeOutProc(XtPointer client_data, XtIntervalId* timer);
- static void ReadPipe(XtPointer client_data, int *fd, XtInputId *id);
- static int ProcessBuf(char *savebuf, I18nEnv *env);
- static int CheckHostname(I18nEnv *env, char *hostname);
- static void PutSelectMode(FILE *fp, int start_mode);
- static void PutImsName(FILE *fp, char *im_name);
- static void PutHostname(FILE *fp, char *hostname);
- static void PutSelectionEntry(FILE *fp, char *tag, char *value);
- /*+++++++++++++++++++++++++++++++++++++++*/
- /* Internal Variables */
- /*+++++++++++++++++++++++++++++++++++++++*/
- /*+++++++++++++++++++++++++++++++++++++++*/
- /* Global Variables */
- /*+++++++++++++++++++++++++++++++++++++++*/
- I18nEnv i18n_env;
- /*+++++++++++++++++++++++++++++++++++++++*/
- /* strcasecmp */
- /*+++++++++++++++++++++++++++++++++++++++*/
- #ifdef NEED_STRCASECMP
- /*
- * In case strcasecmp is not provided by the system here is one
- * which does the trick.
- */
- static int
- strcasecmp(const char *s1,
- const char *s2)
- {
- int c1, c2;
- while (*s1 && *s2) {
- c1 = isupper(*s1) ? tolower(*s1) : *s1;
- c2 = isupper(*s2) ? tolower(*s2) : *s2;
- if (c1 != c2)
- return (c1 - c2);
- s1++;
- s2++;
- }
- return (int) (*s1 - *s2);
- }
- #endif
- /*+++++++++++++++++++++++++++++++++++++++*/
- /* _DtI18nGetEnvValues */
- /*+++++++++++++++++++++++++++++++++++++++*/
- int
- _DtI18nGetEnvValues(
- I18nEnv *env
- )
- {
- int ret = NoError;
- /* Get the user environment */
- env->user_env = (UserEnv *) XtMalloc(sizeof(UserEnv));
- ret = GetUserEnv(env);
- /* Get the user selection stored in the IM Selection File */
- if (ret == NoError) {
- env->file_sel = (FileSel *) XtMalloc(sizeof(FileSel));
- ret = GetUserIMSelectionFile(env);
- }
- /* Alloc the user selection */
- env->ims_sel = (ImsSel *) XtMalloc(sizeof(ImsSel));
- env->ims_sel->ims_list = NULL;
- env->ims_sel->ims_list_size = 0 ;
- env->ims_sel->host_name = NULL ;
- /* Get the Input Method available on the selected host.
- * The selected host is the one stored in the IMS Selection File.
- */
- if (ret == NoError)
- ret = _DtI18nGetImList(env, env->file_sel->hostname);
- return ret;
- }
- /*+++++++++++++++++++++++++++++++++++++++*/
- /* GetUserEnv */
- /*+++++++++++++++++++++++++++++++++++++++*/
- static int
- GetUserEnv(
- I18nEnv *env
- )
- {
- UserEnv *uenv = env->user_env ;
- int ret = NoError;
- char buf[BUFSIZ], *p;
- /* get the host name */
- gethostname(buf, BUFSIZ);
- uenv->localhostname = XtNewString(buf);
- /* get the user name */
- if ((p = getlogin()) == NULL) {
- struct passwd *pw;
- pw = getpwuid(getuid());
- p = pw->pw_name;
- }
-
- uenv->username = XtNewString(p);
- /* get the display name */
- uenv->displayname = XtNewString(XDisplayString(XtDisplay(env->shell)));
-
- /* get the locale */
- if ((p = getenv("LANG")) && *p)
- uenv->locale = XtNewString(p);
- else
- return ErrNoLocale;
-
- /* find the CDE generic locale name */
- if (FindCDELocaleName(uenv) != NoError)
- return ErrNoCDELocale;
-
- /* get the home directory */
- if ((p = getenv("HOME")) && *p)
- uenv->homedir = XtNewString(p);
- else
- ret = ErrNoHome;
- return ret;
- }
- static int
- FindCDELocaleName(
- UserEnv *uenv
- )
- {
- _DtXlateDb db = NULL;
- int ret = NoError;
- char plat[_DtPLATFORM_MAX_LEN];
- int execver;
- int compver;
- ret = _DtLcxOpenAllDbs(&db);
- if (ret == NoError)
- ret = _DtXlateGetXlateEnv(db, plat, &execver, &compver);
- if (ret == NoError)
- ret = _DtLcxXlateOpToStd(db, plat, compver, DtLCX_OPER_SETLOCALE,
- uenv->locale, &uenv->CDE_locale,
- NULL, NULL, NULL);
- if (ret == NoError)
- ret = _DtLcxCloseDb(&db);
- return ret;
- }
- static int
- GetUserIMSelectionFile(
- I18nEnv *env
- )
- {
- int ret = NoError;
- FILE *fp = NULL;
- ret = GetUserFileName(env);
-
- if (ret == NoError) {
- /* Look if this file is readable */
- if ((fp = fopen(env->file_sel->fname, "r")) == NULL) {
- env->file_sel->start_mode = -1;
- return ErrNoSelectionFile;
- }
- }
- start_tag_line(env->file_sel->fname);
- ret = ReadImSelectionFile(env->file_sel, fp);
- if(fp) {
- fclose(fp);
- }
- return ret;
- }
- static int
- GetUserFileName(
- I18nEnv *env
- )
- {
- int status, ret = NoError;
- char *path, *tmp_path;
- int len = 0;
- struct stat buf;
- /* The user IMS Selection File should be of the following form:
- * $HOME/.dt/ims/[display-name]/CDE-locale
- */
- path = (char *) XtMalloc((MAXPATHLEN + 1) * sizeof(char));
- strcpy(path, env->user_env->homedir);
- strcat(path, DtUSER_IMSFS_DIR);
- /* Look if there is a display specific directory */
- tmp_path = (char *) XtMalloc((MAXPATHLEN + 1) * sizeof(char));
-
- strcpy(tmp_path, path);
- strcat(tmp_path, "/");
- strcat(tmp_path, env->user_env->displayname);
- if ((status = stat (tmp_path, &buf)) == 0) {
- strcat(path, "/");
- strcat(path, env->user_env->displayname);
- }
- XtFree(tmp_path);
- /* Now add the CDE-specific locale name */
- strcat(path, "/");
- strcat(path, env->user_env->CDE_locale);
- env->file_sel->fname = path;
- return ret;
- }
- static int
- ReadImSelectionFile(
- FileSel *fsel,
- FILE *fp
- )
- {
- int ret = NoError;
- char *lp, *valp, *vp, *p;
- int select_mode = 0;
- char *imsname, *hostname;
- int line_num, i;
- imsname = hostname = NULL;
- while ((line_num = read_tag_line(fp, &lp, &valp)) > 0) {
- if (!valp) {
- continue;
- }
- if (lp[0] != STR_PREFIX_CHAR) {
- continue;
- }
- if (strncmp(lp + 1, STR_SELECTMODE, 3) == 0) {
- if (str_to_int(valp, &i) && i >= 0) {
- select_mode = i;
- }
- } else if (strncmp(lp + 1, STR_IMSNAME, 4) == 0) {
- vp = valp; cut_field(valp);
- if (*vp) {
- XtFree(imsname);
- imsname = XtNewString(vp);
- }
- } else if (strncmp(lp + 1, STR_HOSTNAME, 4) == 0) {
- vp = valp; cut_field(valp);
- if (*vp) {
- XtFree(hostname);
- if (strcmp(vp, NAME_LOCAL)) {
- hostname = XtNewString(vp);
- }
- }
- }
- }
- fsel->im_name = imsname;
- fsel->hostname = hostname;
- fsel->start_mode = select_mode;
- return ret;
- }
- int
- _DtI18nGetImList(
- I18nEnv *env,
- char *hostname )
- {
- int ret = NoError;
- int host_type = HOST_LOCAL;
- if (hostname)
- host_type = CheckHostname(env, hostname);
- switch (host_type) {
- case HOST_UNKNOWN:
- ret = ErrUnknownHost;
- break;
- case HOST_REMOTE:
- /* Put the host name in the ImsSel structure */
- env->ims_sel->host_name = hostname;
- ret = GetImsList(env, hostname);
- break;
- case HOST_LOCAL:
- if (hostname && strcasecmp(hostname, "local") != 0)
- env->ims_sel->host_name = hostname;
- ret = GetImsList(env, env->user_env->localhostname);
- break;
- }
- return ret;
- }
- static int
- GetImsList(
- I18nEnv *env,
- char *hostname )
- {
- int ret = NoError;
- char pipe_command[255];
- FILE *fp;
- struct stat buf;
- unsigned long timeout;
- /* First check if dtimsstart is installed correctly */
- if ((ret = stat ("/usr/dt/bin/dtimsstart", &buf)) != NoError) {
- return ErrNoDtimsstart;
- }
-
- sprintf(pipe_command, "/usr/dt/bin/dtimsstart -listname -hostname %s",
- hostname);
- if (fp = popen(pipe_command, "r")) {
- /* Set the sensitivity of the InputMethod Title Box to False until we
- * are done reading the new information. */
- _DtI18nSetSensitiveImTB(env, False);
- /* Initialize the pipe record. */
- if (!(env->pipe_info))
- env->pipe_info = (PipeRec *) XtMalloc(sizeof(PipeRec));
-
- env->pipe_info->pipe = fp; /* to close it */
- env->pipe_info->input_id = /* to remove it */
- XtAppAddInput (XtWidgetToApplicationContext(env->shell),
- fileno(fp), (XtPointer) XtInputReadMask,
- ReadPipe, (XtPointer) env);
- /* Also add a timeout in case the pipe ain't talk */
- timeout = (unsigned long) (style.xrdb.pipeTimeOut) * 1000;
- env->pipe_info->timer_id =
- XtAppAddTimeOut(XtWidgetToApplicationContext(env->shell),
- timeout, TimeOutProc, (XtPointer)env);
- } else {
- ret = ErrNoPopen;
- }
- return ret;
- }
-
- static void TimeOutProc (XtPointer client_data,
- XtIntervalId* timer)
- {
- I18nEnv *env = (I18nEnv *) client_data;
- /* the command is not fast enough, but calling pclose blocks
- and then print "Broken Pipe". I need to kill the child somehow
- pclose(env->pipe_info->pipe);*/
- XtRemoveInput(env->pipe_info->input_id);
- /* Set the sensitivity of the InputMethod Title Box back to True. */
- _DtI18nSetSensitiveImTB(env, True);
- _DtI18nErrorDialog(ErrTimeOut) ;
- }
- static void
- ReadPipe (
- XtPointer client_data,
- int *fd,
- XtInputId *id )
- {
- char buf[512];
- int i, nbytes;
- int status = NoError;
- static char * savebuf = NULL;
- static int savebuf_bytes = 0 ;
- I18nEnv *env = (I18nEnv *) client_data;
-
- nbytes = read (*fd, buf, 512);
- if (nbytes > 0) {
- savebuf = XtRealloc(savebuf, savebuf_bytes + nbytes);
- memcpy(savebuf+savebuf_bytes, buf, nbytes);
- savebuf_bytes += nbytes ;
- } else {
- if (savebuf)
- *(savebuf + savebuf_bytes) = '\0';
- status = ProcessBuf(savebuf, client_data);
- savebuf_bytes = 0;
- if (savebuf) {
- XtFree(savebuf);
- savebuf = NULL;
- }
- pclose(env->pipe_info->pipe);
- XtRemoveInput(*id);
- /* Set the sensitivity of the InputMethod Title Box back to True. */
- _DtI18nSetSensitiveImTB(env, True);
- /* Remove timer too */
- XtRemoveTimeOut(env->pipe_info->timer_id);
- if (status != NoError)
- _DtI18nErrorDialog(status) ;
- }
- }
- static int
- ProcessBuf(
- char *savebuf,
- I18nEnv *env )
- {
- int i, n = 0;
- int ret = NoError;
- ImsEnt *ims_ent;
- char * filename, * label ;
- /* The dtimsstart execution gave back an empty buffer */
- if (!savebuf)
- return(ErrRemoteFailed);
-
- /* parse savebuf: The lines have the following syntax:
- * [#](im_filename) im_label or
- * [#]im_filename im_label
- * where "#" if present means the default IM,
- * im_filename is the file name where all the IM info is stored,
- * im_label is the label to present to the user.
- */
- while (*savebuf) {
- /* We're at the beginning of a new line */
- /* grow the array */
- env->ims_sel->ims_list =
- (ImsEnt *) XtRealloc((char *) env->ims_sel->ims_list,
- sizeof(ImsEnt)*(n+1));
- ims_ent = &(env->ims_sel->ims_list[n]);
- /* Look to see if this is the default one. */
- if (*savebuf == '#') {
- ims_ent->im_default = 1;
- savebuf++;
- } else
- ims_ent->im_default = 0;
- /* Look to see if it is not reachable. */
- if (*savebuf == '(') {
- ims_ent->inactive = 1;
- savebuf++ ;
- } else
- ims_ent->inactive = 0 ;
- /* Mark begin of im filename */
- filename = savebuf ;
- /* Go to the end of it */
- while (!isspace(*savebuf++)) ;
- /* We're on the first space, mark the end of the im filename,
- * don't forget to count the ')' if inactive. */
- *(savebuf - ims_ent->inactive - 1) = '\0';
- /* Mark the beginning of the im name */
- label = savebuf ;
- while (*savebuf != '\n') savebuf++ ;
- /* mark the end */
- *savebuf = '\0';
- savebuf++;
- /* copy the string data here. it's gonna be freed after that */
- ims_ent->im_name = XtNewString(filename) ;
- ims_ent->im_label = XtNewString(label) ;
- n++;
- }
- env->ims_sel->ims_list_size = n;
- return(ret);
- }
- static int
- CheckHostname(
- I18nEnv *env,
- char *hostname
- )
- {
- int host_type = HOST_UNKNOWN;
- char *local = env->user_env->localhostname;
- struct hostent *hp;
- unsigned long addr = 0L;
- static unsigned long local_addr = 0L;
- if (!hostname || !*hostname || strcasecmp(hostname, "local") == 0
- || strcasecmp(hostname, local) == 0) {
- host_type = HOST_LOCAL;
- } else { /* compare inet address */
- if (!local_addr) {
- if ((hp = gethostbyname(local)) && hp->h_addrtype == AF_INET) {
- local_addr = *((unsigned long *) hp->h_addr_list[0]);
- } else {
- host_type = HOST_REMOTE;
- }
- }
- if (host_type == HOST_UNKNOWN) {
- if ((hp = gethostbyname(hostname)) && hp->h_addrtype == AF_INET) {
- addr = *((unsigned long *) hp->h_addr_list[0]);
- if (addr == local_addr)
- host_type = HOST_LOCAL;
- else
- host_type = HOST_REMOTE;
- } else {
- host_type = HOST_UNKNOWN;
- }
- }
- }
- return host_type;
- }
- /*+++++++++++++++++++++++++++++++++++++++*/
- /* _DtI18nWriteImSelectionFile - writes */
- /* the values saved in the FileSel */
- /* structure to the IMS Selection File. */
- /*+++++++++++++++++++++++++++++++++++++++*/
- int
- _DtI18nWriteImSelectionFile(
- I18nEnv *env
- )
- {
- FILE *fp;
-
- /* Look if this file is writable */
- if ((fp = fopen(env->file_sel->fname, "w")) == NULL)
- return ErrFileCreate;
- /* Write the select mode */
- PutSelectMode(fp, env->file_sel->start_mode);
- /* Write the IM selected if not null */
- PutImsName(fp, env->file_sel->im_name);
- /* Write the hostname if not null */
- PutHostname(fp, env->file_sel->hostname);
-
- /* Close the file */
- fclose(fp);
- return NoError;
- }
- static void
- PutSelectMode(
- FILE *fp,
- int start_mode
- )
- {
- char val[20];
-
- sprintf(val, "%ld", (long)start_mode);
- PutSelectionEntry(fp, STR_SELECTMODE, val);
- }
- static void
- PutImsName(
- FILE *fp,
- char *im_name
- )
- {
- char *valp;
- if ((valp = im_name) && *valp)
- PutSelectionEntry(fp, STR_IMSNAME, valp);
- }
- static void
- PutHostname(
- FILE *fp,
- char *hostname
- )
- {
- char *valp;
- if ((valp = hostname) && *valp)
- PutSelectionEntry(fp, STR_HOSTNAME, valp);
- }
- static void
- PutSelectionEntry(
- FILE *fp,
- char *tag,
- char *value
- )
- {
- fprintf(fp, "%c%s%c\t%s\n", STR_PREFIX_CHAR, tag, TAG_END_CHAR, value);
- }
|