18ef8280bc0909042122458cebcde1bf8ac5a7f6
[platform/upstream/glib.git] / glib / gutils.c
1 /* GLIB - Library of useful routines for C programming
2  * Copyright (C) 1995-1998  Peter Mattis, Spencer Kimball and Josh MacDonald
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 /*
21  * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
22  * file for a list of people on the GLib Team.  See the ChangeLog
23  * files for a list of changes.  These files are distributed with
24  * GLib at ftp://ftp.gtk.org/pub/gtk/. 
25  */
26
27 /* 
28  * MT safe for the unix part, FIXME: make the win32 part MT safe as well.
29  */
30
31 #include "config.h"
32
33 #ifdef HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36 #include <stdarg.h>
37 #include <stdlib.h>
38 #include <stdio.h>
39 #include <string.h>
40 #include <errno.h>
41 #ifdef HAVE_PWD_H
42 #include <pwd.h>
43 #endif
44 #include <sys/types.h>
45 #ifdef HAVE_SYS_PARAM_H
46 #include <sys/param.h>
47 #endif
48
49 /* implement gutils's inline functions
50  */
51 #define G_IMPLEMENT_INLINES 1
52 #define __G_UTILS_C__
53 #include "glib.h"
54 #include "gprintfint.h"
55
56 #ifdef  MAXPATHLEN
57 #define G_PATH_LENGTH   MAXPATHLEN
58 #elif   defined (PATH_MAX)
59 #define G_PATH_LENGTH   PATH_MAX
60 #elif   defined (_PC_PATH_MAX)
61 #define G_PATH_LENGTH   sysconf(_PC_PATH_MAX)
62 #else   
63 #define G_PATH_LENGTH   2048
64 #endif
65
66 #ifdef G_PLATFORM_WIN32
67 #  define STRICT                /* Strict typing, please */
68 #  include <windows.h>
69 #  undef STRICT
70 #  include <lmcons.h>           /* For UNLEN */
71 #  include <ctype.h>
72 #endif /* G_PLATFORM_WIN32 */
73
74 #ifdef G_OS_WIN32
75 #  include <direct.h>
76 #endif
77
78 #ifdef HAVE_CODESET
79 #include <langinfo.h>
80 #endif
81
82 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
83 #include <libintl.h>
84 #endif
85
86 const guint glib_major_version = GLIB_MAJOR_VERSION;
87 const guint glib_minor_version = GLIB_MINOR_VERSION;
88 const guint glib_micro_version = GLIB_MICRO_VERSION;
89 const guint glib_interface_age = GLIB_INTERFACE_AGE;
90 const guint glib_binary_age = GLIB_BINARY_AGE;
91
92 #if !defined (HAVE_MEMMOVE) && !defined (HAVE_WORKING_BCOPY)
93 void 
94 g_memmove (gpointer dest, gconstpointer src, gulong len)
95 {
96   gchar* destptr = dest;
97   const gchar* srcptr = src;
98   if (src + len < dest || dest + len < src)
99     {
100       bcopy (src, dest, len);
101       return;
102     }
103   else if (dest <= src)
104     {
105       while (len--)
106         *(destptr++) = *(srcptr++);
107     }
108   else
109     {
110       destptr += len;
111       srcptr += len;
112       while (len--)
113         *(--destptr) = *(--srcptr);
114     }
115 }
116 #endif /* !HAVE_MEMMOVE && !HAVE_WORKING_BCOPY */
117
118 void
119 g_atexit (GVoidFunc func)
120 {
121   gint result;
122   const gchar *error = NULL;
123
124   /* keep this in sync with glib.h */
125
126 #ifdef  G_NATIVE_ATEXIT
127   result = ATEXIT (func);
128   if (result)
129     error = g_strerror (errno);
130 #elif defined (HAVE_ATEXIT)
131 #  ifdef NeXT /* @#%@! NeXTStep */
132   result = !atexit ((void (*)(void)) func);
133   if (result)
134     error = g_strerror (errno);
135 #  else
136   result = atexit ((void (*)(void)) func);
137   if (result)
138     error = g_strerror (errno);
139 #  endif /* NeXT */
140 #elif defined (HAVE_ON_EXIT)
141   result = on_exit ((void (*)(int, void *)) func, NULL);
142   if (result)
143     error = g_strerror (errno);
144 #else
145   result = 0;
146   error = "no implementation";
147 #endif /* G_NATIVE_ATEXIT */
148
149   if (error)
150     g_error ("Could not register atexit() function: %s", error);
151 }
152
153 /* Based on execvp() from GNU Libc.
154  * Some of this code is cut-and-pasted into gspawn.c
155  */
156
157 static gchar*
158 my_strchrnul (const gchar *str, gchar c)
159 {
160   gchar *p = (gchar*)str;
161   while (*p && (*p != c))
162     ++p;
163
164   return p;
165 }
166
167 #ifdef G_OS_WIN32
168
169 gchar *inner_find_program_in_path (const gchar *program);
170
171 gchar*
172 g_find_program_in_path (const gchar *program)
173 {
174   const gchar *last_dot = strrchr (program, '.');
175
176   if (last_dot == NULL || strchr (last_dot, '\\') != NULL)
177     {
178       const gint program_length = strlen (program);
179       const gchar *pathext = getenv ("PATHEXT");
180       const gchar *p;
181       gchar *decorated_program;
182       gchar *retval;
183
184       if (pathext == NULL)
185         pathext = ".com;.exe;.bat";
186
187       p = pathext;
188       do
189         {
190           pathext = p;
191           p = my_strchrnul (pathext, ';');
192
193           decorated_program = g_malloc (program_length + (p-pathext) + 1);
194           memcpy (decorated_program, program, program_length);
195           memcpy (decorated_program+program_length, pathext, p-pathext);
196           decorated_program [program_length + (p-pathext)] = '\0';
197           
198           retval = inner_find_program_in_path (decorated_program);
199           g_free (decorated_program);
200
201           if (retval != NULL)
202             return retval;
203         } while (*p++ != '\0');
204       return NULL;
205     }
206   else
207     return inner_find_program_in_path (program);
208 }
209
210 #define g_find_program_in_path inner_find_program_in_path
211 #endif
212
213 /**
214  * g_find_program_in_path:
215  * @program: a program name
216  * 
217  * Locates the first executable named @program in the user's path, in the
218  * same way that execvp() would locate it. Returns an allocated string
219  * with the absolute path name, or NULL if the program is not found in
220  * the path. If @program is already an absolute path, returns a copy of
221  * @program if @program exists and is executable, and NULL otherwise.
222  * 
223  * On Windows, if @program does not have a file type suffix, tries to
224  * append the suffixes in the PATHEXT environment variable (if that
225  * doesn't exists, the suffixes .com, .exe, and .bat) in turn, and
226  * then look for the resulting file name in the same way as
227  * CreateProcess() would. This means first in the directory where the
228  * program was loaded from, then in the current directory, then in the
229  * Windows 32-bit system directory, then in the Windows directory, and
230  * finally in the directories in the PATH environment variable. If
231  * the program is found, the return value contains the full name
232  * including the type suffix.
233  *
234  * Return value: absolute path, or NULL
235  **/
236 gchar*
237 g_find_program_in_path (const gchar *program)
238 {
239   const gchar *path, *p;
240   gchar *name, *freeme;
241 #ifdef G_OS_WIN32
242   gchar *path_tmp;
243 #endif
244   size_t len;
245   size_t pathlen;
246
247   g_return_val_if_fail (program != NULL, NULL);
248
249   /* If it is an absolute path, or a relative path including subdirectories,
250    * don't look in PATH.
251    */
252   if (g_path_is_absolute (program)
253       || strchr (program, G_DIR_SEPARATOR) != NULL)
254     {
255       if (g_file_test (program, G_FILE_TEST_IS_EXECUTABLE))
256         return g_strdup (program);
257       else
258         return NULL;
259     }
260   
261   path = g_getenv ("PATH");
262 #ifdef G_OS_UNIX
263   if (path == NULL)
264     {
265       /* There is no `PATH' in the environment.  The default
266        * search path in GNU libc is the current directory followed by
267        * the path `confstr' returns for `_CS_PATH'.
268        */
269       
270       /* In GLib we put . last, for security, and don't use the
271        * unportable confstr(); UNIX98 does not actually specify
272        * what to search if PATH is unset. POSIX may, dunno.
273        */
274       
275       path = "/bin:/usr/bin:.";
276     }
277 #else
278   {
279     gchar *tmp;
280     gchar moddir[MAXPATHLEN], sysdir[MAXPATHLEN], windir[MAXPATHLEN];
281
282     GetModuleFileName (NULL, moddir, sizeof (moddir));
283     tmp = g_path_get_dirname (moddir);
284     GetSystemDirectory (sysdir, sizeof (sysdir));
285     GetWindowsDirectory (windir, sizeof (windir));
286     path_tmp = g_strconcat (tmp, ";.;", sysdir, ";", windir,
287                             (path != NULL ? ";" : NULL),
288                             (path != NULL ? path : NULL),
289                             NULL);
290     g_free (tmp);
291     path = path_tmp;
292   }
293 #endif
294   
295   len = strlen (program) + 1;
296   pathlen = strlen (path);
297   freeme = name = g_malloc (pathlen + len + 1);
298   
299   /* Copy the file name at the top, including '\0'  */
300   memcpy (name + pathlen + 1, program, len);
301   name = name + pathlen;
302   /* And add the slash before the filename  */
303   *name = G_DIR_SEPARATOR;
304   
305   p = path;
306   do
307     {
308       char *startp;
309
310       path = p;
311       p = my_strchrnul (path, G_SEARCHPATH_SEPARATOR);
312
313       if (p == path)
314         /* Two adjacent colons, or a colon at the beginning or the end
315          * of `PATH' means to search the current directory.
316          */
317         startp = name + 1;
318       else
319         startp = memcpy (name - (p - path), path, p - path);
320
321       if (g_file_test (startp, G_FILE_TEST_IS_EXECUTABLE))
322         {
323           gchar *ret;
324           ret = g_strdup (startp);
325           g_free (freeme);
326 #ifdef G_OS_WIN32
327           g_free (path_tmp);
328 #endif
329           return ret;
330         }
331     }
332   while (*p++ != '\0');
333   
334   g_free (freeme);
335 #ifdef G_OS_WIN32
336   g_free (path_tmp);
337 #endif
338
339   return NULL;
340 }
341
342 guint        
343 g_parse_debug_string  (const gchar     *string, 
344                        const GDebugKey *keys, 
345                        guint            nkeys)
346 {
347   guint i;
348   guint result = 0;
349   
350   g_return_val_if_fail (string != NULL, 0);
351   
352   if (!g_ascii_strcasecmp (string, "all"))
353     {
354       for (i=0; i<nkeys; i++)
355         result |= keys[i].value;
356     }
357   else
358     {
359       const gchar *p = string;
360       const gchar *q;
361       gboolean done = FALSE;
362       
363       while (*p && !done)
364         {
365           q = strchr (p, ':');
366           if (!q)
367             {
368               q = p + strlen(p);
369               done = TRUE;
370             }
371           
372           for (i=0; i<nkeys; i++)
373             if (g_ascii_strncasecmp(keys[i].key, p, q - p) == 0 &&
374                 keys[i].key[q - p] == '\0')
375               result |= keys[i].value;
376           
377           p = q + 1;
378         }
379     }
380   
381   return result;
382 }
383
384 /**
385  * g_basename:
386  * @file_name: the name of the file.
387  * 
388  * Gets the name of the file without any leading directory components.  
389  * It returns a pointer into the given file name string.
390  * 
391  * Return value: the name of the file without any leading directory components.
392  *
393  * Deprecated: Use g_path_get_basename() instead, but notice that
394  * g_path_get_basename() allocates new memory for the returned string, unlike
395  * this function which returns a pointer into the argument.
396  **/
397 G_CONST_RETURN gchar*
398 g_basename (const gchar    *file_name)
399 {
400   register gchar *base;
401   
402   g_return_val_if_fail (file_name != NULL, NULL);
403   
404   base = strrchr (file_name, G_DIR_SEPARATOR);
405   if (base)
406     return base + 1;
407
408 #ifdef G_OS_WIN32
409   if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
410     return (gchar*) file_name + 2;
411 #endif /* G_OS_WIN32 */
412   
413   return (gchar*) file_name;
414 }
415
416 /**
417  * g_path_get_basename:
418  * @file_name: the name of the file.
419  *
420  * Gets the last component of the filename. If @file_name ends with a 
421  * directory separator it gets the component before the last slash. If 
422  * @file_name consists only of directory separators (and on Windows, 
423  * possibly a drive letter), a single separator is returned. If
424  * @file_name is empty, it gets ".".
425  *
426  * Return value: a newly allocated string containing the last component of 
427  *   the filename.
428  */
429 gchar*
430 g_path_get_basename (const gchar   *file_name)
431 {
432   register gssize base;             
433   register gssize last_nonslash;    
434   gsize len;    
435   gchar *retval;
436  
437   g_return_val_if_fail (file_name != NULL, NULL);
438
439   if (file_name[0] == '\0')
440     /* empty string */
441     return g_strdup (".");
442   
443   last_nonslash = strlen (file_name) - 1;
444
445   while (last_nonslash >= 0 && file_name [last_nonslash] == G_DIR_SEPARATOR)
446     last_nonslash--;
447
448   if (last_nonslash == -1)
449     /* string only containing slashes */
450     return g_strdup (G_DIR_SEPARATOR_S);
451
452 #ifdef G_OS_WIN32
453   if (last_nonslash == 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
454     /* string only containing slashes and a drive */
455     return g_strdup (G_DIR_SEPARATOR_S);
456 #endif /* G_OS_WIN32 */
457
458   base = last_nonslash;
459
460   while (base >=0 && file_name [base] != G_DIR_SEPARATOR)
461     base--;
462
463 #ifdef G_OS_WIN32
464   if (base == -1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
465     base = 1;
466 #endif /* G_OS_WIN32 */
467
468   len = last_nonslash - base;
469   retval = g_malloc (len + 1);
470   memcpy (retval, file_name + base + 1, len);
471   retval [len] = '\0';
472   return retval;
473 }
474
475 gboolean
476 g_path_is_absolute (const gchar *file_name)
477 {
478   g_return_val_if_fail (file_name != NULL, FALSE);
479   
480   if (file_name[0] == G_DIR_SEPARATOR
481 #ifdef G_OS_WIN32
482       || file_name[0] == '/'
483 #endif
484                                      )
485     return TRUE;
486
487 #ifdef G_OS_WIN32
488   /* Recognize drive letter on native Windows */
489   if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && (file_name[2] == G_DIR_SEPARATOR || file_name[2] == '/'))
490     return TRUE;
491 #endif /* G_OS_WIN32 */
492
493   return FALSE;
494 }
495
496 G_CONST_RETURN gchar*
497 g_path_skip_root (const gchar *file_name)
498 {
499   g_return_val_if_fail (file_name != NULL, NULL);
500   
501 #ifdef G_PLATFORM_WIN32
502   /* Skip \\server\share (Win32) or //server/share (Cygwin) */
503   if (file_name[0] == G_DIR_SEPARATOR &&
504       file_name[1] == G_DIR_SEPARATOR &&
505       file_name[2])
506     {
507       gchar *p;
508
509       if ((p = strchr (file_name + 2, G_DIR_SEPARATOR)) > file_name + 2 &&
510           p[1])
511         {
512           file_name = p + 1;
513
514           while (file_name[0] && file_name[0] != G_DIR_SEPARATOR)
515             file_name++;
516
517           /* Possibly skip a backslash after the share name */
518           if (file_name[0] == G_DIR_SEPARATOR)
519             file_name++;
520
521           return (gchar *)file_name;
522         }
523     }
524 #endif
525   
526   /* Skip initial slashes */
527   if (file_name[0] == G_DIR_SEPARATOR)
528     {
529       while (file_name[0] == G_DIR_SEPARATOR)
530         file_name++;
531       return (gchar *)file_name;
532     }
533
534 #ifdef G_OS_WIN32
535   /* Skip X:\ */
536   if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && file_name[2] == G_DIR_SEPARATOR)
537     return (gchar *)file_name + 3;
538 #endif
539
540   return NULL;
541 }
542
543 gchar*
544 g_path_get_dirname (const gchar    *file_name)
545 {
546   register gchar *base;
547   register gsize len;    
548   
549   g_return_val_if_fail (file_name != NULL, NULL);
550   
551   base = strrchr (file_name, G_DIR_SEPARATOR);
552   if (!base)
553     return g_strdup (".");
554   while (base > file_name && *base == G_DIR_SEPARATOR)
555     base--;
556   len = (guint) 1 + base - file_name;
557   
558   base = g_new (gchar, len + 1);
559   g_memmove (base, file_name, len);
560   base[len] = 0;
561   
562   return base;
563 }
564
565 gchar*
566 g_get_current_dir (void)
567 {
568   gchar *buffer = NULL;
569   gchar *dir = NULL;
570   static gulong max_len = 0;
571
572   if (max_len == 0) 
573     max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
574   
575   /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
576    * and, if that wasn't bad enough, hangs in doing so.
577    */
578 #if     (defined (sun) && !defined (__SVR4)) || !defined(HAVE_GETCWD)
579   buffer = g_new (gchar, max_len + 1);
580   *buffer = 0;
581   dir = getwd (buffer);
582 #else   /* !sun || !HAVE_GETCWD */
583   while (max_len < G_MAXULONG / 2)
584     {
585       buffer = g_new (gchar, max_len + 1);
586       *buffer = 0;
587       dir = getcwd (buffer, max_len);
588
589       if (dir || errno != ERANGE)
590         break;
591
592       g_free (buffer);
593       max_len *= 2;
594     }
595 #endif  /* !sun || !HAVE_GETCWD */
596   
597   if (!dir || !*buffer)
598     {
599       /* hm, should we g_error() out here?
600        * this can happen if e.g. "./" has mode \0000
601        */
602       buffer[0] = G_DIR_SEPARATOR;
603       buffer[1] = 0;
604     }
605
606   dir = g_strdup (buffer);
607   g_free (buffer);
608   
609   return dir;
610 }
611
612 /**
613  * g_getenv:
614  * @variable: the environment variable to get.
615  * 
616  * Returns an environment variable.
617  * 
618  * Return value: the value of the environment variable, or %NULL if the environment
619  * variable is not found. The returned string may be overwritten by the next call to g_getenv(),
620  * g_setenv() or g_unsetenv().
621  **/
622 G_CONST_RETURN gchar*
623 g_getenv (const gchar *variable)
624 {
625 #ifndef G_OS_WIN32
626   g_return_val_if_fail (variable != NULL, NULL);
627
628   return getenv (variable);
629 #else
630   G_LOCK_DEFINE_STATIC (getenv);
631   struct env_struct
632   {
633     gchar *key;
634     gchar *value;
635   } *env;
636   static GArray *environs = NULL;
637   gchar *system_env;
638   guint length, i;
639   gchar dummy[2];
640
641   g_return_val_if_fail (variable != NULL, NULL);
642   
643   G_LOCK (getenv);
644
645   if (!environs)
646     environs = g_array_new (FALSE, FALSE, sizeof (struct env_struct));
647
648   /* First we try to find the environment variable inside the already
649    * found ones.
650    */
651
652   for (i = 0; i < environs->len; i++)
653     {
654       env = &g_array_index (environs, struct env_struct, i);
655       if (strcmp (env->key, variable) == 0)
656         {
657           g_assert (env->value);
658           G_UNLOCK (getenv);
659           return env->value;
660         }
661     }
662
663   /* If not found, we ask the system */
664
665   system_env = getenv (variable);
666   if (!system_env)
667     {
668       G_UNLOCK (getenv);
669       return NULL;
670     }
671
672   /* On Windows NT, it is relatively typical that environment variables
673    * contain references to other environment variables. Handle that by
674    * calling ExpandEnvironmentStrings.
675    */
676
677   g_array_set_size (environs, environs->len + 1);
678
679   env = &g_array_index (environs, struct env_struct, environs->len - 1);
680
681   /* First check how much space we need */
682   length = ExpandEnvironmentStrings (system_env, dummy, 2);
683
684   /* Then allocate that much, and actualy do the expansion and insert
685    * the new found pair into our buffer 
686    */
687
688   env->value = g_malloc (length);
689   env->key = g_strdup (variable);
690
691   ExpandEnvironmentStrings (system_env, env->value, length);
692
693   G_UNLOCK (getenv);
694   return env->value;
695 #endif
696 }
697
698 /**
699  * g_setenv:
700  * @variable: the environment variable to set, must not contain '='.
701  * @value: the value for to set the variable to.
702  * @overwrite: whether to change the variable if it already exists.
703  *
704  * Sets an environment variable.
705  *
706  * Note that on some systems, the memory used for the variable and its value 
707  * can't be reclaimed later.
708  *
709  * Returns: %FALSE if the environment variable couldn't be set.
710  *
711  * Since: 2.4
712  */
713 gboolean
714 g_setenv (const gchar *variable, 
715           const gchar *value, 
716           gboolean     overwrite)
717 {
718   gint result;
719   g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE);
720 #ifdef HAVE_SETENV
721   result = setenv (variable, value, overwrite);
722 #else
723   gchar *string;
724   
725   if (!overwrite && g_getenv (variable) != NULL)
726     return TRUE;
727   
728   /* This results in a leak when you overwrite existing
729    * settings. It would be fairly easy to fix this by keeping
730    * our own parallel array or hash table.
731    */
732   string = g_strconcat (variable, "=", value, NULL);
733   result = putenv (string);
734 #endif
735   return result == 0;
736 }
737
738 #ifndef HAVE_UNSETENV     
739 /* According to the Single Unix Specification, environ is not in 
740  * any system header, although unistd.h often declares it.
741  */
742 extern char **environ;
743 #endif
744            
745 /**
746  * g_unsetenv:
747  * @variable: the environment variable to remove, must not contain '='.
748  * 
749  * Removes an environment variable from the environment.
750  *
751  * Note that on some systems, the memory used for the variable and its value 
752  * can't be reclaimed. Furthermore, this function can't be guaranteed to operate in a 
753  * threadsafe way.
754  *
755  * Since: 2.4 
756  **/
757 void
758 g_unsetenv (const gchar *variable)
759 {
760 #ifdef HAVE_UNSETENV
761   g_return_if_fail (strchr (variable, '=') == NULL);
762
763   unsetenv (variable);
764 #else
765   int i, len;
766   gchar **e, **f;
767
768   g_return_if_fail (strchr (variable, '=') == NULL);
769
770   len = strlen (variable);
771   
772   /* Mess directly with the environ array.
773    * This seems to be the only portable way to do this.
774    *
775    * Note that we remove *all* environment entries for
776    * the variable name, not just the first.
777    */
778   e = f = environ;
779   while (*e != NULL) 
780     {
781       if (strncmp (*e, variable, len) != 0 || (*e)[len] != '=') 
782         {
783           *f = *e;
784           f++;
785         }
786       e++;
787     }
788   *f = NULL;
789 #endif
790 }
791
792 G_LOCK_DEFINE_STATIC (g_utils_global);
793
794 static  gchar   *g_tmp_dir = NULL;
795 static  gchar   *g_user_name = NULL;
796 static  gchar   *g_real_name = NULL;
797 static  gchar   *g_home_dir = NULL;
798
799 /* HOLDS: g_utils_global_lock */
800 static void
801 g_get_any_init (void)
802 {
803   if (!g_tmp_dir)
804     {
805       g_tmp_dir = g_strdup (g_getenv ("TMPDIR"));
806       if (!g_tmp_dir)
807         g_tmp_dir = g_strdup (g_getenv ("TMP"));
808       if (!g_tmp_dir)
809         g_tmp_dir = g_strdup (g_getenv ("TEMP"));
810       
811 #ifdef P_tmpdir
812       if (!g_tmp_dir)
813         {
814           gsize k;    
815           g_tmp_dir = g_strdup (P_tmpdir);
816           k = strlen (g_tmp_dir);
817           if (k > 1 && g_tmp_dir[k - 1] == G_DIR_SEPARATOR)
818             g_tmp_dir[k - 1] = '\0';
819         }
820 #endif
821       
822       if (!g_tmp_dir)
823         {
824 #ifndef G_OS_WIN32
825           g_tmp_dir = g_strdup ("/tmp");
826 #else /* G_OS_WIN32 */
827           g_tmp_dir = g_strdup ("C:\\");
828 #endif /* G_OS_WIN32 */
829         }
830       
831 #ifdef G_OS_WIN32
832       /* We check $HOME first for Win32, though it is a last resort for Unix
833        * where we prefer the results of getpwuid().
834        */
835       g_home_dir = g_strdup (g_getenv ("HOME"));
836       
837       /* In case HOME is Unix-style (it happens), convert it to
838        * Windows style.
839        */
840       if (g_home_dir)
841         {
842           gchar *p;
843           while ((p = strchr (g_home_dir, '/')) != NULL)
844             *p = '\\';
845         }
846
847       if (!g_home_dir)
848         {
849           /* USERPROFILE is probably the closest equivalent to $HOME? */
850           if (getenv ("USERPROFILE") != NULL)
851             g_home_dir = g_strdup (g_getenv ("USERPROFILE"));
852         }
853
854       if (!g_home_dir)
855         {
856           /* At least at some time, HOMEDRIVE and HOMEPATH were used
857            * to point to the home directory, I think. But on Windows
858            * 2000 HOMEDRIVE seems to be equal to SYSTEMDRIVE, and
859            * HOMEPATH is its root "\"?
860            */
861           if (getenv ("HOMEDRIVE") != NULL && getenv ("HOMEPATH") != NULL)
862             {
863               gchar *homedrive, *homepath;
864               
865               homedrive = g_strdup (g_getenv ("HOMEDRIVE"));
866               homepath = g_strdup (g_getenv ("HOMEPATH"));
867               
868               g_home_dir = g_strconcat (homedrive, homepath, NULL);
869               g_free (homedrive);
870               g_free (homepath);
871             }
872         }
873 #endif /* G_OS_WIN32 */
874       
875 #ifdef HAVE_PWD_H
876       {
877         struct passwd *pw = NULL;
878         gpointer buffer = NULL;
879         gint error;
880         
881 #  if defined (HAVE_POSIX_GETPWUID_R) || defined (HAVE_NONPOSIX_GETPWUID_R)
882         struct passwd pwd;
883 #    ifdef _SC_GETPW_R_SIZE_MAX  
884         /* This reurns the maximum length */
885         glong bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
886         
887         if (bufsize < 0)
888           bufsize = 64;
889 #    else /* _SC_GETPW_R_SIZE_MAX */
890         glong bufsize = 64;
891 #    endif /* _SC_GETPW_R_SIZE_MAX */
892         
893         do
894           {
895             g_free (buffer);
896             buffer = g_malloc (bufsize);
897             errno = 0;
898             
899 #    ifdef HAVE_POSIX_GETPWUID_R
900             error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
901             error = error < 0 ? errno : error;
902 #    else /* HAVE_NONPOSIX_GETPWUID_R */
903        /* HPUX 11 falls into the HAVE_POSIX_GETPWUID_R case */
904 #      if defined(_AIX) || defined(__hpux)
905             error = getpwuid_r (getuid (), &pwd, buffer, bufsize);
906             pw = error == 0 ? &pwd : NULL;
907 #      else /* !_AIX */
908             pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
909             error = pw ? 0 : errno;
910 #      endif /* !_AIX */            
911 #    endif /* HAVE_NONPOSIX_GETPWUID_R */
912             
913             if (!pw)
914               {
915                 /* we bail out prematurely if the user id can't be found
916                  * (should be pretty rare case actually), or if the buffer
917                  * should be sufficiently big and lookups are still not
918                  * successfull.
919                  */
920                 if (error == 0 || error == ENOENT)
921                   {
922                     g_warning ("getpwuid_r(): failed due to unknown user id (%lu)",
923                                (gulong) getuid ());
924                     break;
925                   }
926                 if (bufsize > 32 * 1024)
927                   {
928                     g_warning ("getpwuid_r(): failed due to: %s.",
929                                g_strerror (error));
930                     break;
931                   }
932                 
933                 bufsize *= 2;
934               }
935           }
936         while (!pw);
937 #  endif /* HAVE_POSIX_GETPWUID_R || HAVE_NONPOSIX_GETPWUID_R */
938         
939         if (!pw)
940           {
941             setpwent ();
942             pw = getpwuid (getuid ());
943             endpwent ();
944           }
945         if (pw)
946           {
947             g_user_name = g_strdup (pw->pw_name);
948             g_real_name = g_strdup (pw->pw_gecos);
949             if (!g_home_dir)
950               g_home_dir = g_strdup (pw->pw_dir);
951           }
952         g_free (buffer);
953       }
954       
955 #else /* !HAVE_PWD_H */
956       
957 #  ifdef G_OS_WIN32
958       {
959         guint len = UNLEN+1;
960         gchar buffer[UNLEN+1];
961         
962         if (GetUserName ((LPTSTR) buffer, (LPDWORD) &len))
963           {
964             g_user_name = g_strdup (buffer);
965             g_real_name = g_strdup (buffer);
966           }
967       }
968 #  endif /* G_OS_WIN32 */
969
970 #endif /* !HAVE_PWD_H */
971
972       if (!g_home_dir)
973         g_home_dir = g_strdup (g_getenv ("HOME"));
974       
975 #ifdef __EMX__
976       /* change '\\' in %HOME% to '/' */
977       g_strdelimit (g_home_dir, "\\",'/');
978 #endif
979       if (!g_user_name)
980         g_user_name = g_strdup ("somebody");
981       if (!g_real_name)
982         g_real_name = g_strdup ("Unknown");
983       else
984         {
985           gchar *p;
986
987           for (p = g_real_name; *p; p++)
988             if (*p == ',')
989               {
990                 *p = 0;
991                 p = g_strdup (g_real_name);
992                 g_free (g_real_name);
993                 g_real_name = p;
994                 break;
995               }
996         }
997     }
998 }
999
1000 G_CONST_RETURN gchar*
1001 g_get_user_name (void)
1002 {
1003   G_LOCK (g_utils_global);
1004   if (!g_tmp_dir)
1005     g_get_any_init ();
1006   G_UNLOCK (g_utils_global);
1007   
1008   return g_user_name;
1009 }
1010
1011 G_CONST_RETURN gchar*
1012 g_get_real_name (void)
1013 {
1014   G_LOCK (g_utils_global);
1015   if (!g_tmp_dir)
1016     g_get_any_init ();
1017   G_UNLOCK (g_utils_global);
1018  
1019   return g_real_name;
1020 }
1021
1022 /* Return the home directory of the user. If there is a HOME
1023  * environment variable, its value is returned, otherwise use some
1024  * system-dependent way of finding it out. If no home directory can be
1025  * deduced, return NULL.
1026  */
1027
1028 G_CONST_RETURN gchar*
1029 g_get_home_dir (void)
1030 {
1031   G_LOCK (g_utils_global);
1032   if (!g_tmp_dir)
1033     g_get_any_init ();
1034   G_UNLOCK (g_utils_global);
1035   
1036   return g_home_dir;
1037 }
1038
1039 /* Return a directory to be used to store temporary files. This is the
1040  * value of the TMPDIR, TMP or TEMP environment variables (they are
1041  * checked in that order). If none of those exist, use P_tmpdir from
1042  * stdio.h.  If that isn't defined, return "/tmp" on POSIXly systems,
1043  * and C:\ on Windows.
1044  */
1045
1046 G_CONST_RETURN gchar*
1047 g_get_tmp_dir (void)
1048 {
1049   G_LOCK (g_utils_global);
1050   if (!g_tmp_dir)
1051     g_get_any_init ();
1052   G_UNLOCK (g_utils_global);
1053   
1054   return g_tmp_dir;
1055 }
1056
1057 G_LOCK_DEFINE (g_prgname);
1058 static gchar *g_prgname = NULL;
1059
1060 gchar*
1061 g_get_prgname (void)
1062 {
1063   gchar* retval;
1064
1065   G_LOCK (g_prgname);
1066   retval = g_prgname;
1067   G_UNLOCK (g_prgname);
1068
1069   return retval;
1070 }
1071
1072 void
1073 g_set_prgname (const gchar *prgname)
1074 {
1075   G_LOCK (g_prgname);
1076   g_free (g_prgname);
1077   g_prgname = g_strdup (prgname);
1078   G_UNLOCK (g_prgname);
1079 }
1080
1081 G_LOCK_DEFINE (g_application_name);
1082 static gchar *g_application_name = NULL;
1083
1084 /**
1085  * g_get_application_name:
1086  * 
1087  * Gets a human-readable name for the application, as set by
1088  * g_set_application_name(). This name should be localized if
1089  * possible, and is intended for display to the user.  Contrast with
1090  * g_get_prgname(), which gets a non-localized name. If
1091  * g_set_application_name() has not been called, returns the result of
1092  * g_get_prgname() (which may be %NULL if g_set_prgname() has also not
1093  * been called).
1094  * 
1095  * Return value: human-readable application name. may return %NULL
1096  *
1097  * Since: 2.2
1098  **/
1099 G_CONST_RETURN gchar*
1100 g_get_application_name (void)
1101 {
1102   gchar* retval;
1103
1104   G_LOCK (g_application_name);
1105   retval = g_application_name;
1106   G_UNLOCK (g_application_name);
1107
1108   if (retval == NULL)
1109     return g_get_prgname ();
1110   
1111   return retval;
1112 }
1113
1114 /**
1115  * g_set_application_name:
1116  * @application_name: localized name of the application
1117  *
1118  * Sets a human-readable name for the application. This name should be
1119  * localized if possible, and is intended for display to the user.
1120  * Contrast with g_set_prgname(), which sets a non-localized name.
1121  * g_set_prgname() will be called automatically by gtk_init(),
1122  * but g_set_application_name() will not.
1123  *
1124  * Note that for thread safety reasons, this function can only
1125  * be called once.
1126  *
1127  * The application name will be used in contexts such as error messages,
1128  * or when displaying an application's name in the task list.
1129  * 
1130  **/
1131 void
1132 g_set_application_name (const gchar *application_name)
1133 {
1134   gboolean already_set = FALSE;
1135         
1136   G_LOCK (g_application_name);
1137   if (g_application_name)
1138     already_set = TRUE;
1139   else
1140     g_application_name = g_strdup (application_name);
1141   G_UNLOCK (g_application_name);
1142
1143   if (already_set)
1144     g_warning ("g_set_application() name called multiple times");
1145 }
1146
1147 guint
1148 g_direct_hash (gconstpointer v)
1149 {
1150   return GPOINTER_TO_UINT (v);
1151 }
1152
1153 gboolean
1154 g_direct_equal (gconstpointer v1,
1155                 gconstpointer v2)
1156 {
1157   return v1 == v2;
1158 }
1159
1160 gboolean
1161 g_int_equal (gconstpointer v1,
1162              gconstpointer v2)
1163 {
1164   return *((const gint*) v1) == *((const gint*) v2);
1165 }
1166
1167 guint
1168 g_int_hash (gconstpointer v)
1169 {
1170   return *(const gint*) v;
1171 }
1172
1173 /**
1174  * g_nullify_pointer:
1175  * @nullify_location: the memory address of the pointer.
1176  * 
1177  * Set the pointer at the specified location to %NULL.
1178  **/
1179 void
1180 g_nullify_pointer (gpointer *nullify_location)
1181 {
1182   g_return_if_fail (nullify_location != NULL);
1183
1184   *nullify_location = NULL;
1185 }
1186
1187 /**
1188  * g_get_codeset:
1189  * 
1190  * Get the codeset for the current locale.
1191  * 
1192  * Return value: a newly allocated string containing the name
1193  * of the codeset. This string must be freed with g_free().
1194  **/
1195 gchar *
1196 g_get_codeset (void)
1197 {
1198 #ifdef HAVE_CODESET  
1199   char *result = nl_langinfo (CODESET);
1200   return g_strdup (result);
1201 #else
1202 #ifdef G_PLATFORM_WIN32
1203   return g_strdup_printf ("CP%d", GetACP ());
1204 #else
1205   /* FIXME: Do something more intelligent based on setlocale (LC_CTYPE, NULL)
1206    */
1207   return g_strdup ("ISO-8859-1");
1208 #endif
1209 #endif
1210 }
1211
1212 #ifdef ENABLE_NLS
1213
1214 #include <libintl.h>
1215
1216 #ifdef G_PLATFORM_WIN32
1217
1218 G_WIN32_DLLMAIN_FOR_DLL_NAME (static, dll_name)
1219
1220 static const gchar *
1221 _glib_get_locale_dir (void)
1222 {
1223   static const gchar *cache = NULL;
1224   if (cache == NULL)
1225     cache = g_win32_get_package_installation_subdirectory
1226       (GETTEXT_PACKAGE, dll_name, "lib\\locale");
1227
1228   return cache;
1229 }
1230
1231 #undef GLIB_LOCALE_DIR
1232 #define GLIB_LOCALE_DIR _glib_get_locale_dir ()
1233
1234 #endif /* G_PLATFORM_WIN32 */
1235
1236 G_CONST_RETURN gchar *
1237 _glib_gettext (const gchar *str)
1238 {
1239   static gboolean _glib_gettext_initialized = FALSE;
1240
1241   if (!_glib_gettext_initialized)
1242     {
1243       bindtextdomain(GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
1244 #    ifdef HAVE_BIND_TEXTDOMAIN_CODESET
1245       bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
1246 #    endif
1247       _glib_gettext_initialized = TRUE;
1248     }
1249   
1250   return dgettext (GETTEXT_PACKAGE, str);
1251 }
1252
1253 #endif /* ENABLE_NLS */