282d7f729d2ed3496d5197a80f8d0d8492cfdc1e
[oweals/cde.git] / cde / programs / dtappbuilder / src / libAButil / util.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 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
24 /*
25  *      $TOG: util.c /main/6 1998/04/06 13:13:09 mgreess $
26  *
27  * @(#)util.c   1.21 16 Feb 1994        cde_app_builder/src/libAButil
28  *
29  *      RESTRICTED CONFIDENTIAL INFORMATION:
30  *      
31  *      The information in this document is subject to special
32  *      restrictions in a confidential disclosure agreement between
33  *      HP, IBM, Sun, USL, SCO and Univel.  Do not distribute this
34  *      document outside HP, IBM, Sun, USL, SCO, Fujitsu, or Univel without
35  *      Sun's specific written approval.  This document and all copies
36  *      and derivative works thereof must be returned or destroyed at
37  *      Sun's request.
38  *
39  *      Copyright 1993 Sun Microsystems, Inc.  All rights reserved.
40  *
41  */
42
43
44 /*
45  * File:  util.c - general utilities
46  */
47 #include <stdlib.h>
48 #include <stdio.h>
49 #include <string.h>
50 #include <ctype.h>
51 #include <limits.h>
52 #include <sys/param.h>
53 #include <sys/utsname.h>
54 #include <ab_private/AB.h>              /* include first! */
55 #include <ab_private/util.h>
56 #include <ab_private/istr.h>
57 #include "utilP.h"
58
59 static char *const      util_verbosity_env_var_name= "AB_DEBUG_VERBOSITY";
60 static char *const      default_program_name=   "AppBuilder";
61 static ISTRING          program_name= NULL;
62
63 const STRING Util_null_string= "(nil)";
64 const STRING Util_empty_string= "";
65
66 const int Util_major_version = 1;
67 const int Util_minor_version = 0;
68
69 int utilP_verbosity= 1;
70
71
72 /*
73  * argv0 may be NULL
74  */
75 int
76 util_init(int *argc_in_out, STRING **argv_in_out)
77 {
78 #define argc (*argc_in_out)
79 #define argv (*argv_in_out)
80     STRING      argv0 = argv[0];
81     char        *verboseVar= NULL;
82     int         verboseVarValue= -1;
83     int         verbosity= 0;
84
85     verbosity = util_get_verbosity();
86
87     /*
88      * If this is a debugging build, look for the debugging level env. var
89      */
90 #ifdef DEBUG
91     verboseVar= getenv(util_verbosity_env_var_name);
92     if (verboseVar != NULL)
93     {
94         verboseVarValue= atoi(verboseVar);
95         verbosity= verboseVarValue;
96     }
97 #endif /* DEBUG */
98
99     /*
100      * When debugging, keeps the output order consistent.  A little
101      * slower, though.
102      */
103     if (verbosity >= 3)
104     {
105         /* there's really no good reason to unbuffer stdin */
106         util_unbuffer_file(stdout);
107         util_unbuffer_file(stderr);
108     }
109
110     if (argv0 != NULL)
111     {
112         util_set_program_name_from_argv0(argv0);
113     }
114
115     if (verbosity >= 3)
116     {
117         util_puts("Debugging output enabled, because verbosity > 2.\n");
118     }
119     util_set_verbosity(verbosity);
120     verbosity= util_get_verbosity();
121
122     return 0;
123 #undef argc
124 #undef argv
125 }
126
127
128 int
129 util_set_verbosity(int newVerbosity)
130 {
131     int         oldVerbosity = utilP_verbosity;
132
133     utilP_verbosity= newVerbosity;
134
135     /*
136      * If this is not a debugging build, do not allow verbosity to
137      * go outside the range that is normal for an end-user.
138      */
139 #ifndef DEBUG
140     utilP_verbosity = util_max(0, utilP_verbosity);
141     utilP_verbosity = util_min(2, utilP_verbosity);
142 #endif
143
144     /*
145      * Nifty message if we're debugging.
146      */
147 #ifdef DEBUG
148     if (  ((oldVerbosity >= 3) || (newVerbosity >= 3))
149         && (oldVerbosity != newVerbosity) )
150     {
151         int     newDebugLevel = debug_level();
152         utilP_verbosity = 3;    /* make sure dprintf() prints something */
153         util_dprintf(0, "Verbosity = %d", newVerbosity);
154         if (newDebugLevel > 0)
155         {
156             util_dprintf(0," [ Debugging level %d ]", newDebugLevel);
157         }
158         util_dprintf(0,"\n");
159         utilP_verbosity = newVerbosity;
160     }
161 #endif /* DEBUG */
162
163     return 0;
164 }
165
166
167 int
168 util_set_program_name(STRING new_program_name)
169 {
170     istr_destroy(program_name);
171     if (new_program_name == NULL)
172     {
173         program_name= istr_const(default_program_name);
174     }
175     else
176     {
177         program_name= istr_create(new_program_name);
178     }
179     return 0;
180 }
181
182
183 int
184 util_set_program_name_from_argv0(STRING argv0)
185 {
186     char        progName[MAXPATHLEN];
187     util_get_file_name_from_path(argv0, progName, MAXPATHLEN);
188     if (strlen(progName) > (size_t)0)
189     {
190         util_set_program_name(progName);
191     }
192     return 0;
193 }
194
195
196 STRING
197 util_get_program_name(void)
198 {
199     return (program_name == NULL? 
200                 default_program_name
201                 :istr_string(program_name));
202 }
203
204
205 /*
206  * Performs a lighter-weight fork that does not immediately copy
207  * all the pages of the application. This is ideal for doing a
208  * a fork and immediately execing another application.
209  *
210  * Not all UNIX implementations support a lightweight fork.  For
211  * the ones that don't we'll do a normal fork.
212  */
213 pid_t
214 util_vfork()
215 {
216     return fork();
217 }
218
219
220 /*
221  * putenv() is non-POSIX, so the parameter types can vary a bit...
222  */
223 #ifdef __cplusplus
224 extern "C" {
225 #endif
226 #if defined(__uxp__) || defined(__hpux) || (defined(sun) && OSMAJORVERSION >= 5 && OSMINORVERSION >= 4 && OSMINORVERSION <=10 )
227     extern int putenv(const char *string);
228 #elif !(defined(__osf__) || defined(__aix) || defined(__NetBSD__))
229     extern int putenv(char *string);
230 #endif
231 #ifdef __cplusplus
232 } // extern "C"
233 #endif
234 int
235 util_putenv(STRING string)
236 {
237     return putenv(string);
238 }
239
240 /*
241  * 
242  */
243 AB_OS_TYPE
244 util_get_os_type(void)
245 {
246     static AB_OS_TYPE           osType = AB_OS_UNDEF;
247     static BOOL                 osTypeDefined = FALSE;
248     int                         rc = 0;         /* return code */
249     struct utsname              sysInfo;
250     int                         aixIndex = -1;
251     int                         hpIndex = -1;
252     int                         sunIndex = -1;
253     int                         unixwareIndex = -1;
254     int                         uxpIndex = -1;
255     int                         osf1Index = -1;
256     int                         lnxIndex = -1;
257     int                         fbsdIndex = -1;
258     int                         nbsdIndex = -1;
259     int                         obsdIndex = -1;
260
261     if (osTypeDefined)
262     {
263         goto epilogue;
264     }
265     if ((rc = uname(&sysInfo)) < 0)
266     {
267         goto epilogue;
268     }
269
270     aixIndex = util_strcasestr(sysInfo.sysname, "aix");
271     hpIndex = util_strcasestr(sysInfo.sysname, "hp");
272     sunIndex = util_strcasestr(sysInfo.sysname, "sun");
273     unixwareIndex = util_strcasestr(sysInfo.sysname, "UNIX_SV");
274     uxpIndex = util_strcasestr(sysInfo.sysname, "UNIX_System_V");
275     osf1Index = util_strcasestr(sysInfo.sysname, "osf1");
276     lnxIndex = util_strcasestr(sysInfo.sysname, "linux");
277     fbsdIndex = util_strcasestr(sysInfo.sysname, "freebsd");
278     nbsdIndex = util_strcasestr(sysInfo.sysname, "netbsd");
279     obsdIndex = util_strcasestr(sysInfo.sysname, "openbsd");
280
281     if (aixIndex < 0) aixIndex = INT_MAX;
282     if (hpIndex < 0) hpIndex = INT_MAX;
283     if (sunIndex < 0) sunIndex = INT_MAX;
284     if (unixwareIndex < 0) unixwareIndex = INT_MAX;
285     if (uxpIndex < 0) uxpIndex = INT_MAX;
286     if (osf1Index < 0) osf1Index = INT_MAX;
287     if (lnxIndex < 0) lnxIndex = INT_MAX;
288     if (fbsdIndex < 0) fbsdIndex = INT_MAX;
289     if (nbsdIndex < 0) nbsdIndex = INT_MAX;
290     if (obsdIndex < 0) obsdIndex = INT_MAX;
291
292 #define IS_MATCH(a,b,c,d,e,f,g,h,i,j)   \
293   (((a) < (b)) && ((a) < (c)) && ((a) < (d)) && ((a) < (e)) && ((a) < (f)) && \
294    ((a) < (g)) && ((a) < (h)) && ((a) < (i)) && ((a) < (j)))
295
296     if (IS_MATCH(aixIndex, hpIndex, sunIndex, osf1Index, unixwareIndex,
297                  uxpIndex, lnxIndex, fbsdIndex, nbsdIndex, obsdIndex))
298     {
299         return AB_OS_AIX;
300     }
301     if (IS_MATCH(hpIndex, aixIndex, sunIndex, osf1Index, unixwareIndex,
302                  uxpIndex, lnxIndex, fbsdIndex, nbsdIndex, obsdIndex))
303     {
304         return AB_OS_HPUX;
305     }
306     if (IS_MATCH(sunIndex, aixIndex, hpIndex, osf1Index, unixwareIndex,
307                  uxpIndex, lnxIndex, fbsdIndex, nbsdIndex, obsdIndex))
308     {
309         return AB_OS_SUNOS;
310     }
311     if (IS_MATCH(osf1Index, aixIndex, hpIndex, sunIndex, unixwareIndex,
312                  uxpIndex, lnxIndex, fbsdIndex, nbsdIndex, obsdIndex))
313     {
314         return AB_OS_OSF1;
315     }
316     if (IS_MATCH(uxpIndex, aixIndex, hpIndex, sunIndex, unixwareIndex,
317                  osf1Index, lnxIndex, fbsdIndex, nbsdIndex, obsdIndex))
318     {
319         return AB_OS_UXP;
320     }
321     if (IS_MATCH(unixwareIndex, aixIndex, hpIndex, sunIndex, osf1Index,
322                  uxpIndex, lnxIndex, fbsdIndex, nbsdIndex, obsdIndex))
323     {
324         return AB_OS_UNIXWARE;
325     }
326     if (IS_MATCH(lnxIndex, aixIndex, hpIndex, sunIndex, osf1Index,
327                  unixwareIndex, uxpIndex, fbsdIndex, nbsdIndex, obsdIndex))
328     {
329         return AB_OS_LNX;
330     }
331     if (IS_MATCH(fbsdIndex, aixIndex, hpIndex, sunIndex, osf1Index,
332                  unixwareIndex, uxpIndex, lnxIndex, nbsdIndex, obsdIndex))
333     {
334         return AB_OS_FBSD;
335     }
336     if (IS_MATCH(nbsdIndex, aixIndex, hpIndex, sunIndex, osf1Index,
337                  unixwareIndex, uxpIndex, lnxIndex, fbsdIndex, obsdIndex))
338     {
339         return AB_OS_NBSD;
340     }
341     if (IS_MATCH(obsdIndex, aixIndex, hpIndex, sunIndex, osf1Index,
342                  unixwareIndex, uxpIndex, lnxIndex, fbsdIndex, nbsdIndex))
343     {
344         return AB_OS_OBSD;
345     }
346
347     osTypeDefined = TRUE;
348
349 epilogue:
350     return osType;
351 }
352
353