Link with C++ linker
[oweals/cde.git] / cde / programs / dtksh / userinit.c
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 librararies 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 /* $TOG: userinit.c /main/6 1998/04/20 12:55:18 mgreess $ */
24 #include "defs.h"
25 #include "name.h"
26 #include "variables.h"
27 #include <Dt/DtNlUtils.h>
28 #include <Dt/EnvControlP.h>
29 #include <stdio.h>
30 #include <nl_types.h>
31 #include <X11/X.h>
32 #include <X11/Intrinsic.h>
33 #include <X11/IntrinsicP.h>
34 #include <X11/CoreP.h>
35 #include <X11/StringDefs.h>
36 #include <Xm/XmStrDefs.h>
37 #include <setjmp.h>
38 #include <string.h>
39 #include <ctype.h>
40 #include <Xm/Xm.h>
41 #include <Xm/Protocols.h>
42 #include "hash.h"
43 #include "stdio.h"
44 #define NO_AST
45 #include "dtksh.h"
46 #undef NO_AST
47 #include "xmksh.h"
48 #include "dtkcmds.h"
49 #include "xmcvt.h"
50 #include "widget.h"
51 #include "extra.h"
52 #include "xmwidgets.h"
53 #include "msgs.h"
54 #include <locale.h>
55
56
57 /*
58  * LocaleChanged is defined in ksh93/src/cmd/ksh93/sh/init.c
59  */
60
61 extern void LocaleChanged (
62                 Namval_t * np,
63                 const char * val,
64                 int flags,
65                 Namfun_t * fp );
66
67
68 static Namdisc_t localeDisc = { 0, LocaleChanged, NULL, NULL, NULL, NULL, NULL, NULL };
69 static Namfun_t localeFun = {NULL, NULL };
70
71 extern char *savedNlsPath; /* in ./ksh93/src/cmd/ksh93/sh/init.c */
72
73
74 void
75 SyncEnv(
76     char *name)
77 {
78   char *value, *buf;
79
80   value = getenv(name);
81   if(value != (char *)NULL)
82   {
83     buf = malloc(strlen(name) + strlen(value) + 2);
84     strcpy(buf, name);
85     strcat(buf, "=");
86     strcat(buf, value);
87     ksh_putenv(buf);
88     free(buf);  /* I hope it's legal to free this! */
89   }
90 }
91
92 /*
93  *  This is a hook for an additional initialization routine
94  *  A function of this name is called in main after sh_init().
95  */
96
97 void
98 sh_userinit( void )
99
100 {
101    int * lockedFds;
102
103    lockedFds = LockKshFileDescriptors();
104    (void) XtSetLanguageProc((XtAppContext)NULL, (XtLanguageProc)NULL,
105                                 (XtPointer)NULL);
106    setlocale(LC_ALL, "");
107    DtNlInitialize();
108    _DtEnvControl(DT_ENV_SET);
109    localeFun.disc = &localeDisc;
110    nv_stack(LANGNOD, &localeFun);
111    UnlockKshFileDescriptors(lockedFds);
112
113    /*
114     * Save the current setting of NLSPATH.  The user/script may want to
115     * set its own NLSPATH to access its message catalog, so we need to
116     * remember where to find our own catalog(s).  This saved path is used
117     * in ksh93/src/cmd/ksh93/sh/init.c: _DtGetMessage().  We don't mess
118     * with the user/script's setting of LANG as we want to track changes
119     * in LANG.
120     */
121    savedNlsPath = strdup(getenv("NLSPATH"));
122
123    /*
124     * Sync the libc environment (set up by DtEnvControl) with our internal
125     * hash table environment.
126     */
127   SyncEnv("NLSPATH");
128   SyncEnv("LANG");
129 }
130
131 /*
132  * The following routines are used to query a CDE database to determine
133  * if the current character encoding requires special care in the ksh
134  * parser.  They are used in updateShSpecialParse().  These are copied
135  * from the DtHelp code.
136  */
137 #include <XlationSvc.h>
138 #include <LocaleXlate.h>
139
140 static const char *DfltStdCharset = "ISO-8859-1";
141 static const char *DfltStdLang = "C";
142
143 static char       MyPlatform[_DtPLATFORM_MAX_LEN+1];
144 static int        CompVer;
145
146 /******************************************************************************
147  * Function:    static _DtXlateDb OpenLcxDb ()
148  *
149  * Parameters:   none
150  *
151  * Return Value:  NULL: error, else a _DtXlateDb
152  *
153  * errno Values:
154  *
155  * Purpose: Opens the Ce-private Lcx database
156  *
157  *****************************************************************************/
158 static _DtXlateDb
159 OpenLcxDb (void)
160 {
161     static _DtXlateDb MyDb;
162     static Boolean  MyFirst   = True;
163     static Boolean  MyProcess = False;
164     static int        ExecVer;
165     time_t      time1  = 0;
166     time_t      time2  = 0;
167
168     /*
169      * wait up to 30 sec. until another thread or enter is done 
170      * modifying the table.
171      */
172     while (MyProcess == True)
173       {
174         /* if time out, return */
175         if (time(&time2) == (time_t)-1)
176             return (_DtXlateDb)NULL;
177
178         if (time1 == 0)
179             time1 = time2;
180         else if (time2 - time1 >= (time_t)30)
181             return (_DtXlateDb)NULL;
182       }
183
184     if (MyFirst == True)
185       {
186         MyProcess = True;
187         if (_DtLcxOpenAllDbs(&MyDb) == 0 &&
188             _DtXlateGetXlateEnv(MyDb,MyPlatform,&ExecVer,&CompVer) != 0)
189           {
190             _DtLcxCloseDb(&MyDb);
191             MyDb = NULL;
192           }
193         MyFirst = False;
194         MyProcess = False;
195       }
196
197     return MyDb;
198 }
199
200 /******************************************************************************
201  * Function:    static void XlateOpToStdLocale(char *operation, char *opLocale,
202  *                                             char **ret_stdLocale, 
203  *                                             char **ret_stdLang, 
204  *                                             char **ret_stdSet)
205  *
206  * Parameters:
207  *              operation       Operation associated with the locale value
208  *              opLocale        An operation-specific locale string
209  *              ret_locale      Returns the std locale
210  *                              Caller must free this string.
211  *              ret_stdLang        Returns the std language & territory string.
212  *                              Caller must free this string.
213  *              ret_stdSet         Returns the std code set string.
214  *                              Caller must free this string.
215  *
216  * Return Value:
217  *
218  * Purpose:  Gets the standard locale given an operation and its locale
219  *
220  *****************************************************************************/
221 static void
222 XlateOpToStdLocale (
223      char       *operation,
224      char       *opLocale,
225      char       **ret_stdLocale,
226      char       **ret_stdLang,
227      char       **ret_stdSet)
228 {
229     _DtXlateDb MyDb;
230
231     MyDb = OpenLcxDb();
232
233     if (MyDb != NULL)
234       {
235         (void) _DtLcxXlateOpToStd(MyDb, MyPlatform, CompVer,
236                                 operation,opLocale,
237                                 ret_stdLocale, ret_stdLang, ret_stdSet, NULL);
238       }
239
240     /* if failed, give default values */
241     if (ret_stdLocale != NULL && *ret_stdLocale == NULL)
242     {
243         *ret_stdLocale = malloc(strlen(DfltStdLang)+strlen(DfltStdCharset)+3);
244         sprintf(*ret_stdLocale,"%s.%s",DfltStdLang,DfltStdCharset);
245     }
246     if (ret_stdLang != NULL && *ret_stdLang == NULL)
247         *ret_stdLang = strdup(DfltStdLang);
248     if (ret_stdSet != NULL && *ret_stdSet == NULL)
249         *ret_stdSet = strdup(DfltStdCharset);
250 }
251
252
253 /******************************************************************************
254  * Function:    static void XlateStdToOpLocale(char *operation, 
255  *                              char *stdLocale, char *dflt_opLocale, 
256  *                              char **ret_opLocale)
257  *
258  * Parameters:
259  *    operation         operation whose locale value will be retrieved
260  *    stdLocale         standard locale value
261  *    dflt_opLocale     operation-specific locale-value
262  *                      This is the default value used in error case
263  *    ret_opLocale      operation-specific locale-value placed here
264  *                      Caller must free this string.
265  *
266  * Return Value:
267  *
268  * Purpose: Gets an operation-specific locale string given the standard string
269  *
270  *****************************************************************************/
271 static void
272 XlateStdToOpLocale (
273      char       *operation,
274      char       *stdLocale,
275      char       *dflt_opLocale,
276      char       **ret_opLocale)
277 {
278     _DtXlateDb MyDb;
279
280     MyDb = OpenLcxDb();
281
282     if (MyDb != NULL)
283         (void) _DtLcxXlateStdToOp(MyDb, MyPlatform, CompVer,
284                         operation, stdLocale, NULL, NULL, NULL, ret_opLocale);
285 }
286
287 extern int shSpecialParse; /* in ksh93/src/cmd/ksh93/sh/lex.c */
288
289 /*
290  * updateShellSpecialParse uses the libXvh database to determine if the
291  * current character encoding requires special care in the ksh parser.
292  * It sets or clears a global flag (shSpecialParse) based on the value
293  * from the database.  This flag is declared and inspected in sh_lex() in 
294  * ksh93/src/cmd/ksh93/sh/lex.c.  This routine is stubbed in the 
295  * file .../sh/userinit.c to allow ksh93 to compile & run, albeit
296  * without any knowledge of when to do special parsing.
297  */
298
299 void
300 updateShSpecialParse( void )
301 {
302     char *locale = (char *)NULL, *parseVal = (char *)NULL;
303     int * lockedFds;
304
305     lockedFds = LockKshFileDescriptors();
306
307     XlateOpToStdLocale(DtLCX_OPER_SETLOCALE, setlocale(LC_CTYPE,NULL),
308                        &locale, NULL, NULL);
309     XlateStdToOpLocale("dtkshSpecialParse", locale, NULL, &parseVal);
310     XtFree(locale);
311
312     UnlockKshFileDescriptors(lockedFds);
313
314     if(parseVal != (char *)NULL)
315     {
316         shSpecialParse = 1;
317         XtFree(parseVal);
318     }
319     else
320         shSpecialParse = 0;
321 }