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