Check for crt_externs.h and _NSGetEnviron.
[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 <locale.h>
40 #include <string.h>
41 #include <errno.h>
42 #ifdef HAVE_PWD_H
43 #include <pwd.h>
44 #endif
45 #include <sys/types.h>
46 #ifdef HAVE_SYS_PARAM_H
47 #include <sys/param.h>
48 #endif
49 #ifdef HAVE_CRT_EXTERNS_H 
50 #include <crt-externs.h> /* for _NSGetEnviron */
51 #endif
52
53 /* implement gutils's inline functions
54  */
55 #define G_IMPLEMENT_INLINES 1
56 #define __G_UTILS_C__
57 #include "glib.h"
58 #include "gprintfint.h"
59 #include "gthreadinit.h"
60 #include "galias.h"
61
62 #ifdef  MAXPATHLEN
63 #define G_PATH_LENGTH   MAXPATHLEN
64 #elif   defined (PATH_MAX)
65 #define G_PATH_LENGTH   PATH_MAX
66 #elif   defined (_PC_PATH_MAX)
67 #define G_PATH_LENGTH   sysconf(_PC_PATH_MAX)
68 #else   
69 #define G_PATH_LENGTH   2048
70 #endif
71
72 #ifdef G_PLATFORM_WIN32
73 #  define STRICT                /* Strict typing, please */
74 #  include <windows.h>
75 #  undef STRICT
76 #  ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
77 #    define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 2
78 #    define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 4
79 #  endif
80 #  include <lmcons.h>           /* For UNLEN */
81 #endif /* G_PLATFORM_WIN32 */
82
83 #ifdef G_OS_WIN32
84 #  include <direct.h>
85 #  include <shlobj.h>
86    /* older SDK (e.g. msvc 5.0) does not have these*/
87 #  ifndef CSIDL_INTERNET_CACHE
88 #    define CSIDL_INTERNET_CACHE 32
89 #  endif
90 #  ifndef CSIDL_COMMON_APPDATA
91 #    define CSIDL_COMMON_APPDATA 35
92 #  endif
93 #  ifndef CSIDL_COMMON_DOCUMENTS
94 #    define CSIDL_COMMON_DOCUMENTS 46
95 #  endif
96 #  ifndef CSIDL_PROFILE
97 #    define CSIDL_PROFILE 40
98 #  endif
99 #  include <process.h>
100 #endif
101
102 #ifdef HAVE_CODESET
103 #include <langinfo.h>
104 #endif
105
106 #ifdef HAVE_BIND_TEXTDOMAIN_CODESET
107 #include <libintl.h>
108 #endif
109
110 const guint glib_major_version = GLIB_MAJOR_VERSION;
111 const guint glib_minor_version = GLIB_MINOR_VERSION;
112 const guint glib_micro_version = GLIB_MICRO_VERSION;
113 const guint glib_interface_age = GLIB_INTERFACE_AGE;
114 const guint glib_binary_age = GLIB_BINARY_AGE;
115
116 #ifdef G_PLATFORM_WIN32
117
118 G_WIN32_DLLMAIN_FOR_DLL_NAME (static, dll_name)
119
120 #endif
121
122 /**
123  * glib_check_version:
124  * @required_major: the required major version.
125  * @required_minor: the required major version.
126  * @required_micro: the required major version.
127  *
128  * Checks that the GLib library in use is compatible with the
129  * given version. Generally you would pass in the constants
130  * #GLIB_MAJOR_VERSION, #GLIB_MINOR_VERSION, #GLIB_MICRO_VERSION
131  * as the three arguments to this function; that produces
132  * a check that the library in use is compatible with
133  * the version of GLib the application or module was compiled
134  * against.
135  *
136  * Compatibility is defined by two things: first the version
137  * of the running library is newer than the version
138  * @required_major.required_minor.@required_micro. Second
139  * the running library must be binary compatible with the
140  * version @required_major.required_minor.@required_micro
141  * (same major version.)
142  *
143  * Return value: %NULL if the GLib library is compatible with the
144  *   given version, or a string describing the version mismatch.
145  *   The returned string is owned by GLib and must not be modified
146  *   or freed.
147  *
148  * Since: 2.6
149  **/
150 const gchar *
151 glib_check_version (guint required_major,
152                     guint required_minor,
153                     guint required_micro)
154 {
155   gint glib_effective_micro = 100 * GLIB_MINOR_VERSION + GLIB_MICRO_VERSION;
156   gint required_effective_micro = 100 * required_minor + required_micro;
157
158   if (required_major > GLIB_MAJOR_VERSION)
159     return "GLib version too old (major mismatch)";
160   if (required_major < GLIB_MAJOR_VERSION)
161     return "GLib version too new (major mismatch)";
162   if (required_effective_micro < glib_effective_micro - GLIB_BINARY_AGE)
163     return "GLib version too new (micro mismatch)";
164   if (required_effective_micro > glib_effective_micro)
165     return "GLib version too old (micro mismatch)";
166   return NULL;
167 }
168
169 #if !defined (HAVE_MEMMOVE) && !defined (HAVE_WORKING_BCOPY)
170 /**
171  * g_memmove: 
172  * @dest: the destination address to copy the bytes to.
173  * @src: the source address to copy the bytes from.
174  * @len: the number of bytes to copy.
175  *
176  * Copies a block of memory @len bytes long, from @src to @dest.
177  * The source and destination areas may overlap.
178  *
179  * In order to use this function, you must include 
180  * <filename>string.h</filename> yourself, because this macro will 
181  * typically simply resolve to memmove() and GLib does not include 
182  * <filename>string.h</filename> for you.
183  */
184 void 
185 g_memmove (gpointer      dest, 
186            gconstpointer src, 
187            gulong        len)
188 {
189   gchar* destptr = dest;
190   const gchar* srcptr = src;
191   if (src + len < dest || dest + len < src)
192     {
193       bcopy (src, dest, len);
194       return;
195     }
196   else if (dest <= src)
197     {
198       while (len--)
199         *(destptr++) = *(srcptr++);
200     }
201   else
202     {
203       destptr += len;
204       srcptr += len;
205       while (len--)
206         *(--destptr) = *(--srcptr);
207     }
208 }
209 #endif /* !HAVE_MEMMOVE && !HAVE_WORKING_BCOPY */
210
211 /**
212  * g_atexit:
213  * @func: the function to call on normal program termination.
214  * 
215  * Specifies a function to be called at normal program termination.
216  */
217 void
218 g_atexit (GVoidFunc func)
219 {
220   gint result;
221   const gchar *error = NULL;
222
223   /* keep this in sync with glib.h */
224
225 #ifdef  G_NATIVE_ATEXIT
226   result = ATEXIT (func);
227   if (result)
228     error = g_strerror (errno);
229 #elif defined (HAVE_ATEXIT)
230 #  ifdef NeXT /* @#%@! NeXTStep */
231   result = !atexit ((void (*)(void)) func);
232   if (result)
233     error = g_strerror (errno);
234 #  else
235   result = atexit ((void (*)(void)) func);
236   if (result)
237     error = g_strerror (errno);
238 #  endif /* NeXT */
239 #elif defined (HAVE_ON_EXIT)
240   result = on_exit ((void (*)(int, void *)) func, NULL);
241   if (result)
242     error = g_strerror (errno);
243 #else
244   result = 0;
245   error = "no implementation";
246 #endif /* G_NATIVE_ATEXIT */
247
248   if (error)
249     g_error ("Could not register atexit() function: %s", error);
250 }
251
252 /* Based on execvp() from GNU Libc.
253  * Some of this code is cut-and-pasted into gspawn.c
254  */
255
256 static gchar*
257 my_strchrnul (const gchar *str, 
258               gchar        c)
259 {
260   gchar *p = (gchar*)str;
261   while (*p && (*p != c))
262     ++p;
263
264   return p;
265 }
266
267 #ifdef G_OS_WIN32
268
269 static gchar *inner_find_program_in_path (const gchar *program);
270
271 gchar*
272 g_find_program_in_path (const gchar *program)
273 {
274   const gchar *last_dot = strrchr (program, '.');
275
276   if (last_dot == NULL ||
277       strchr (last_dot, '\\') != NULL ||
278       strchr (last_dot, '/') != NULL)
279     {
280       const gint program_length = strlen (program);
281       gchar *pathext = g_build_path (";",
282                                      ".exe;.cmd;.bat;.com",
283                                      g_getenv ("PATHEXT"),
284                                      NULL);
285       gchar *p;
286       gchar *decorated_program;
287       gchar *retval;
288
289       p = pathext;
290       do
291         {
292           gchar *q = my_strchrnul (p, ';');
293
294           decorated_program = g_malloc (program_length + (q-p) + 1);
295           memcpy (decorated_program, program, program_length);
296           memcpy (decorated_program+program_length, p, q-p);
297           decorated_program [program_length + (q-p)] = '\0';
298           
299           retval = inner_find_program_in_path (decorated_program);
300           g_free (decorated_program);
301
302           if (retval != NULL)
303             {
304               g_free (pathext);
305               return retval;
306             }
307           p = q;
308         } while (*p++ != '\0');
309       g_free (pathext);
310       return NULL;
311     }
312   else
313     return inner_find_program_in_path (program);
314 }
315
316 #endif
317
318 /**
319  * g_find_program_in_path:
320  * @program: a program name in the GLib file name encoding
321  * 
322  * Locates the first executable named @program in the user's path, in the
323  * same way that execvp() would locate it. Returns an allocated string
324  * with the absolute path name, or %NULL if the program is not found in
325  * the path. If @program is already an absolute path, returns a copy of
326  * @program if @program exists and is executable, and %NULL otherwise.
327  *  
328  * On Windows, if @program does not have a file type suffix, tries
329  * with the suffixes .exe, .cmd, .bat and .com, and the suffixes in
330  * the <envar>PATHEXT</envar> environment variable. 
331  * 
332  * On Windows, it looks for the file in the same way as CreateProcess() 
333  * would. This means first in the directory where the executing
334  * program was loaded from, then in the current directory, then in the
335  * Windows 32-bit system directory, then in the Windows directory, and
336  * finally in the directories in the <envar>PATH</envar> environment 
337  * variable. If the program is found, the return value contains the 
338  * full name including the type suffix.
339  *
340  * Return value: absolute path, or %NULL
341  **/
342 #ifdef G_OS_WIN32
343 static gchar *
344 inner_find_program_in_path (const gchar *program)
345 #else
346 gchar*
347 g_find_program_in_path (const gchar *program)
348 #endif
349 {
350   const gchar *path, *p;
351   gchar *name, *freeme;
352 #ifdef G_OS_WIN32
353   const gchar *path_copy;
354   gchar *filename = NULL, *appdir = NULL;
355   gchar *sysdir = NULL, *windir = NULL;
356 #endif
357   size_t len;
358   size_t pathlen;
359
360   g_return_val_if_fail (program != NULL, NULL);
361
362   /* If it is an absolute path, or a relative path including subdirectories,
363    * don't look in PATH.
364    */
365   if (g_path_is_absolute (program)
366       || strchr (program, G_DIR_SEPARATOR) != NULL
367 #ifdef G_OS_WIN32
368       || strchr (program, '/') != NULL
369 #endif
370       )
371     {
372       if (g_file_test (program, G_FILE_TEST_IS_EXECUTABLE) &&
373           !g_file_test (program, G_FILE_TEST_IS_DIR))
374         return g_strdup (program);
375       else
376         return NULL;
377     }
378   
379   path = g_getenv ("PATH");
380 #if defined(G_OS_UNIX) || defined(G_OS_BEOS)
381   if (path == NULL)
382     {
383       /* There is no `PATH' in the environment.  The default
384        * search path in GNU libc is the current directory followed by
385        * the path `confstr' returns for `_CS_PATH'.
386        */
387       
388       /* In GLib we put . last, for security, and don't use the
389        * unportable confstr(); UNIX98 does not actually specify
390        * what to search if PATH is unset. POSIX may, dunno.
391        */
392       
393       path = "/bin:/usr/bin:.";
394     }
395 #else
396   if (G_WIN32_HAVE_WIDECHAR_API ())
397     {
398       int n;
399       wchar_t wfilename[MAXPATHLEN], wsysdir[MAXPATHLEN],
400         wwindir[MAXPATHLEN];
401       
402       n = GetModuleFileNameW (NULL, wfilename, MAXPATHLEN);
403       if (n > 0 && n < MAXPATHLEN)
404         filename = g_utf16_to_utf8 (wfilename, -1, NULL, NULL, NULL);
405       
406       n = GetSystemDirectoryW (wsysdir, MAXPATHLEN);
407       if (n > 0 && n < MAXPATHLEN)
408         sysdir = g_utf16_to_utf8 (wsysdir, -1, NULL, NULL, NULL);
409       
410       n = GetWindowsDirectoryW (wwindir, MAXPATHLEN);
411       if (n > 0 && n < MAXPATHLEN)
412         windir = g_utf16_to_utf8 (wwindir, -1, NULL, NULL, NULL);
413     }
414   else
415     {
416       int n;
417       gchar cpfilename[MAXPATHLEN], cpsysdir[MAXPATHLEN],
418         cpwindir[MAXPATHLEN];
419       
420       n = GetModuleFileNameA (NULL, cpfilename, MAXPATHLEN);
421       if (n > 0 && n < MAXPATHLEN)
422         filename = g_locale_to_utf8 (cpfilename, -1, NULL, NULL, NULL);
423       
424       n = GetSystemDirectoryA (cpsysdir, MAXPATHLEN);
425       if (n > 0 && n < MAXPATHLEN)
426         sysdir = g_locale_to_utf8 (cpsysdir, -1, NULL, NULL, NULL);
427       
428       n = GetWindowsDirectoryA (cpwindir, MAXPATHLEN);
429       if (n > 0 && n < MAXPATHLEN)
430         windir = g_locale_to_utf8 (cpwindir, -1, NULL, NULL, NULL);
431     }
432   
433   if (filename)
434     {
435       appdir = g_path_get_dirname (filename);
436       g_free (filename);
437     }
438   
439   path = g_strdup (path);
440
441   if (windir)
442     {
443       const gchar *tem = path;
444       path = g_strconcat (windir, ";", path, NULL);
445       g_free ((gchar *) tem);
446       g_free (windir);
447     }
448   
449   if (sysdir)
450     {
451       const gchar *tem = path;
452       path = g_strconcat (sysdir, ";", path, NULL);
453       g_free ((gchar *) tem);
454       g_free (sysdir);
455     }
456   
457   {
458     const gchar *tem = path;
459     path = g_strconcat (".;", path, NULL);
460     g_free ((gchar *) tem);
461   }
462   
463   if (appdir)
464     {
465       const gchar *tem = path;
466       path = g_strconcat (appdir, ";", path, NULL);
467       g_free ((gchar *) tem);
468       g_free (appdir);
469     }
470
471   path_copy = path;
472 #endif
473   
474   len = strlen (program) + 1;
475   pathlen = strlen (path);
476   freeme = name = g_malloc (pathlen + len + 1);
477   
478   /* Copy the file name at the top, including '\0'  */
479   memcpy (name + pathlen + 1, program, len);
480   name = name + pathlen;
481   /* And add the slash before the filename  */
482   *name = G_DIR_SEPARATOR;
483   
484   p = path;
485   do
486     {
487       char *startp;
488
489       path = p;
490       p = my_strchrnul (path, G_SEARCHPATH_SEPARATOR);
491
492       if (p == path)
493         /* Two adjacent colons, or a colon at the beginning or the end
494          * of `PATH' means to search the current directory.
495          */
496         startp = name + 1;
497       else
498         startp = memcpy (name - (p - path), path, p - path);
499
500       if (g_file_test (startp, G_FILE_TEST_IS_EXECUTABLE) &&
501           !g_file_test (startp, G_FILE_TEST_IS_DIR))
502         {
503           gchar *ret;
504           ret = g_strdup (startp);
505           g_free (freeme);
506 #ifdef G_OS_WIN32
507           g_free ((gchar *) path_copy);
508 #endif
509           return ret;
510         }
511     }
512   while (*p++ != '\0');
513   
514   g_free (freeme);
515 #ifdef G_OS_WIN32
516   g_free ((gchar *) path_copy);
517 #endif
518
519   return NULL;
520 }
521
522 /**
523  * g_parse_debug_string:
524  * @string: a list of debug options separated by ':' or "all" 
525  *     to set all flags.
526  * @keys: pointer to an array of #GDebugKey which associate 
527  *     strings with bit flags.
528  * @nkeys: the number of #GDebugKey<!-- -->s in the array.
529  *
530  * Parses a string containing debugging options separated 
531  * by ':' into a %guint containing bit flags. This is used 
532  * within GDK and GTK+ to parse the debug options passed on the
533  * command line or through environment variables.
534  *
535  * Returns: the combined set of bit flags.
536  */
537 guint        
538 g_parse_debug_string  (const gchar     *string, 
539                        const GDebugKey *keys, 
540                        guint            nkeys)
541 {
542   guint i;
543   guint result = 0;
544   
545   g_return_val_if_fail (string != NULL, 0);
546   
547   if (!g_ascii_strcasecmp (string, "all"))
548     {
549       for (i=0; i<nkeys; i++)
550         result |= keys[i].value;
551     }
552   else
553     {
554       const gchar *p = string;
555       const gchar *q;
556       gboolean done = FALSE;
557       
558       while (*p && !done)
559         {
560           q = strchr (p, ':');
561           if (!q)
562             {
563               q = p + strlen(p);
564               done = TRUE;
565             }
566           
567           for (i=0; i<nkeys; i++)
568             if (g_ascii_strncasecmp (keys[i].key, p, q - p) == 0 &&
569                 keys[i].key[q - p] == '\0')
570               result |= keys[i].value;
571           
572           p = q + 1;
573         }
574     }
575   
576   return result;
577 }
578
579 /**
580  * g_basename:
581  * @file_name: the name of the file.
582  * 
583  * Gets the name of the file without any leading directory components.  
584  * It returns a pointer into the given file name string.
585  * 
586  * Return value: the name of the file without any leading directory components.
587  *
588  * Deprecated: Use g_path_get_basename() instead, but notice that
589  * g_path_get_basename() allocates new memory for the returned string, unlike
590  * this function which returns a pointer into the argument.
591  **/
592 G_CONST_RETURN gchar*
593 g_basename (const gchar    *file_name)
594 {
595   register gchar *base;
596   
597   g_return_val_if_fail (file_name != NULL, NULL);
598   
599   base = strrchr (file_name, G_DIR_SEPARATOR);
600
601 #ifdef G_OS_WIN32
602   {
603     gchar *q = strrchr (file_name, '/');
604     if (base == NULL || (q != NULL && q > base))
605         base = q;
606   }
607 #endif
608
609   if (base)
610     return base + 1;
611
612 #ifdef G_OS_WIN32
613   if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
614     return (gchar*) file_name + 2;
615 #endif /* G_OS_WIN32 */
616   
617   return (gchar*) file_name;
618 }
619
620 /**
621  * g_path_get_basename:
622  * @file_name: the name of the file.
623  *
624  * Gets the last component of the filename. If @file_name ends with a 
625  * directory separator it gets the component before the last slash. If 
626  * @file_name consists only of directory separators (and on Windows, 
627  * possibly a drive letter), a single separator is returned. If
628  * @file_name is empty, it gets ".".
629  *
630  * Return value: a newly allocated string containing the last component of 
631  *   the filename.
632  */
633 gchar*
634 g_path_get_basename (const gchar   *file_name)
635 {
636   register gssize base;             
637   register gssize last_nonslash;    
638   gsize len;    
639   gchar *retval;
640  
641   g_return_val_if_fail (file_name != NULL, NULL);
642
643   if (file_name[0] == '\0')
644     /* empty string */
645     return g_strdup (".");
646   
647   last_nonslash = strlen (file_name) - 1;
648
649   while (last_nonslash >= 0 && G_IS_DIR_SEPARATOR (file_name [last_nonslash]))
650     last_nonslash--;
651
652   if (last_nonslash == -1)
653     /* string only containing slashes */
654     return g_strdup (G_DIR_SEPARATOR_S);
655
656 #ifdef G_OS_WIN32
657   if (last_nonslash == 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
658     /* string only containing slashes and a drive */
659     return g_strdup (G_DIR_SEPARATOR_S);
660 #endif /* G_OS_WIN32 */
661
662   base = last_nonslash;
663
664   while (base >=0 && !G_IS_DIR_SEPARATOR (file_name [base]))
665     base--;
666
667 #ifdef G_OS_WIN32
668   if (base == -1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
669     base = 1;
670 #endif /* G_OS_WIN32 */
671
672   len = last_nonslash - base;
673   retval = g_malloc (len + 1);
674   memcpy (retval, file_name + base + 1, len);
675   retval [len] = '\0';
676   return retval;
677 }
678
679 /**
680  * g_path_is_absolute:
681  * @file_name: a file name.
682  *
683  * Returns %TRUE if the given @file_name is an absolute file name,
684  * i.e. it contains a full path from the root directory such as "/usr/local"
685  * on UNIX or "C:\windows" on Windows systems.
686  *
687  * Returns: %TRUE if @file_name is an absolute path. 
688  */
689 gboolean
690 g_path_is_absolute (const gchar *file_name)
691 {
692   g_return_val_if_fail (file_name != NULL, FALSE);
693   
694   if (G_IS_DIR_SEPARATOR (file_name[0]))
695     return TRUE;
696
697 #ifdef G_OS_WIN32
698   /* Recognize drive letter on native Windows */
699   if (g_ascii_isalpha (file_name[0]) && 
700       file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
701     return TRUE;
702 #endif /* G_OS_WIN32 */
703
704   return FALSE;
705 }
706
707 /**
708  * g_path_skip_root:
709  * @file_name: a file name.
710  *
711  * Returns a pointer into @file_name after the root component, i.e. after
712  * the "/" in UNIX or "C:\" under Windows. If @file_name is not an absolute
713  * path it returns %NULL.
714  *
715  * Returns: a pointer into @file_name after the root component.
716  */
717 G_CONST_RETURN gchar*
718 g_path_skip_root (const gchar *file_name)
719 {
720   g_return_val_if_fail (file_name != NULL, NULL);
721   
722 #ifdef G_PLATFORM_WIN32
723   /* Skip \\server\share or //server/share */
724   if (G_IS_DIR_SEPARATOR (file_name[0]) &&
725       G_IS_DIR_SEPARATOR (file_name[1]) &&
726       file_name[2] &&
727       !G_IS_DIR_SEPARATOR (file_name[2]))
728     {
729       gchar *p;
730
731       p = strchr (file_name + 2, G_DIR_SEPARATOR);
732 #ifdef G_OS_WIN32
733       {
734         gchar *q = strchr (file_name + 2, '/');
735         if (p == NULL || (q != NULL && q < p))
736           p = q;
737       }
738 #endif
739       if (p &&
740           p > file_name + 2 &&
741           p[1])
742         {
743           file_name = p + 1;
744
745           while (file_name[0] && !G_IS_DIR_SEPARATOR (file_name[0]))
746             file_name++;
747
748           /* Possibly skip a backslash after the share name */
749           if (G_IS_DIR_SEPARATOR (file_name[0]))
750             file_name++;
751
752           return (gchar *)file_name;
753         }
754     }
755 #endif
756   
757   /* Skip initial slashes */
758   if (G_IS_DIR_SEPARATOR (file_name[0]))
759     {
760       while (G_IS_DIR_SEPARATOR (file_name[0]))
761         file_name++;
762       return (gchar *)file_name;
763     }
764
765 #ifdef G_OS_WIN32
766   /* Skip X:\ */
767   if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
768     return (gchar *)file_name + 3;
769 #endif
770
771   return NULL;
772 }
773
774 /**
775  * g_path_get_dirname:
776  * @file_name: the name of the file.
777  *
778  * Gets the directory components of a file name.  If the file name has no
779  * directory components "." is returned.  The returned string should be
780  * freed when no longer needed.
781  * 
782  * Returns: the directory components of the file.
783  */
784 gchar*
785 g_path_get_dirname (const gchar    *file_name)
786 {
787   register gchar *base;
788   register gsize len;    
789   
790   g_return_val_if_fail (file_name != NULL, NULL);
791   
792   base = strrchr (file_name, G_DIR_SEPARATOR);
793 #ifdef G_OS_WIN32
794   {
795     gchar *q = strrchr (file_name, '/');
796     if (base == NULL || (q != NULL && q > base))
797         base = q;
798   }
799 #endif
800   if (!base)
801     {
802 #ifdef G_OS_WIN32
803       if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
804         {
805           gchar drive_colon_dot[4];
806
807           drive_colon_dot[0] = file_name[0];
808           drive_colon_dot[1] = ':';
809           drive_colon_dot[2] = '.';
810           drive_colon_dot[3] = '\0';
811
812           return g_strdup (drive_colon_dot);
813         }
814 #endif
815     return g_strdup (".");
816     }
817
818   while (base > file_name && G_IS_DIR_SEPARATOR (*base))
819     base--;
820
821 #ifdef G_OS_WIN32
822   /* base points to the char before the last slash.
823    *
824    * In case file_name is the root of a drive (X:\) or a child of the
825    * root of a drive (X:\foo), include the slash.
826    *
827    * In case file_name is the root share of an UNC path
828    * (\\server\share), add a slash, returning \\server\share\ .
829    *
830    * In case file_name is a direct child of a share in an UNC path
831    * (\\server\share\foo), include the slash after the share name,
832    * returning \\server\share\ .
833    */
834   if (base == file_name + 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
835     base++;
836   else if (G_IS_DIR_SEPARATOR (file_name[0]) &&
837            G_IS_DIR_SEPARATOR (file_name[1]) &&
838            file_name[2] &&
839            !G_IS_DIR_SEPARATOR (file_name[2]) &&
840            base >= file_name + 2)
841     {
842       const gchar *p = file_name + 2;
843       while (*p && !G_IS_DIR_SEPARATOR (*p))
844         p++;
845       if (p == base + 1)
846         {
847           len = (guint) strlen (file_name) + 1;
848           base = g_new (gchar, len + 1);
849           strcpy (base, file_name);
850           base[len-1] = G_DIR_SEPARATOR;
851           base[len] = 0;
852           return base;
853         }
854       if (G_IS_DIR_SEPARATOR (*p))
855         {
856           p++;
857           while (*p && !G_IS_DIR_SEPARATOR (*p))
858             p++;
859           if (p == base + 1)
860             base++;
861         }
862     }
863 #endif
864
865   len = (guint) 1 + base - file_name;
866   
867   base = g_new (gchar, len + 1);
868   g_memmove (base, file_name, len);
869   base[len] = 0;
870   
871   return base;
872 }
873
874 /**
875  * g_get_current_dir:
876  *
877  * Gets the current directory.
878  * The returned string should be freed when no longer needed. The encoding 
879  * of the returned string is system defined. On Windows, it is always UTF-8.
880  * 
881  * Returns: the current directory.
882  */
883 gchar*
884 g_get_current_dir (void)
885 {
886 #ifdef G_OS_WIN32
887
888   gchar *dir = NULL;
889
890   if (G_WIN32_HAVE_WIDECHAR_API ())
891     {
892       wchar_t dummy[2], *wdir;
893       int len;
894
895       len = GetCurrentDirectoryW (2, dummy);
896       wdir = g_new (wchar_t, len);
897
898       if (GetCurrentDirectoryW (len, wdir) == len - 1)
899         dir = g_utf16_to_utf8 (wdir, -1, NULL, NULL, NULL);
900
901       g_free (wdir);
902     }
903   else
904     {
905       gchar dummy[2], *cpdir;
906       int len;
907
908       len = GetCurrentDirectoryA (2, dummy);
909       cpdir = g_new (gchar, len);
910
911       if (GetCurrentDirectoryA (len, cpdir) == len - 1)
912         dir = g_locale_to_utf8 (cpdir, -1, NULL, NULL, NULL);
913
914       g_free (cpdir);
915     }
916
917   if (dir == NULL)
918     dir = g_strdup ("\\");
919
920   return dir;
921
922 #else
923
924   gchar *buffer = NULL;
925   gchar *dir = NULL;
926   static gulong max_len = 0;
927
928   if (max_len == 0) 
929     max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
930   
931   /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
932    * and, if that wasn't bad enough, hangs in doing so.
933    */
934 #if     (defined (sun) && !defined (__SVR4)) || !defined(HAVE_GETCWD)
935   buffer = g_new (gchar, max_len + 1);
936   *buffer = 0;
937   dir = getwd (buffer);
938 #else   /* !sun || !HAVE_GETCWD */
939   while (max_len < G_MAXULONG / 2)
940     {
941       buffer = g_new (gchar, max_len + 1);
942       *buffer = 0;
943       dir = getcwd (buffer, max_len);
944
945       if (dir || errno != ERANGE)
946         break;
947
948       g_free (buffer);
949       max_len *= 2;
950     }
951 #endif  /* !sun || !HAVE_GETCWD */
952   
953   if (!dir || !*buffer)
954     {
955       /* hm, should we g_error() out here?
956        * this can happen if e.g. "./" has mode \0000
957        */
958       buffer[0] = G_DIR_SEPARATOR;
959       buffer[1] = 0;
960     }
961
962   dir = g_strdup (buffer);
963   g_free (buffer);
964   
965   return dir;
966 #endif /* !Win32 */
967 }
968
969 /**
970  * g_getenv:
971  * @variable: the environment variable to get, in the GLib file name encoding.
972  * 
973  * Returns the value of an environment variable. The name and value
974  * are in the GLib file name encoding. On UNIX, this means the actual
975  * bytes which might or might not be in some consistent character set
976  * and encoding. On Windows, it is in UTF-8. On Windows, in case the
977  * environment variable's value contains references to other
978  * environment variables, they are expanded.
979  * 
980  * Return value: the value of the environment variable, or %NULL if
981  * the environment variable is not found. The returned string may be
982  * overwritten by the next call to g_getenv(), g_setenv() or
983  * g_unsetenv().
984  **/
985 G_CONST_RETURN gchar*
986 g_getenv (const gchar *variable)
987 {
988 #ifndef G_OS_WIN32
989
990   g_return_val_if_fail (variable != NULL, NULL);
991
992   return getenv (variable);
993
994 #else /* G_OS_WIN32 */
995
996   GQuark quark;
997   gchar *value;
998
999   g_return_val_if_fail (variable != NULL, NULL);
1000   g_return_val_if_fail (g_utf8_validate (variable, -1, NULL), NULL);
1001
1002   /* On Windows NT, it is relatively typical that environment
1003    * variables contain references to other environment variables. If
1004    * so, use ExpandEnvironmentStrings(). (In an ideal world, such
1005    * environment variables would be stored in the Registry as
1006    * REG_EXPAND_SZ type values, and would then get automatically
1007    * expanded before a program sees them. But there is broken software
1008    * that stores environment variables as REG_SZ values even if they
1009    * contain references to other environment variables.)
1010    */
1011
1012   if (G_WIN32_HAVE_WIDECHAR_API ())
1013     {
1014       wchar_t dummy[2], *wname, *wvalue;
1015       int len;
1016       
1017       wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL);
1018
1019       len = GetEnvironmentVariableW (wname, dummy, 2);
1020
1021       if (len == 0)
1022         {
1023           g_free (wname);
1024           return NULL;
1025         }
1026       else if (len == 1)
1027         len = 2;
1028
1029       wvalue = g_new (wchar_t, len);
1030
1031       if (GetEnvironmentVariableW (wname, wvalue, len) != len - 1)
1032         {
1033           g_free (wname);
1034           g_free (wvalue);
1035           return NULL;
1036         }
1037
1038       if (wcschr (wvalue, L'%') != NULL)
1039         {
1040           wchar_t *tem = wvalue;
1041
1042           len = ExpandEnvironmentStringsW (wvalue, dummy, 2);
1043
1044           if (len > 0)
1045             {
1046               wvalue = g_new (wchar_t, len);
1047
1048               if (ExpandEnvironmentStringsW (tem, wvalue, len) != len)
1049                 {
1050                   g_free (wvalue);
1051                   wvalue = tem;
1052                 }
1053               else
1054                 g_free (tem);
1055             }
1056         }
1057
1058       value = g_utf16_to_utf8 (wvalue, -1, NULL, NULL, NULL);
1059
1060       g_free (wname);
1061       g_free (wvalue);
1062     }
1063   else
1064     {
1065       gchar dummy[3], *cpname, *cpvalue;
1066       int len;
1067       
1068       cpname = g_locale_from_utf8 (variable, -1, NULL, NULL, NULL);
1069
1070       g_return_val_if_fail (cpname != NULL, NULL);
1071
1072       len = GetEnvironmentVariableA (cpname, dummy, 2);
1073
1074       if (len == 0)
1075         {
1076           g_free (cpname);
1077           return NULL;
1078         }
1079       else if (len == 1)
1080         len = 2;
1081
1082       cpvalue = g_new (gchar, len);
1083
1084       if (GetEnvironmentVariableA (cpname, cpvalue, len) != len - 1)
1085         {
1086           g_free (cpname);
1087           g_free (cpvalue);
1088           return NULL;
1089         }
1090
1091       if (strchr (cpvalue, '%') != NULL)
1092         {
1093           gchar *tem = cpvalue;
1094
1095           len = ExpandEnvironmentStringsA (cpvalue, dummy, 3);
1096
1097           if (len > 0)
1098             {
1099               cpvalue = g_new (gchar, len);
1100
1101               if (ExpandEnvironmentStringsA (tem, cpvalue, len) != len)
1102                 {
1103                   g_free (cpvalue);
1104                   cpvalue = tem;
1105                 }
1106               else
1107                 g_free (tem);
1108             }
1109         }
1110
1111       value = g_locale_to_utf8 (cpvalue, -1, NULL, NULL, NULL);
1112
1113       g_free (cpname);
1114       g_free (cpvalue);
1115     }
1116
1117   quark = g_quark_from_string (value);
1118   g_free (value);
1119   
1120   return g_quark_to_string (quark);
1121
1122 #endif /* G_OS_WIN32 */
1123 }
1124
1125 /**
1126  * g_setenv:
1127  * @variable: the environment variable to set, must not contain '='.
1128  * @value: the value for to set the variable to.
1129  * @overwrite: whether to change the variable if it already exists.
1130  *
1131  * Sets an environment variable. Both the variable's name and value
1132  * should be in the GLib file name encoding. On UNIX, this means that
1133  * they can be any sequence of bytes. On Windows, they should be in
1134  * UTF-8.
1135  *
1136  * Note that on some systems, when variables are overwritten, the memory 
1137  * used for the previous variables and its value isn't reclaimed.
1138  *
1139  * Returns: %FALSE if the environment variable couldn't be set.
1140  *
1141  * Since: 2.4
1142  */
1143 gboolean
1144 g_setenv (const gchar *variable, 
1145           const gchar *value, 
1146           gboolean     overwrite)
1147 {
1148 #ifndef G_OS_WIN32
1149
1150   gint result;
1151 #ifndef HAVE_SETENV
1152   gchar *string;
1153 #endif
1154
1155   g_return_val_if_fail (variable != NULL, FALSE);
1156   g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE);
1157
1158 #ifdef HAVE_SETENV
1159   result = setenv (variable, value, overwrite);
1160 #else
1161   if (!overwrite && getenv (variable) != NULL)
1162     return TRUE;
1163   
1164   /* This results in a leak when you overwrite existing
1165    * settings. It would be fairly easy to fix this by keeping
1166    * our own parallel array or hash table.
1167    */
1168   string = g_strconcat (variable, "=", value, NULL);
1169   result = putenv (string);
1170 #endif
1171   return result == 0;
1172
1173 #else /* G_OS_WIN32 */
1174
1175   gboolean retval;
1176
1177   g_return_val_if_fail (variable != NULL, FALSE);
1178   g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE);
1179   g_return_val_if_fail (g_utf8_validate (variable, -1, NULL), FALSE);
1180   g_return_val_if_fail (g_utf8_validate (value, -1, NULL), FALSE);
1181
1182   if (!overwrite && g_getenv (variable) != NULL)
1183     return TRUE;
1184
1185   /* We want to (if possible) set both the environment variable copy
1186    * kept by the C runtime and the one kept by the system.
1187    *
1188    * We can't use only the C runtime's putenv or _wputenv() as that
1189    * won't work for arbitrary Unicode strings in a "non-Unicode" app
1190    * (with main() and not wmain()). In a "main()" app the C runtime
1191    * initializes the C runtime's environment table by converting the
1192    * real (wide char) environment variables to system codepage, thus
1193    * breaking those that aren't representable in the system codepage.
1194    *
1195    * As the C runtime's putenv() will also set the system copy, we do
1196    * the putenv() first, then call SetEnvironmentValueW ourselves.
1197    */
1198
1199   if (G_WIN32_HAVE_WIDECHAR_API ())
1200     {
1201       wchar_t *wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL);
1202       wchar_t *wvalue = g_utf8_to_utf16 (value, -1, NULL, NULL, NULL);
1203       gchar *tem = g_strconcat (variable, "=", value, NULL);
1204       wchar_t *wassignment = g_utf8_to_utf16 (tem, -1, NULL, NULL, NULL);
1205       
1206       g_free (tem);
1207       _wputenv (wassignment);
1208       g_free (wassignment);
1209
1210       retval = (SetEnvironmentVariableW (wname, wvalue) != 0);
1211
1212       g_free (wname);
1213       g_free (wvalue);
1214     }
1215   else
1216     {
1217       /* In the non-Unicode case (Win9x), just putenv() is good
1218        * enough.
1219        */
1220       gchar *tem = g_strconcat (variable, "=", value, NULL);
1221       gchar *cpassignment = g_locale_from_utf8 (tem, -1, NULL, NULL, NULL);
1222
1223       g_free (tem);
1224       
1225       retval = (putenv (cpassignment) == 0);
1226
1227       g_free (cpassignment);
1228     }
1229
1230   return retval;
1231
1232 #endif /* G_OS_WIN32 */
1233 }
1234
1235 #ifdef HAVE__NSGETENVIRON
1236 #define environ (*_NSGetEnviron())
1237 #elif !defined(G_OS_WIN32)
1238
1239 /* According to the Single Unix Specification, environ is not in 
1240  * any system header, although unistd.h often declares it.
1241  */
1242 extern char **environ;
1243 #endif
1244
1245 /**
1246  * g_unsetenv:
1247  * @variable: the environment variable to remove, must not contain '='.
1248  * 
1249  * Removes an environment variable from the environment.
1250  *
1251  * Note that on some systems, when variables are overwritten, the memory 
1252  * used for the previous variables and its value isn't reclaimed.
1253  * Furthermore, this function can't be guaranteed to operate in a 
1254  * threadsafe way.
1255  *
1256  * Since: 2.4 
1257  **/
1258 void
1259 g_unsetenv (const gchar *variable)
1260 {
1261 #ifndef G_OS_WIN32
1262
1263 #ifdef HAVE_UNSETENV
1264   g_return_if_fail (variable != NULL);
1265   g_return_if_fail (strchr (variable, '=') == NULL);
1266
1267   unsetenv (variable);
1268 #else /* !HAVE_UNSETENV */
1269   int len;
1270   gchar **e, **f;
1271
1272   g_return_if_fail (variable != NULL);
1273   g_return_if_fail (strchr (variable, '=') == NULL);
1274
1275   len = strlen (variable);
1276   
1277   /* Mess directly with the environ array.
1278    * This seems to be the only portable way to do this.
1279    *
1280    * Note that we remove *all* environment entries for
1281    * the variable name, not just the first.
1282    */
1283   e = f = environ;
1284   while (*e != NULL) 
1285     {
1286       if (strncmp (*e, variable, len) != 0 || (*e)[len] != '=') 
1287         {
1288           *f = *e;
1289           f++;
1290         }
1291       e++;
1292     }
1293   *f = NULL;
1294 #endif /* !HAVE_UNSETENV */
1295
1296 #else  /* G_OS_WIN32 */
1297
1298   g_return_if_fail (variable != NULL);
1299   g_return_if_fail (strchr (variable, '=') == NULL);
1300   g_return_if_fail (g_utf8_validate (variable, -1, NULL));
1301
1302   if (G_WIN32_HAVE_WIDECHAR_API ())
1303     {
1304       wchar_t *wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL);
1305       gchar *tem = g_strconcat (variable, "=", NULL);
1306       wchar_t *wassignment = g_utf8_to_utf16 (tem, -1, NULL, NULL, NULL);
1307       
1308       g_free (tem);
1309       _wputenv (wassignment);
1310       g_free (wassignment);
1311
1312       SetEnvironmentVariableW (wname, NULL);
1313
1314       g_free (wname);
1315     }
1316   else
1317     {
1318       /* In the non-Unicode case (Win9x), just putenv() is good
1319        * enough.
1320        */
1321       gchar *tem = g_strconcat (variable, "=", NULL);
1322       gchar *cpassignment = g_locale_from_utf8 (tem, -1, NULL, NULL, NULL);
1323
1324       g_free (tem);
1325       
1326       putenv (cpassignment);
1327
1328       g_free (cpassignment);
1329     }
1330
1331 #endif /* G_OS_WIN32 */
1332 }
1333
1334 /**
1335  * g_listenv:
1336  *
1337  * Gets the names of all variables set in the environment.
1338  * 
1339  * Returns: a %NULL-terminated list of strings which must be freed
1340  * with g_strfreev().
1341  *
1342  * Since: 2.8
1343  */
1344 gchar **
1345 g_listenv (void)
1346 {
1347   gchar **result, *eq;
1348   gint len, i, j;
1349
1350   len = g_strv_length (environ);
1351   result = g_new0 (gchar *, len + 1);
1352   
1353   j = 0;
1354   for (i = 0; i < len; i++)
1355     {
1356       eq = strchr (environ[i], '=');
1357       if (eq)
1358         result[j++] = g_strndup (environ[i], eq - environ[i]);
1359     }
1360
1361   result[j] = NULL;
1362
1363   return result;
1364 }
1365
1366 G_LOCK_DEFINE_STATIC (g_utils_global);
1367
1368 static  gchar   *g_tmp_dir = NULL;
1369 static  gchar   *g_user_name = NULL;
1370 static  gchar   *g_real_name = NULL;
1371 static  gchar   *g_home_dir = NULL;
1372 static  gchar   *g_host_name = NULL;
1373
1374 #ifdef G_OS_WIN32
1375 /* System codepage versions of the above, kept at file level so that they,
1376  * too, are produced only once.
1377  */
1378 static  gchar   *g_tmp_dir_cp = NULL;
1379 static  gchar   *g_user_name_cp = NULL;
1380 static  gchar   *g_real_name_cp = NULL;
1381 static  gchar   *g_home_dir_cp = NULL;
1382 #endif
1383
1384 static  gchar   *g_user_data_dir = NULL;
1385 static  gchar  **g_system_data_dirs = NULL;
1386 static  gchar   *g_user_cache_dir = NULL;
1387 static  gchar   *g_user_config_dir = NULL;
1388 static  gchar  **g_system_config_dirs = NULL;
1389
1390 #ifdef G_OS_WIN32
1391
1392 static gchar *
1393 get_special_folder (int csidl)
1394 {
1395   union {
1396     char c[MAX_PATH+1];
1397     wchar_t wc[MAX_PATH+1];
1398   } path;
1399   HRESULT hr;
1400   LPITEMIDLIST pidl = NULL;
1401   BOOL b;
1402   gchar *retval = NULL;
1403
1404   hr = SHGetSpecialFolderLocation (NULL, csidl, &pidl);
1405   if (hr == S_OK)
1406     {
1407       if (G_WIN32_HAVE_WIDECHAR_API ())
1408         {
1409           b = SHGetPathFromIDListW (pidl, path.wc);
1410           if (b)
1411             retval = g_utf16_to_utf8 (path.wc, -1, NULL, NULL, NULL);
1412         }
1413       else
1414         {
1415           b = SHGetPathFromIDListA (pidl, path.c);
1416           if (b)
1417             retval = g_locale_to_utf8 (path.c, -1, NULL, NULL, NULL);
1418         }
1419       CoTaskMemFree (pidl);
1420     }
1421   return retval;
1422 }
1423
1424 static char *
1425 get_windows_directory_root (void)
1426 {
1427   char windowsdir[MAX_PATH];
1428
1429   if (GetWindowsDirectory (windowsdir, sizeof (windowsdir)))
1430     {
1431       /* Usually X:\Windows, but in terminal server environments
1432        * might be an UNC path, AFAIK.
1433        */
1434       char *p = (char *) g_path_skip_root (windowsdir);
1435       if (G_IS_DIR_SEPARATOR (p[-1]) && p[-2] != ':')
1436         p--;
1437       *p = '\0';
1438       return g_strdup (windowsdir);
1439     }
1440   else
1441     return g_strdup ("C:\\");
1442 }
1443
1444 #endif
1445
1446 /* HOLDS: g_utils_global_lock */
1447 static void
1448 g_get_any_init_do (void)
1449 {
1450   gchar hostname[100];
1451
1452   g_tmp_dir = g_strdup (g_getenv ("TMPDIR"));
1453   if (!g_tmp_dir)
1454     g_tmp_dir = g_strdup (g_getenv ("TMP"));
1455   if (!g_tmp_dir)
1456     g_tmp_dir = g_strdup (g_getenv ("TEMP"));
1457
1458 #ifdef G_OS_WIN32
1459   if (!g_tmp_dir)
1460     g_tmp_dir = get_windows_directory_root ();
1461 #else  
1462 #ifdef P_tmpdir
1463   if (!g_tmp_dir)
1464     {
1465       gsize k;    
1466       g_tmp_dir = g_strdup (P_tmpdir);
1467       k = strlen (g_tmp_dir);
1468       if (k > 1 && G_IS_DIR_SEPARATOR (g_tmp_dir[k - 1]))
1469         g_tmp_dir[k - 1] = '\0';
1470     }
1471 #endif
1472   
1473   if (!g_tmp_dir)
1474     {
1475       g_tmp_dir = g_strdup ("/tmp");
1476     }
1477 #endif  /* !G_OS_WIN32 */
1478   
1479 #ifdef G_OS_WIN32
1480   /* We check $HOME first for Win32, though it is a last resort for Unix
1481    * where we prefer the results of getpwuid().
1482    */
1483   g_home_dir = g_strdup (g_getenv ("HOME"));
1484
1485   /* Only believe HOME if it is an absolute path and exists */
1486   if (g_home_dir)
1487     {
1488       if (!(g_path_is_absolute (g_home_dir) &&
1489             g_file_test (g_home_dir, G_FILE_TEST_IS_DIR)))
1490         {
1491           g_free (g_home_dir);
1492           g_home_dir = NULL;
1493         }
1494     }
1495   
1496   /* In case HOME is Unix-style (it happens), convert it to
1497    * Windows style.
1498    */
1499   if (g_home_dir)
1500     {
1501       gchar *p;
1502       while ((p = strchr (g_home_dir, '/')) != NULL)
1503         *p = '\\';
1504     }
1505
1506   if (!g_home_dir)
1507     {
1508       /* USERPROFILE is probably the closest equivalent to $HOME? */
1509       if (g_getenv ("USERPROFILE") != NULL)
1510         g_home_dir = g_strdup (g_getenv ("USERPROFILE"));
1511     }
1512
1513   if (!g_home_dir)
1514     g_home_dir = get_special_folder (CSIDL_PROFILE);
1515   
1516   if (!g_home_dir)
1517     g_home_dir = get_windows_directory_root ();
1518 #endif /* G_OS_WIN32 */
1519   
1520 #ifdef HAVE_PWD_H
1521   {
1522     struct passwd *pw = NULL;
1523     gpointer buffer = NULL;
1524     gint error;
1525     
1526 #  if defined (HAVE_POSIX_GETPWUID_R) || defined (HAVE_NONPOSIX_GETPWUID_R)
1527     struct passwd pwd;
1528 #    ifdef _SC_GETPW_R_SIZE_MAX  
1529     /* This reurns the maximum length */
1530     glong bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
1531     
1532     if (bufsize < 0)
1533       bufsize = 64;
1534 #    else /* _SC_GETPW_R_SIZE_MAX */
1535     glong bufsize = 64;
1536 #    endif /* _SC_GETPW_R_SIZE_MAX */
1537     
1538     do
1539       {
1540         g_free (buffer);
1541         /* we allocate 6 extra bytes to work around a bug in 
1542          * Mac OS < 10.3. See #156446
1543          */
1544         buffer = g_malloc (bufsize + 6);
1545         errno = 0;
1546         
1547 #    ifdef HAVE_POSIX_GETPWUID_R
1548         error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
1549         error = error < 0 ? errno : error;
1550 #    else /* HAVE_NONPOSIX_GETPWUID_R */
1551    /* HPUX 11 falls into the HAVE_POSIX_GETPWUID_R case */
1552 #      if defined(_AIX) || defined(__hpux)
1553         error = getpwuid_r (getuid (), &pwd, buffer, bufsize);
1554         pw = error == 0 ? &pwd : NULL;
1555 #      else /* !_AIX */
1556         pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
1557         error = pw ? 0 : errno;
1558 #      endif /* !_AIX */            
1559 #    endif /* HAVE_NONPOSIX_GETPWUID_R */
1560         
1561         if (!pw)
1562           {
1563             /* we bail out prematurely if the user id can't be found
1564              * (should be pretty rare case actually), or if the buffer
1565              * should be sufficiently big and lookups are still not
1566              * successfull.
1567              */
1568             if (error == 0 || error == ENOENT)
1569               {
1570                 g_warning ("getpwuid_r(): failed due to unknown user id (%lu)",
1571                            (gulong) getuid ());
1572                 break;
1573               }
1574             if (bufsize > 32 * 1024)
1575               {
1576                 g_warning ("getpwuid_r(): failed due to: %s.",
1577                            g_strerror (error));
1578                 break;
1579               }
1580             
1581             bufsize *= 2;
1582           }
1583       }
1584     while (!pw);
1585 #  endif /* HAVE_POSIX_GETPWUID_R || HAVE_NONPOSIX_GETPWUID_R */
1586     
1587     if (!pw)
1588       {
1589         setpwent ();
1590         pw = getpwuid (getuid ());
1591         endpwent ();
1592       }
1593     if (pw)
1594       {
1595         g_user_name = g_strdup (pw->pw_name);
1596
1597         if (pw->pw_gecos && *pw->pw_gecos != '\0') 
1598           {
1599             gchar **gecos_fields;
1600             gchar **name_parts;
1601
1602             /* split the gecos field and substitute '&' */
1603             gecos_fields = g_strsplit (pw->pw_gecos, ",", 0);
1604             name_parts = g_strsplit (gecos_fields[0], "&", 0);
1605             pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]);
1606             g_real_name = g_strjoinv (pw->pw_name, name_parts);
1607             g_strfreev (gecos_fields);
1608             g_strfreev (name_parts);
1609           }
1610
1611         if (!g_home_dir)
1612           g_home_dir = g_strdup (pw->pw_dir);
1613       }
1614     g_free (buffer);
1615   }
1616   
1617 #else /* !HAVE_PWD_H */
1618   
1619 #ifdef G_OS_WIN32
1620   if (G_WIN32_HAVE_WIDECHAR_API ())
1621     {
1622       guint len = UNLEN+1;
1623       wchar_t buffer[UNLEN+1];
1624       
1625       if (GetUserNameW (buffer, (LPDWORD) &len))
1626         {
1627           g_user_name = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL);
1628           g_real_name = g_strdup (g_user_name);
1629         }
1630     }
1631   else
1632     {
1633       guint len = UNLEN+1;
1634       char buffer[UNLEN+1];
1635       
1636       if (GetUserNameA (buffer, (LPDWORD) &len))
1637         {
1638           g_user_name = g_locale_to_utf8 (buffer, -1, NULL, NULL, NULL);
1639           g_real_name = g_strdup (g_user_name);
1640         }
1641     }
1642 #endif /* G_OS_WIN32 */
1643
1644 #endif /* !HAVE_PWD_H */
1645
1646 #ifndef G_OS_WIN32
1647   if (!g_home_dir)
1648     g_home_dir = g_strdup (g_getenv ("HOME"));
1649 #endif
1650
1651 #ifdef __EMX__
1652   /* change '\\' in %HOME% to '/' */
1653   g_strdelimit (g_home_dir, "\\",'/');
1654 #endif
1655   if (!g_user_name)
1656     g_user_name = g_strdup ("somebody");
1657   if (!g_real_name)
1658     g_real_name = g_strdup ("Unknown");
1659
1660   {
1661 #ifndef G_OS_WIN32
1662     gboolean hostname_fail = (gethostname (hostname, sizeof (hostname)) == -1);
1663 #else
1664     DWORD size = sizeof (hostname);
1665     gboolean hostname_fail = (!GetComputerName (hostname, &size));
1666 #endif
1667     g_host_name = g_strdup (hostname_fail ? "localhost" : hostname);
1668   }
1669
1670 #ifdef G_OS_WIN32
1671   g_tmp_dir_cp = g_locale_from_utf8 (g_tmp_dir, -1, NULL, NULL, NULL);
1672   g_user_name_cp = g_locale_from_utf8 (g_user_name, -1, NULL, NULL, NULL);
1673   g_real_name_cp = g_locale_from_utf8 (g_real_name, -1, NULL, NULL, NULL);
1674
1675   if (!g_tmp_dir_cp)
1676     g_tmp_dir_cp = g_strdup ("\\");
1677   if (!g_user_name_cp)
1678     g_user_name_cp = g_strdup ("somebody");
1679   if (!g_real_name_cp)
1680     g_real_name_cp = g_strdup ("Unknown");
1681
1682   /* home_dir might be NULL, unlike tmp_dir, user_name and
1683    * real_name.
1684    */
1685   if (g_home_dir)
1686     g_home_dir_cp = g_locale_from_utf8 (g_home_dir, -1, NULL, NULL, NULL);
1687   else
1688     g_home_dir_cp = NULL;
1689 #endif /* G_OS_WIN32 */
1690 }
1691
1692 static inline void
1693 g_get_any_init (void)
1694 {
1695   if (!g_tmp_dir)
1696     g_get_any_init_do ();
1697 }
1698
1699 static inline void
1700 g_get_any_init_locked (void)
1701 {
1702   G_LOCK (g_utils_global);
1703   g_get_any_init ();
1704   G_UNLOCK (g_utils_global);
1705 }
1706
1707
1708 /**
1709  * g_get_user_name:
1710  *
1711  * Gets the user name of the current user. The encoding of the returned
1712  * string is system-defined. On UNIX, it might be the preferred file name
1713  * encoding, or something else, and there is no guarantee that it is even
1714  * consistent on a machine. On Windows, it is always UTF-8.
1715  *
1716  * Returns: the user name of the current user.
1717  */
1718 G_CONST_RETURN gchar*
1719 g_get_user_name (void)
1720 {
1721   g_get_any_init_locked ();
1722   return g_user_name;
1723 }
1724
1725 /**
1726  * g_get_real_name:
1727  *
1728  * Gets the real name of the user. This usually comes from the user's entry 
1729  * in the <filename>passwd</filename> file. The encoding of the returned 
1730  * string is system-defined. (On Windows, it is, however, always UTF-8.) 
1731  * If the real user name cannot be determined, the string "Unknown" is 
1732  * returned.
1733  *
1734  * Returns: the user's real name.
1735  */
1736 G_CONST_RETURN gchar*
1737 g_get_real_name (void)
1738 {
1739   g_get_any_init_locked ();
1740   return g_real_name;
1741 }
1742
1743 /**
1744  * g_get_home_dir:
1745  *
1746  * Gets the current user's home directory. 
1747  *
1748  * Note that in contrast to traditional UNIX tools, this function 
1749  * prefers <filename>passwd</filename> entries over the <envar>HOME</envar> 
1750  * environment variable.
1751  *
1752  * Returns: the current user's home directory.
1753  */
1754 G_CONST_RETURN gchar*
1755 g_get_home_dir (void)
1756 {
1757   g_get_any_init_locked ();
1758   return g_home_dir;
1759 }
1760
1761 /**
1762  * g_get_tmp_dir:
1763  *
1764  * Gets the directory to use for temporary files. This is found from 
1765  * inspecting the environment variables <envar>TMPDIR</envar>, 
1766  * <envar>TMP</envar>, and <envar>TEMP</envar> in that order. If none 
1767  * of those are defined "/tmp" is returned on UNIX and "C:\" on Windows. 
1768  * The encoding of the returned string is system-defined. On Windows, 
1769  * it is always UTF-8. The return value is never %NULL.
1770  *
1771  * Returns: the directory to use for temporary files.
1772  */
1773 G_CONST_RETURN gchar*
1774 g_get_tmp_dir (void)
1775 {
1776   g_get_any_init_locked ();
1777   return g_tmp_dir;
1778 }
1779
1780 /**
1781  * g_get_host_name:
1782  *
1783  * Return a name for the machine. 
1784  *
1785  * The returned name is not necessarily a fully-qualified domain name,
1786  * or even present in DNS or some other name service at all. It need
1787  * not even be unique on your local network or site, but usually it
1788  * is. Callers should not rely on the return value having any specific
1789  * properties like uniqueness for security purposes. Even if the name
1790  * of the machine is changed while an application is running, the
1791  * return value from this function does not change. The returned
1792  * string is owned by GLib and should not be modified or freed. If no
1793  * name can be determined, a default fixed string "localhost" is
1794  * returned.
1795  *
1796  * Returns: the host name of the machine.
1797  *
1798  * Since: 2.8
1799  */
1800 const gchar *
1801 g_get_host_name (void)
1802 {
1803   g_get_any_init_locked ();
1804   return g_host_name;
1805 }
1806
1807 G_LOCK_DEFINE_STATIC (g_prgname);
1808 static gchar *g_prgname = NULL;
1809
1810 /**
1811  * g_get_prgname:
1812  *
1813  * Gets the name of the program. This name should <emphasis>not</emphasis> 
1814  * be localized, contrast with g_get_application_name().
1815  * (If you are using GDK or GTK+ the program name is set in gdk_init(), 
1816  * which is called by gtk_init(). The program name is found by taking 
1817  * the last component of <literal>argv[0]</literal>.)
1818  *
1819  * Returns: the name of the program. The returned string belongs 
1820  * to GLib and must not be modified or freed.
1821  */
1822 gchar*
1823 g_get_prgname (void)
1824 {
1825   gchar* retval;
1826
1827   G_LOCK (g_prgname);
1828 #ifdef G_OS_WIN32
1829   if (g_prgname == NULL)
1830     {
1831       static gboolean beenhere = FALSE;
1832
1833       if (!beenhere)
1834         {
1835           gchar *utf8_buf = NULL;
1836
1837           beenhere = TRUE;
1838           if (G_WIN32_HAVE_WIDECHAR_API ())
1839             {
1840               wchar_t buf[MAX_PATH+1];
1841               if (GetModuleFileNameW (GetModuleHandle (NULL),
1842                                       buf, G_N_ELEMENTS (buf)) > 0)
1843                 utf8_buf = g_utf16_to_utf8 (buf, -1, NULL, NULL, NULL);
1844             }
1845           else
1846             {
1847               gchar buf[MAX_PATH+1];
1848               if (GetModuleFileNameA (GetModuleHandle (NULL),
1849                                       buf, G_N_ELEMENTS (buf)) > 0)
1850                 utf8_buf = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL);
1851             }
1852           if (utf8_buf)
1853             {
1854               g_prgname = g_path_get_basename (utf8_buf);
1855               g_free (utf8_buf);
1856             }
1857         }
1858     }
1859 #endif
1860   retval = g_prgname;
1861   G_UNLOCK (g_prgname);
1862
1863   return retval;
1864 }
1865
1866 /**
1867  * g_set_prgname:
1868  * @prgname: the name of the program.
1869  *
1870  * Sets the name of the program. This name should <emphasis>not</emphasis> 
1871  * be localized, contrast with g_set_application_name(). Note that for 
1872  * thread-safety reasons this function can only be called once.
1873  */
1874 void
1875 g_set_prgname (const gchar *prgname)
1876 {
1877   G_LOCK (g_prgname);
1878   g_free (g_prgname);
1879   g_prgname = g_strdup (prgname);
1880   G_UNLOCK (g_prgname);
1881 }
1882
1883 G_LOCK_DEFINE_STATIC (g_application_name);
1884 static gchar *g_application_name = NULL;
1885
1886 /**
1887  * g_get_application_name:
1888  * 
1889  * Gets a human-readable name for the application, as set by
1890  * g_set_application_name(). This name should be localized if
1891  * possible, and is intended for display to the user.  Contrast with
1892  * g_get_prgname(), which gets a non-localized name. If
1893  * g_set_application_name() has not been called, returns the result of
1894  * g_get_prgname() (which may be %NULL if g_set_prgname() has also not
1895  * been called).
1896  * 
1897  * Return value: human-readable application name. may return %NULL
1898  *
1899  * Since: 2.2
1900  **/
1901 G_CONST_RETURN gchar*
1902 g_get_application_name (void)
1903 {
1904   gchar* retval;
1905
1906   G_LOCK (g_application_name);
1907   retval = g_application_name;
1908   G_UNLOCK (g_application_name);
1909
1910   if (retval == NULL)
1911     return g_get_prgname ();
1912   
1913   return retval;
1914 }
1915
1916 /**
1917  * g_set_application_name:
1918  * @application_name: localized name of the application
1919  *
1920  * Sets a human-readable name for the application. This name should be
1921  * localized if possible, and is intended for display to the user.
1922  * Contrast with g_set_prgname(), which sets a non-localized name.
1923  * g_set_prgname() will be called automatically by gtk_init(),
1924  * but g_set_application_name() will not.
1925  *
1926  * Note that for thread safety reasons, this function can only
1927  * be called once.
1928  *
1929  * The application name will be used in contexts such as error messages,
1930  * or when displaying an application's name in the task list.
1931  * 
1932  **/
1933 void
1934 g_set_application_name (const gchar *application_name)
1935 {
1936   gboolean already_set = FALSE;
1937         
1938   G_LOCK (g_application_name);
1939   if (g_application_name)
1940     already_set = TRUE;
1941   else
1942     g_application_name = g_strdup (application_name);
1943   G_UNLOCK (g_application_name);
1944
1945   if (already_set)
1946     g_warning ("g_set_application() name called multiple times");
1947 }
1948
1949 /**
1950  * g_get_user_data_dir:
1951  * 
1952  * Returns a base directory in which to access application data such
1953  * as icons that is customized for a particular user.  
1954  *
1955  * On UNIX platforms this is determined using the mechanisms described in
1956  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
1957  * XDG Base Directory Specification</ulink>
1958  * 
1959  * Return value: a string owned by GLib that must not be modified 
1960  *               or freed.
1961  * Since: 2.6
1962  **/
1963 G_CONST_RETURN gchar*
1964 g_get_user_data_dir (void)
1965 {
1966   gchar *data_dir;  
1967
1968   G_LOCK (g_utils_global);
1969
1970   if (!g_user_data_dir)
1971     {
1972 #ifdef G_OS_WIN32
1973       data_dir = get_special_folder (CSIDL_PERSONAL);
1974 #else
1975       data_dir = (gchar *) g_getenv ("XDG_DATA_HOME");
1976
1977       if (data_dir && data_dir[0])
1978         data_dir = g_strdup (data_dir);
1979 #endif
1980       if (!data_dir || !data_dir[0])
1981         {
1982           g_get_any_init ();
1983
1984           if (g_home_dir)
1985             data_dir = g_build_filename (g_home_dir, ".local", 
1986                                          "share", NULL);
1987           else
1988             data_dir = g_build_filename (g_tmp_dir, g_user_name, ".local", 
1989                                          "share", NULL);
1990         }
1991
1992       g_user_data_dir = data_dir;
1993     }
1994   else
1995     data_dir = g_user_data_dir;
1996
1997   G_UNLOCK (g_utils_global);
1998
1999   return data_dir;
2000 }
2001
2002 /**
2003  * g_get_user_config_dir:
2004  * 
2005  * Returns a base directory in which to store user-specific application 
2006  * configuration information such as user preferences and settings. 
2007  *
2008  * On UNIX platforms this is determined using the mechanisms described in
2009  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
2010  * XDG Base Directory Specification</ulink>
2011  * 
2012  * Return value: a string owned by GLib that must not be modified 
2013  *               or freed.
2014  * Since: 2.6
2015  **/
2016 G_CONST_RETURN gchar*
2017 g_get_user_config_dir (void)
2018 {
2019   gchar *config_dir;  
2020
2021   G_LOCK (g_utils_global);
2022
2023   if (!g_user_config_dir)
2024     {
2025 #ifdef G_OS_WIN32
2026       config_dir = get_special_folder (CSIDL_APPDATA);
2027 #else
2028       config_dir = (gchar *) g_getenv ("XDG_CONFIG_HOME");
2029
2030       if (config_dir && config_dir[0])
2031         config_dir = g_strdup (config_dir);
2032 #endif
2033       if (!config_dir || !config_dir[0])
2034         {
2035           g_get_any_init ();
2036
2037           if (g_home_dir)
2038             config_dir = g_build_filename (g_home_dir, ".config", NULL);
2039           else
2040             config_dir = g_build_filename (g_tmp_dir, g_user_name, ".config", NULL);
2041         }
2042       g_user_config_dir = config_dir;
2043     }
2044   else
2045     config_dir = g_user_config_dir;
2046
2047   G_UNLOCK (g_utils_global);
2048
2049   return config_dir;
2050 }
2051
2052 /**
2053  * g_get_user_cache_dir:
2054  * 
2055  * Returns a base directory in which to store non-essential, cached
2056  * data specific to particular user.
2057  *
2058  * On UNIX platforms this is determined using the mechanisms described in
2059  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
2060  * XDG Base Directory Specification</ulink>
2061  * 
2062  * Return value: a string owned by GLib that must not be modified 
2063  *               or freed.
2064  * Since: 2.6
2065  **/
2066 G_CONST_RETURN gchar*
2067 g_get_user_cache_dir (void)
2068 {
2069   gchar *cache_dir;  
2070
2071   G_LOCK (g_utils_global);
2072
2073   if (!g_user_cache_dir)
2074     {
2075 #ifdef G_OS_WIN32
2076       cache_dir = get_special_folder (CSIDL_INTERNET_CACHE); /* XXX correct? */
2077 #else
2078       cache_dir = (gchar *) g_getenv ("XDG_CACHE_HOME");
2079
2080       if (cache_dir && cache_dir[0])
2081           cache_dir = g_strdup (cache_dir);
2082 #endif
2083       if (!cache_dir || !cache_dir[0])
2084         {
2085           g_get_any_init ();
2086         
2087           if (g_home_dir)
2088             cache_dir = g_build_filename (g_home_dir, ".cache", NULL);
2089           else
2090             cache_dir = g_build_filename (g_tmp_dir, g_user_name, ".cache", NULL);
2091         }
2092       g_user_cache_dir = cache_dir;
2093     }
2094   else
2095     cache_dir = g_user_cache_dir;
2096
2097   G_UNLOCK (g_utils_global);
2098
2099   return cache_dir;
2100 }
2101
2102 #ifdef G_OS_WIN32
2103
2104 #undef g_get_system_data_dirs
2105
2106 static HMODULE
2107 get_module_for_address (gconstpointer address)
2108 {
2109   /* Holds the g_utils_global lock */
2110
2111   static gboolean beenhere = FALSE;
2112   typedef BOOL (WINAPI *t_GetModuleHandleExA) (DWORD, LPCTSTR, HMODULE *);
2113   static t_GetModuleHandleExA p_GetModuleHandleExA = NULL;
2114   HMODULE hmodule;
2115
2116   if (!address)
2117     return NULL;
2118
2119   if (!beenhere)
2120     {
2121       p_GetModuleHandleExA =
2122         (t_GetModuleHandleExA) GetProcAddress (LoadLibrary ("kernel32.dll"),
2123                                                "GetModuleHandleExA");
2124       beenhere = TRUE;
2125     }
2126
2127   if (p_GetModuleHandleExA == NULL ||
2128       !(*p_GetModuleHandleExA) (GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
2129                                 GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
2130                                 address, &hmodule))
2131     {
2132       MEMORY_BASIC_INFORMATION mbi;
2133       VirtualQuery (address, &mbi, sizeof (mbi));
2134       hmodule = (HMODULE) mbi.AllocationBase;
2135     }
2136
2137   return hmodule;
2138 }
2139
2140 static gchar *
2141 get_module_share_dir (gconstpointer address)
2142 {
2143   HMODULE hmodule;
2144   gchar *filename = NULL;
2145   gchar *p, *retval;
2146
2147   hmodule = get_module_for_address (address);
2148   if (hmodule == NULL)
2149     return NULL;
2150
2151   if (G_WIN32_IS_NT_BASED ())
2152     {
2153       wchar_t wfilename[MAX_PATH];
2154       if (GetModuleFileNameW (hmodule, wfilename, G_N_ELEMENTS (wfilename)))
2155         filename = g_utf16_to_utf8 (wfilename, -1, NULL, NULL, NULL);
2156     }
2157   else
2158     {
2159       char cpfilename[MAX_PATH];
2160       if (GetModuleFileNameA (hmodule, cpfilename, G_N_ELEMENTS (cpfilename)))
2161         filename = g_locale_to_utf8 (cpfilename, -1, NULL, NULL, NULL);
2162     }
2163
2164   if (filename == NULL)
2165     return NULL;
2166
2167   if ((p = strrchr (filename, G_DIR_SEPARATOR)) != NULL)
2168     *p = '\0';
2169
2170   p = strrchr (filename, G_DIR_SEPARATOR);
2171   if (p && (g_ascii_strcasecmp (p + 1, "bin") == 0))
2172     *p = '\0';
2173
2174   retval = g_build_filename (filename, "share", NULL);
2175   g_free (filename);
2176
2177   return retval;
2178 }
2179
2180 G_CONST_RETURN gchar * G_CONST_RETURN *
2181 g_win32_get_system_data_dirs_for_module (gconstpointer address)
2182 {
2183   GArray *data_dirs;
2184   HMODULE hmodule;
2185   static GHashTable *per_module_data_dirs = NULL;
2186   gchar **retval;
2187   gchar *p;
2188       
2189   if (address)
2190     {
2191       G_LOCK (g_utils_global);
2192       hmodule = get_module_for_address (address);
2193       if (hmodule != NULL)
2194         {
2195           if (per_module_data_dirs == NULL)
2196             per_module_data_dirs = g_hash_table_new (NULL, NULL);
2197           else
2198             {
2199               retval = g_hash_table_lookup (per_module_data_dirs, hmodule);
2200               
2201               if (retval != NULL)
2202                 {
2203                   G_UNLOCK (g_utils_global);
2204                   return (G_CONST_RETURN gchar * G_CONST_RETURN *) retval;
2205                 }
2206             }
2207         }
2208     }
2209
2210   data_dirs = g_array_new (TRUE, TRUE, sizeof (char *));
2211
2212   /* Documents and Settings\All Users\Application Data */
2213   p = get_special_folder (CSIDL_COMMON_APPDATA);
2214   if (p)
2215     g_array_append_val (data_dirs, p);
2216   
2217   /* Documents and Settings\All Users\Documents */
2218   p = get_special_folder (CSIDL_COMMON_DOCUMENTS);
2219   if (p)
2220     g_array_append_val (data_dirs, p);
2221         
2222   /* Using the above subfolders of Documents and Settings perhaps
2223    * makes sense from a Windows perspective.
2224    *
2225    * But looking at the actual use cases of this function in GTK+
2226    * and GNOME software, what we really want is the "share"
2227    * subdirectory of the installation directory for the package
2228    * our caller is a part of.
2229    *
2230    * The address parameter, if non-NULL, points to a function in the
2231    * calling module. Use that to determine that module's installation
2232    * folder, and use its "share" subfolder.
2233    *
2234    * Additionally, also use the "share" subfolder of the installation
2235    * locations of GLib and the .exe file being run.
2236    *
2237    * To guard against none of the above being what is really wanted,
2238    * callers of this function should have Win32-specific code to look
2239    * up their installation folder themselves, and handle a subfolder
2240    * "share" of it in the same way as the folders returned from this
2241    * function.
2242    */
2243
2244   p = get_module_share_dir (address);
2245   if (p)
2246     g_array_append_val (data_dirs, p);
2247     
2248   p = g_win32_get_package_installation_subdirectory (NULL, dll_name, "share");
2249   if (p)
2250     g_array_append_val (data_dirs, p);
2251   
2252   p = g_win32_get_package_installation_subdirectory (NULL, NULL, "share");
2253   if (p)
2254     g_array_append_val (data_dirs, p);
2255
2256   retval = (gchar **) g_array_free (data_dirs, FALSE);
2257
2258   if (address)
2259     {
2260       if (hmodule != NULL)
2261         g_hash_table_insert (per_module_data_dirs, hmodule, retval);
2262       G_UNLOCK (g_utils_global);
2263     }
2264
2265   return (G_CONST_RETURN gchar * G_CONST_RETURN *) retval;
2266 }
2267
2268 #endif
2269
2270 /**
2271  * g_get_system_data_dirs:
2272  * 
2273  * Returns an ordered list of base directories in which to access 
2274  * system-wide application data.
2275  *
2276  * On UNIX platforms this is determined using the mechanisms described in
2277  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
2278  * XDG Base Directory Specification</ulink>
2279  * 
2280  * On Windows the first elements in the list are the Application Data
2281  * and Documents folders for All Users. (These can be determined only
2282  * on Windows 2000 or later and are not present in the list on other
2283  * Windows versions.) See documentation for CSIDL_COMMON_APPDATA and
2284  * CSIDL_COMMON_DOCUMENTS.
2285  *
2286  * Then follows the "share" subfolder in the installation folder for
2287  * the package containing the DLL that calls this function, if it can
2288  * be determined.
2289  * 
2290  * Finally the list contains the "share" subfolder in the installation
2291  * folder for GLib, and in the installation folder for the package the
2292  * application's .exe file belongs to.
2293  *
2294  * The installation folders above are determined by looking up the
2295  * folder where the module (DLL or EXE) in question is located. If the
2296  * folder's name is "bin", its parent is used, otherwise the folder
2297  * itself.
2298  *
2299  * Note that on Windows the returned list can vary depending on where
2300  * this function is called.
2301  *
2302  * Return value: a %NULL-terminated array of strings owned by GLib that must 
2303  *               not be modified or freed.
2304  * Since: 2.6
2305  **/
2306 G_CONST_RETURN gchar * G_CONST_RETURN * 
2307 g_get_system_data_dirs (void)
2308 {
2309   gchar **data_dir_vector;
2310
2311   G_LOCK (g_utils_global);
2312
2313   if (!g_system_data_dirs)
2314     {
2315 #ifdef G_OS_WIN32
2316       data_dir_vector = (gchar **) g_win32_get_system_data_dirs_for_module (NULL);
2317 #else
2318       gchar *data_dirs = (gchar *) g_getenv ("XDG_DATA_DIRS");
2319
2320       if (!data_dirs || !data_dirs[0])
2321           data_dirs = "/usr/local/share/:/usr/share/";
2322
2323       data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2324 #endif
2325
2326       g_system_data_dirs = data_dir_vector;
2327     }
2328   else
2329     data_dir_vector = g_system_data_dirs;
2330
2331   G_UNLOCK (g_utils_global);
2332
2333   return (G_CONST_RETURN gchar * G_CONST_RETURN *) data_dir_vector;
2334 }
2335
2336 /**
2337  * g_get_system_config_dirs:
2338  * 
2339  * Returns an ordered list of base directories in which to access 
2340  * system-wide configuration information.
2341  *
2342  * On UNIX platforms this is determined using the mechanisms described in
2343  * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
2344  * XDG Base Directory Specification</ulink>
2345  * 
2346  * Return value: a %NULL-terminated array of strings owned by GLib that must 
2347  *               not be modified or freed.
2348  * Since: 2.6
2349  **/
2350 G_CONST_RETURN gchar * G_CONST_RETURN *
2351 g_get_system_config_dirs (void)
2352 {
2353   gchar *conf_dirs, **conf_dir_vector;
2354
2355   G_LOCK (g_utils_global);
2356
2357   if (!g_system_config_dirs)
2358     {
2359 #ifdef G_OS_WIN32
2360       conf_dirs = get_special_folder (CSIDL_COMMON_APPDATA);
2361       if (conf_dirs)
2362         {
2363           conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2364           g_free (conf_dirs);
2365         }
2366       else
2367         {
2368           /* Return empty list */
2369           conf_dir_vector = g_strsplit ("", G_SEARCHPATH_SEPARATOR_S, 0);
2370         }
2371 #else
2372       conf_dirs = (gchar *) g_getenv ("XDG_CONFIG_DIRS");
2373
2374       if (!conf_dirs || !conf_dirs[0])
2375           conf_dirs = "/etc/xdg";
2376
2377       conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
2378 #endif
2379
2380       g_system_config_dirs = conf_dir_vector;
2381     }
2382   else
2383     conf_dir_vector = g_system_config_dirs;
2384   G_UNLOCK (g_utils_global);
2385
2386   return (G_CONST_RETURN gchar * G_CONST_RETURN *) conf_dir_vector;
2387 }
2388
2389 #ifndef G_OS_WIN32
2390
2391 static GHashTable *alias_table = NULL;
2392
2393 /* read an alias file for the locales */
2394 static void
2395 read_aliases (gchar *file)
2396 {
2397   FILE *fp;
2398   char buf[256];
2399   
2400   if (!alias_table)
2401     alias_table = g_hash_table_new (g_str_hash, g_str_equal);
2402   fp = fopen (file,"r");
2403   if (!fp)
2404     return;
2405   while (fgets (buf, 256, fp))
2406     {
2407       char *p, *q;
2408
2409       g_strstrip (buf);
2410
2411       /* Line is a comment */
2412       if ((buf[0] == '#') || (buf[0] == '\0'))
2413         continue;
2414
2415       /* Reads first column */
2416       for (p = buf, q = NULL; *p; p++) {
2417         if ((*p == '\t') || (*p == ' ') || (*p == ':')) {
2418           *p = '\0';
2419           q = p+1;
2420           while ((*q == '\t') || (*q == ' ')) {
2421             q++;
2422           }
2423           break;
2424         }
2425       }
2426       /* The line only had one column */
2427       if (!q || *q == '\0')
2428         continue;
2429       
2430       /* Read second column */
2431       for (p = q; *p; p++) {
2432         if ((*p == '\t') || (*p == ' ')) {
2433           *p = '\0';
2434           break;
2435         }
2436       }
2437
2438       /* Add to alias table if necessary */
2439       if (!g_hash_table_lookup (alias_table, buf)) {
2440         g_hash_table_insert (alias_table, g_strdup (buf), g_strdup (q));
2441       }
2442     }
2443   fclose (fp);
2444 }
2445
2446 #endif
2447
2448 static char *
2449 unalias_lang (char *lang)
2450 {
2451 #ifndef G_OS_WIN32
2452   char *p;
2453   int i;
2454
2455   if (!alias_table)
2456     read_aliases ("/usr/share/locale/locale.alias");
2457
2458   i = 0;
2459   while ((p = g_hash_table_lookup (alias_table, lang)) && (strcmp (p, lang) != 0))
2460     {
2461       lang = p;
2462       if (i++ == 30)
2463         {
2464           static gboolean said_before = FALSE;
2465           if (!said_before)
2466             g_warning ("Too many alias levels for a locale, "
2467                        "may indicate a loop");
2468           said_before = TRUE;
2469           return lang;
2470         }
2471     }
2472 #endif
2473   return lang;
2474 }
2475
2476 /* Mask for components of locale spec. The ordering here is from
2477  * least significant to most significant
2478  */
2479 enum
2480 {
2481   COMPONENT_CODESET =   1 << 0,
2482   COMPONENT_TERRITORY = 1 << 1,
2483   COMPONENT_MODIFIER =  1 << 2
2484 };
2485
2486 /* Break an X/Open style locale specification into components
2487  */
2488 static guint
2489 explode_locale (const gchar *locale,
2490                 gchar      **language, 
2491                 gchar      **territory, 
2492                 gchar      **codeset, 
2493                 gchar      **modifier)
2494 {
2495   const gchar *uscore_pos;
2496   const gchar *at_pos;
2497   const gchar *dot_pos;
2498
2499   guint mask = 0;
2500
2501   uscore_pos = strchr (locale, '_');
2502   dot_pos = strchr (uscore_pos ? uscore_pos : locale, '.');
2503   at_pos = strchr (dot_pos ? dot_pos : (uscore_pos ? uscore_pos : locale), '@');
2504
2505   if (at_pos)
2506     {
2507       mask |= COMPONENT_MODIFIER;
2508       *modifier = g_strdup (at_pos);
2509     }
2510   else
2511     at_pos = locale + strlen (locale);
2512
2513   if (dot_pos)
2514     {
2515       mask |= COMPONENT_CODESET;
2516       *codeset = g_strndup (dot_pos, at_pos - dot_pos);
2517     }
2518   else
2519     dot_pos = at_pos;
2520
2521   if (uscore_pos)
2522     {
2523       mask |= COMPONENT_TERRITORY;
2524       *territory = g_strndup (uscore_pos, dot_pos - uscore_pos);
2525     }
2526   else
2527     uscore_pos = dot_pos;
2528
2529   *language = g_strndup (locale, uscore_pos - locale);
2530
2531   return mask;
2532 }
2533
2534 /*
2535  * Compute all interesting variants for a given locale name -
2536  * by stripping off different components of the value.
2537  *
2538  * For simplicity, we assume that the locale is in
2539  * X/Open format: language[_territory][.codeset][@modifier]
2540  *
2541  * TODO: Extend this to handle the CEN format (see the GNUlibc docs)
2542  *       as well. We could just copy the code from glibc wholesale
2543  *       but it is big, ugly, and complicated, so I'm reluctant
2544  *       to do so when this should handle 99% of the time...
2545  */
2546 GSList *
2547 _g_compute_locale_variants (const gchar *locale)
2548 {
2549   GSList *retval = NULL;
2550
2551   gchar *language = NULL;
2552   gchar *territory = NULL;
2553   gchar *codeset = NULL;
2554   gchar *modifier = NULL;
2555
2556   guint mask;
2557   guint i;
2558
2559   g_return_val_if_fail (locale != NULL, NULL);
2560
2561   mask = explode_locale (locale, &language, &territory, &codeset, &modifier);
2562
2563   /* Iterate through all possible combinations, from least attractive
2564    * to most attractive.
2565    */
2566   for (i = 0; i <= mask; i++)
2567     if ((i & ~mask) == 0)
2568       {
2569         gchar *val = g_strconcat (language,
2570                                   (i & COMPONENT_TERRITORY) ? territory : "",
2571                                   (i & COMPONENT_CODESET) ? codeset : "",
2572                                   (i & COMPONENT_MODIFIER) ? modifier : "",
2573                                   NULL);
2574         retval = g_slist_prepend (retval, val);
2575       }
2576
2577   g_free (language);
2578   if (mask & COMPONENT_CODESET)
2579     g_free (codeset);
2580   if (mask & COMPONENT_TERRITORY)
2581     g_free (territory);
2582   if (mask & COMPONENT_MODIFIER)
2583     g_free (modifier);
2584
2585   return retval;
2586 }
2587
2588 /* The following is (partly) taken from the gettext package.
2589    Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.  */
2590
2591 static const gchar *
2592 guess_category_value (const gchar *category_name)
2593 {
2594   const gchar *retval;
2595
2596   /* The highest priority value is the `LANGUAGE' environment
2597      variable.  This is a GNU extension.  */
2598   retval = g_getenv ("LANGUAGE");
2599   if ((retval != NULL) && (retval[0] != '\0'))
2600     return retval;
2601
2602   /* `LANGUAGE' is not set.  So we have to proceed with the POSIX
2603      methods of looking to `LC_ALL', `LC_xxx', and `LANG'.  On some
2604      systems this can be done by the `setlocale' function itself.  */
2605
2606   /* Setting of LC_ALL overwrites all other.  */
2607   retval = g_getenv ("LC_ALL");  
2608   if ((retval != NULL) && (retval[0] != '\0'))
2609     return retval;
2610
2611   /* Next comes the name of the desired category.  */
2612   retval = g_getenv (category_name);
2613   if ((retval != NULL) && (retval[0] != '\0'))
2614     return retval;
2615
2616   /* Last possibility is the LANG environment variable.  */
2617   retval = g_getenv ("LANG");
2618   if ((retval != NULL) && (retval[0] != '\0'))
2619     return retval;
2620
2621 #ifdef G_PLATFORM_WIN32
2622   /* g_win32_getlocale() first checks for LC_ALL, LC_MESSAGES and
2623    * LANG, which we already did above. Oh well. The main point of
2624    * calling g_win32_getlocale() is to get the thread's locale as used
2625    * by Windows and the Microsoft C runtime (in the "English_United
2626    * States" format) translated into the Unixish format.
2627    */
2628   retval = g_win32_getlocale ();
2629   if ((retval != NULL) && (retval[0] != '\0'))
2630     return retval;
2631 #endif  
2632
2633   return NULL;
2634 }
2635
2636 typedef struct _GLanguageNamesCache GLanguageNamesCache;
2637
2638 struct _GLanguageNamesCache {
2639   gchar *languages;
2640   gchar **language_names;
2641 };
2642
2643 static void
2644 language_names_cache_free (gpointer data)
2645 {
2646   GLanguageNamesCache *cache = data;
2647   g_free (cache->languages);
2648   g_strfreev (cache->language_names);
2649   g_free (cache);
2650 }
2651
2652 /**
2653  * g_get_language_names:
2654  * 
2655  * Computes a list of applicable locale names, which can be used to 
2656  * e.g. construct locale-dependent filenames or search paths. The returned 
2657  * list is sorted from most desirable to least desirable and always contains 
2658  * the default locale "C".
2659  *
2660  * For example, if LANGUAGE=de:en_US, then the returned list is
2661  * "de", "en_US", "en", "C".
2662  *
2663  * This function consults the environment variables <envar>LANGUAGE</envar>, 
2664  * <envar>LC_ALL</envar>, <envar>LC_MESSAGES</envar> and <envar>LANG</envar> 
2665  * to find the list of locales specified by the user.
2666  * 
2667  * Return value: a %NULL-terminated array of strings owned by GLib 
2668  *    that must not be modified or freed.
2669  *
2670  * Since: 2.6
2671  **/
2672 G_CONST_RETURN gchar * G_CONST_RETURN * 
2673 g_get_language_names (void)
2674 {
2675   static GStaticPrivate cache_private = G_STATIC_PRIVATE_INIT;
2676   GLanguageNamesCache *cache = g_static_private_get (&cache_private);
2677   const gchar *value;
2678
2679   if (!cache)
2680     {
2681       cache = g_new0 (GLanguageNamesCache, 1);
2682       g_static_private_set (&cache_private, cache, language_names_cache_free);
2683     }
2684
2685   value = guess_category_value ("LC_MESSAGES");
2686   if (!value)
2687     value = "C";
2688
2689   if (!(cache->languages && strcmp (cache->languages, value) == 0))
2690     {
2691       gchar **languages;
2692       gchar **alist, **a;
2693       GSList *list, *l;
2694       gint i;
2695
2696       g_free (cache->languages);
2697       g_strfreev (cache->language_names);
2698       cache->languages = g_strdup (value);
2699
2700       alist = g_strsplit (value, ":", 0);
2701       list = NULL;
2702       for (a = alist; *a; a++)
2703         {
2704           gchar *b = unalias_lang (*a);
2705           list = g_slist_concat (list, _g_compute_locale_variants (b));
2706         }
2707       g_strfreev (alist);
2708       list = g_slist_append (list, g_strdup ("C"));
2709
2710       cache->language_names = languages = g_new (gchar *, g_slist_length (list) + 1);
2711       for (l = list, i = 0; l; l = l->next, i++)
2712         languages[i] = l->data;
2713       languages[i] = NULL;
2714
2715       g_slist_free (list);
2716     }
2717
2718   return (G_CONST_RETURN gchar * G_CONST_RETURN *) cache->language_names;
2719 }
2720
2721 /**
2722  * g_direct_hash:
2723  * @v: a #gpointer key
2724  *
2725  * Converts a gpointer to a hash value.
2726  * It can be passed to g_hash_table_new() as the @hash_func parameter, 
2727  * when using pointers as keys in a #GHashTable.
2728  *
2729  * Returns: a hash value corresponding to the key.
2730  */
2731 guint
2732 g_direct_hash (gconstpointer v)
2733 {
2734   return GPOINTER_TO_UINT (v);
2735 }
2736
2737 /**
2738  * g_direct_equal:
2739  * @v1: a key.
2740  * @v2: a key to compare with @v1.
2741  *
2742  * Compares two #gpointer arguments and returns %TRUE if they are equal.
2743  * It can be passed to g_hash_table_new() as the @key_equal_func
2744  * parameter, when using pointers as keys in a #GHashTable.
2745  * 
2746  * Returns: %TRUE if the two keys match.
2747  */
2748 gboolean
2749 g_direct_equal (gconstpointer v1,
2750                 gconstpointer v2)
2751 {
2752   return v1 == v2;
2753 }
2754
2755 /**
2756  * g_int_equal:
2757  * @v1: a pointer to a #gint key.
2758  * @v2: a pointer to a #gint key to compare with @v1.
2759  *
2760  * Compares the two #gint values being pointed to and returns 
2761  * %TRUE if they are equal.
2762  * It can be passed to g_hash_table_new() as the @key_equal_func
2763  * parameter, when using pointers to integers as keys in a #GHashTable.
2764  * 
2765  * Returns: %TRUE if the two keys match.
2766  */
2767 gboolean
2768 g_int_equal (gconstpointer v1,
2769              gconstpointer v2)
2770 {
2771   return *((const gint*) v1) == *((const gint*) v2);
2772 }
2773
2774 /**
2775  * g_int_hash:
2776  * @v: a pointer to a #gint key
2777  *
2778  * Converts a pointer to a #gint to a hash value.
2779  * It can be passed to g_hash_table_new() as the @hash_func parameter, 
2780  * when using pointers to integers values as keys in a #GHashTable.
2781  *
2782  * Returns: a hash value corresponding to the key.
2783  */
2784 guint
2785 g_int_hash (gconstpointer v)
2786 {
2787   return *(const gint*) v;
2788 }
2789
2790 /**
2791  * g_nullify_pointer:
2792  * @nullify_location: the memory address of the pointer.
2793  * 
2794  * Set the pointer at the specified location to %NULL.
2795  **/
2796 void
2797 g_nullify_pointer (gpointer *nullify_location)
2798 {
2799   g_return_if_fail (nullify_location != NULL);
2800
2801   *nullify_location = NULL;
2802 }
2803
2804 /**
2805  * g_get_codeset:
2806  * 
2807  * Get the codeset for the current locale.
2808  * 
2809  * Return value: a newly allocated string containing the name
2810  * of the codeset. This string must be freed with g_free().
2811  **/
2812 gchar *
2813 g_get_codeset (void)
2814 {
2815   const gchar *charset;
2816
2817   g_get_charset (&charset);
2818
2819   return g_strdup (charset);
2820 }
2821
2822 /* This is called from g_thread_init(). It's used to
2823  * initialize some static data in a threadsafe way.
2824  */
2825 void
2826 _g_utils_thread_init (void)
2827 {
2828   g_get_language_names ();
2829 }
2830
2831 #ifdef ENABLE_NLS
2832
2833 #include <libintl.h>
2834
2835 #ifdef G_OS_WIN32
2836
2837 /**
2838  * _glib_get_locale_dir:
2839  *
2840  * Return the path to the lib\locale subfolder of the GLib
2841  * installation folder. The path is in the system codepage. We have to
2842  * use system codepage as bindtextdomain() doesn't have a UTF-8
2843  * interface.
2844  */
2845 static const gchar *
2846 _glib_get_locale_dir (void)
2847 {
2848   gchar *dir, *cp_dir;
2849   gchar *retval = NULL;
2850
2851   dir = g_win32_get_package_installation_directory (GETTEXT_PACKAGE, dll_name);
2852   cp_dir = g_win32_locale_filename_from_utf8 (dir);
2853   g_free (dir);
2854
2855   if (cp_dir)
2856     {
2857       /* Don't use g_build_filename() on pathnames in the system
2858        * codepage. In CJK locales cp_dir might end with a double-byte
2859        * character whose trailing byte is a backslash.
2860        */
2861       retval = g_strconcat (cp_dir, "\\lib\\locale", NULL);
2862       g_free (cp_dir);
2863     }
2864
2865   if (retval)
2866     return retval;
2867   else
2868     return g_strdup ("");
2869 }
2870
2871 #undef GLIB_LOCALE_DIR
2872 #define GLIB_LOCALE_DIR _glib_get_locale_dir ()
2873
2874 #endif /* G_OS_WIN32 */
2875
2876 G_CONST_RETURN gchar *
2877 _glib_gettext (const gchar *str)
2878 {
2879   static gboolean _glib_gettext_initialized = FALSE;
2880
2881   if (!_glib_gettext_initialized)
2882     {
2883       bindtextdomain(GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
2884 #    ifdef HAVE_BIND_TEXTDOMAIN_CODESET
2885       bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
2886 #    endif
2887       _glib_gettext_initialized = TRUE;
2888     }
2889   
2890   return dgettext (GETTEXT_PACKAGE, str);
2891 }
2892
2893 #endif /* ENABLE_NLS */
2894
2895 #ifdef G_OS_WIN32
2896
2897 /* Binary compatibility versions. Not for newly compiled code. */
2898
2899 #undef g_find_program_in_path
2900
2901 gchar*
2902 g_find_program_in_path (const gchar *program)
2903 {
2904   gchar *utf8_program = g_locale_to_utf8 (program, -1, NULL, NULL, NULL);
2905   gchar *utf8_retval = g_find_program_in_path_utf8 (utf8_program);
2906   gchar *retval;
2907
2908   g_free (utf8_program);
2909   if (utf8_retval == NULL)
2910     return NULL;
2911   retval = g_locale_from_utf8 (utf8_retval, -1, NULL, NULL, NULL);
2912   g_free (utf8_retval);
2913
2914   return retval;
2915 }
2916
2917 #undef g_get_current_dir
2918
2919 gchar*
2920 g_get_current_dir (void)
2921 {
2922   gchar *utf8_dir = g_get_current_dir_utf8 ();
2923   gchar *dir = g_locale_from_utf8 (utf8_dir, -1, NULL, NULL, NULL);
2924   g_free (utf8_dir);
2925   return dir;
2926 }
2927
2928 #undef g_getenv
2929
2930 G_CONST_RETURN gchar*
2931 g_getenv (const gchar *variable)
2932 {
2933   gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL);
2934   const gchar *utf8_value = g_getenv_utf8 (utf8_variable);
2935   gchar *value;
2936   GQuark quark;
2937
2938   g_free (utf8_variable);
2939   if (!utf8_value)
2940     return NULL;
2941   value = g_locale_from_utf8 (utf8_value, -1, NULL, NULL, NULL);
2942   quark = g_quark_from_string (value);
2943   g_free (value);
2944
2945   return g_quark_to_string (quark);
2946 }
2947
2948 #undef g_setenv
2949
2950 gboolean
2951 g_setenv (const gchar *variable, 
2952           const gchar *value, 
2953           gboolean     overwrite)
2954 {
2955   gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL);
2956   gchar *utf8_value = g_locale_to_utf8 (value, -1, NULL, NULL, NULL);
2957   gboolean retval = g_setenv_utf8 (utf8_variable, utf8_value, overwrite);
2958
2959   g_free (utf8_variable);
2960   g_free (utf8_value);
2961
2962   return retval;
2963 }
2964
2965 #undef g_unsetenv
2966
2967 void
2968 g_unsetenv (const gchar *variable)
2969 {
2970   gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL);
2971
2972   g_unsetenv_utf8 (utf8_variable);
2973
2974   g_free (utf8_variable);
2975 }
2976
2977 #undef g_get_user_name
2978
2979 G_CONST_RETURN gchar*
2980 g_get_user_name (void)
2981 {
2982   g_get_any_init_locked ();
2983   return g_user_name_cp;
2984 }
2985
2986 #undef g_get_real_name
2987
2988 G_CONST_RETURN gchar*
2989 g_get_real_name (void)
2990 {
2991   g_get_any_init_locked ();
2992   return g_real_name_cp;
2993 }
2994
2995 #undef g_get_home_dir
2996
2997 G_CONST_RETURN gchar*
2998 g_get_home_dir (void)
2999 {
3000   g_get_any_init_locked ();
3001   return g_home_dir_cp;
3002 }
3003
3004 #undef g_get_tmp_dir
3005
3006 G_CONST_RETURN gchar*
3007 g_get_tmp_dir (void)
3008 {
3009   g_get_any_init_locked ();
3010   return g_tmp_dir_cp;
3011 }
3012
3013 #endif
3014
3015 #define __G_UTILS_C__
3016 #include "galiasdef.c"